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 { |