| 3319 |
} |
} |
| 3320 |
} |
} |
| 3321 |
|
|
| 3322 |
|
#ifdef CONFIG_SOFTMMU |
| 3323 |
|
void *get_mmap_addr(unsigned long size) |
| 3324 |
|
{ |
| 3325 |
|
return NULL; |
| 3326 |
|
} |
| 3327 |
|
#else |
| 3328 |
unsigned long mmap_addr = PHYS_RAM_BASE; |
unsigned long mmap_addr = PHYS_RAM_BASE; |
| 3329 |
|
|
| 3330 |
void *get_mmap_addr(unsigned long size) |
void *get_mmap_addr(unsigned long size) |
| 3334 |
mmap_addr += ((size + 4095) & ~4095) + 4096; |
mmap_addr += ((size + 4095) & ~4095) + 4096; |
| 3335 |
return (void *)addr; |
return (void *)addr; |
| 3336 |
} |
} |
| 3337 |
|
#endif |
| 3338 |
|
|
| 3339 |
/* main execution loop */ |
/* main execution loop */ |
| 3340 |
|
|
| 3529 |
struct sigaction act; |
struct sigaction act; |
| 3530 |
struct itimerval itv; |
struct itimerval itv; |
| 3531 |
CPUX86State *env; |
CPUX86State *env; |
| 3532 |
const char *tmpdir, *initrd_filename; |
const char *initrd_filename; |
| 3533 |
const char *hd_filename[MAX_DISKS]; |
const char *hd_filename[MAX_DISKS]; |
| 3534 |
const char *kernel_filename, *kernel_cmdline; |
const char *kernel_filename, *kernel_cmdline; |
| 3535 |
DisplayState *ds = &display_state; |
DisplayState *ds = &display_state; |
| 3651 |
net_init(); |
net_init(); |
| 3652 |
|
|
| 3653 |
/* init the memory */ |
/* init the memory */ |
|
tmpdir = getenv("QEMU_TMPDIR"); |
|
|
if (!tmpdir) |
|
|
tmpdir = "/tmp"; |
|
|
snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir); |
|
|
if (mkstemp(phys_ram_file) < 0) { |
|
|
fprintf(stderr, "Could not create temporary memory file '%s'\n", |
|
|
phys_ram_file); |
|
|
exit(1); |
|
|
} |
|
|
phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600); |
|
|
if (phys_ram_fd < 0) { |
|
|
fprintf(stderr, "Could not open temporary memory file '%s'\n", |
|
|
phys_ram_file); |
|
|
exit(1); |
|
|
} |
|
| 3654 |
total_ram_size = phys_ram_size + vga_ram_size; |
total_ram_size = phys_ram_size + vga_ram_size; |
| 3655 |
ftruncate(phys_ram_fd, total_ram_size); |
|
| 3656 |
unlink(phys_ram_file); |
#ifdef CONFIG_SOFTMMU |
| 3657 |
phys_ram_base = mmap(get_mmap_addr(total_ram_size), |
phys_ram_base = malloc(total_ram_size); |
| 3658 |
total_ram_size, |
if (!phys_ram_base) { |
| 3659 |
PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, |
fprintf(stderr, "Could not allocate physical memory\n"); |
|
phys_ram_fd, 0); |
|
|
if (phys_ram_base == MAP_FAILED) { |
|
|
fprintf(stderr, "Could not map physical memory\n"); |
|
| 3660 |
exit(1); |
exit(1); |
| 3661 |
} |
} |
| 3662 |
|
#else |
| 3663 |
|
/* as we must map the same page at several addresses, we must use |
| 3664 |
|
a fd */ |
| 3665 |
|
{ |
| 3666 |
|
const char *tmpdir; |
| 3667 |
|
|
| 3668 |
|
tmpdir = getenv("QEMU_TMPDIR"); |
| 3669 |
|
if (!tmpdir) |
| 3670 |
|
tmpdir = "/tmp"; |
| 3671 |
|
snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir); |
| 3672 |
|
if (mkstemp(phys_ram_file) < 0) { |
| 3673 |
|
fprintf(stderr, "Could not create temporary memory file '%s'\n", |
| 3674 |
|
phys_ram_file); |
| 3675 |
|
exit(1); |
| 3676 |
|
} |
| 3677 |
|
phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600); |
| 3678 |
|
if (phys_ram_fd < 0) { |
| 3679 |
|
fprintf(stderr, "Could not open temporary memory file '%s'\n", |
| 3680 |
|
phys_ram_file); |
| 3681 |
|
exit(1); |
| 3682 |
|
} |
| 3683 |
|
ftruncate(phys_ram_fd, total_ram_size); |
| 3684 |
|
unlink(phys_ram_file); |
| 3685 |
|
phys_ram_base = mmap(get_mmap_addr(total_ram_size), |
| 3686 |
|
total_ram_size, |
| 3687 |
|
PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, |
| 3688 |
|
phys_ram_fd, 0); |
| 3689 |
|
if (phys_ram_base == MAP_FAILED) { |
| 3690 |
|
fprintf(stderr, "Could not map physical memory\n"); |
| 3691 |
|
exit(1); |
| 3692 |
|
} |
| 3693 |
|
} |
| 3694 |
|
#endif |
| 3695 |
|
|
| 3696 |
/* open the virtual block devices */ |
/* open the virtual block devices */ |
| 3697 |
for(i = 0; i < MAX_DISKS; i++) { |
for(i = 0; i < MAX_DISKS; i++) { |
| 3739 |
params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR); |
params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR); |
| 3740 |
memset(params, 0, sizeof(struct linux_params)); |
memset(params, 0, sizeof(struct linux_params)); |
| 3741 |
params->mount_root_rdonly = 0; |
params->mount_root_rdonly = 0; |
| 3742 |
params->cl_magic = 0xA33F; |
stw_raw(¶ms->cl_magic, 0xA33F); |
| 3743 |
params->cl_offset = params->commandline - (uint8_t *)params; |
stw_raw(¶ms->cl_offset, params->commandline - (uint8_t *)params); |
| 3744 |
params->alt_mem_k = (phys_ram_size / 1024) - 1024; |
stl_raw(¶ms->alt_mem_k, (phys_ram_size / 1024) - 1024); |
| 3745 |
pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline); |
pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline); |
| 3746 |
params->loader_type = 0x01; |
params->loader_type = 0x01; |
| 3747 |
if (initrd_size > 0) { |
if (initrd_size > 0) { |
| 3748 |
params->initrd_start = INITRD_LOAD_ADDR; |
stl_raw(¶ms->initrd_start, INITRD_LOAD_ADDR); |
| 3749 |
params->initrd_size = initrd_size; |
stl_raw(¶ms->initrd_size, initrd_size); |
| 3750 |
} |
} |
| 3751 |
params->orig_video_lines = 25; |
params->orig_video_lines = 25; |
| 3752 |
params->orig_video_cols = 80; |
params->orig_video_cols = 80; |
| 3757 |
|
|
| 3758 |
memset(params->idt_table, 0, sizeof(params->idt_table)); |
memset(params->idt_table, 0, sizeof(params->idt_table)); |
| 3759 |
|
|
| 3760 |
params->gdt_table[2] = 0x00cf9a000000ffffLL; /* KERNEL_CS */ |
stq_raw(¶ms->gdt_table[2], 0x00cf9a000000ffffLL); /* KERNEL_CS */ |
| 3761 |
params->gdt_table[3] = 0x00cf92000000ffffLL; /* KERNEL_DS */ |
stq_raw(¶ms->gdt_table[3], 0x00cf92000000ffffLL); /* KERNEL_DS */ |
| 3762 |
/* for newer kernels (2.6.0) CS/DS are at different addresses */ |
/* for newer kernels (2.6.0) CS/DS are at different addresses */ |
| 3763 |
params->gdt_table[12] = 0x00cf9a000000ffffLL; /* KERNEL_CS */ |
stq_raw(¶ms->gdt_table[12], 0x00cf9a000000ffffLL); /* KERNEL_CS */ |
| 3764 |
params->gdt_table[13] = 0x00cf92000000ffffLL; /* KERNEL_DS */ |
stq_raw(¶ms->gdt_table[13], 0x00cf92000000ffffLL); /* KERNEL_DS */ |
| 3765 |
|
|
| 3766 |
env->idt.base = (void *)((uint8_t *)params->idt_table - phys_ram_base); |
env->idt.base = (void *)((uint8_t *)params->idt_table - phys_ram_base); |
| 3767 |
env->idt.limit = sizeof(params->idt_table) - 1; |
env->idt.limit = sizeof(params->idt_table) - 1; |
| 3866 |
timer_ms = itv.it_interval.tv_usec / 1000; |
timer_ms = itv.it_interval.tv_usec / 1000; |
| 3867 |
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) / |
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) / |
| 3868 |
1000000; |
1000000; |
| 3869 |
|
|
| 3870 |
if (use_gdbstub) { |
if (use_gdbstub) { |
| 3871 |
cpu_gdbstub(NULL, main_loop, gdbstub_port); |
cpu_gdbstub(NULL, main_loop, gdbstub_port); |
| 3872 |
} else { |
} else { |