Revision a20dd508
b/vl.c | ||
---|---|---|
44 | 44 |
#include <linux/if.h> |
45 | 45 |
#include <linux/if_tun.h> |
46 | 46 |
|
47 |
#include "cpu-i386.h"
|
|
47 |
#include "cpu.h" |
|
48 | 48 |
#include "disas.h" |
49 | 49 |
#include "thunk.h" |
50 | 50 |
|
... | ... | |
216 | 216 |
BlockDriverState *bs_table[MAX_DISKS]; |
217 | 217 |
int vga_ram_size; |
218 | 218 |
static DisplayState display_state; |
219 |
int nodisp;
|
|
219 |
int nographic;
|
|
220 | 220 |
int term_inited; |
221 | 221 |
int64_t ticks_per_sec; |
222 | 222 |
|
... | ... | |
2434 | 2434 |
s->select = 0xa0; |
2435 | 2435 |
} |
2436 | 2436 |
|
2437 |
struct partition { |
|
2438 |
uint8_t boot_ind; /* 0x80 - active */ |
|
2439 |
uint8_t head; /* starting head */ |
|
2440 |
uint8_t sector; /* starting sector */ |
|
2441 |
uint8_t cyl; /* starting cylinder */ |
|
2442 |
uint8_t sys_ind; /* What partition type */ |
|
2443 |
uint8_t end_head; /* end head */ |
|
2444 |
uint8_t end_sector; /* end sector */ |
|
2445 |
uint8_t end_cyl; /* end cylinder */ |
|
2446 |
uint32_t start_sect; /* starting sector counting from 0 */ |
|
2447 |
uint32_t nr_sects; /* nr of sectors in partition */ |
|
2448 |
} __attribute__((packed)); |
|
2449 |
|
|
2450 |
/* try to guess the IDE geometry from the MSDOS partition table */ |
|
2451 |
void ide_guess_geometry(IDEState *s) |
|
2452 |
{ |
|
2453 |
uint8_t buf[512]; |
|
2454 |
int ret, i; |
|
2455 |
struct partition *p; |
|
2456 |
uint32_t nr_sects; |
|
2457 |
|
|
2458 |
if (s->cylinders != 0) |
|
2459 |
return; |
|
2460 |
ret = bdrv_read(s->bs, 0, buf, 1); |
|
2461 |
if (ret < 0) |
|
2462 |
return; |
|
2463 |
/* test msdos magic */ |
|
2464 |
if (buf[510] != 0x55 || buf[511] != 0xaa) |
|
2465 |
return; |
|
2466 |
for(i = 0; i < 4; i++) { |
|
2467 |
p = ((struct partition *)(buf + 0x1be)) + i; |
|
2468 |
nr_sects = tswap32(p->nr_sects); |
|
2469 |
if (nr_sects && p->end_head) { |
|
2470 |
/* We make the assumption that the partition terminates on |
|
2471 |
a cylinder boundary */ |
|
2472 |
s->heads = p->end_head + 1; |
|
2473 |
s->sectors = p->end_sector & 63; |
|
2474 |
s->cylinders = s->nb_sectors / (s->heads * s->sectors); |
|
2475 |
#if 0 |
|
2476 |
printf("guessed partition: CHS=%d %d %d\n", |
|
2477 |
s->cylinders, s->heads, s->sectors); |
|
2478 |
#endif |
|
2479 |
} |
|
2480 |
} |
|
2481 |
} |
|
2482 |
|
|
2437 | 2483 |
void ide_init(void) |
2438 | 2484 |
{ |
2439 | 2485 |
IDEState *s; |
... | ... | |
2445 | 2491 |
s->bs = bs_table[i]; |
2446 | 2492 |
if (s->bs) { |
2447 | 2493 |
bdrv_get_geometry(s->bs, &nb_sectors); |
2494 |
s->nb_sectors = nb_sectors; |
|
2495 |
ide_guess_geometry(s); |
|
2448 | 2496 |
if (s->cylinders == 0) { |
2449 | 2497 |
/* if no geometry, use a LBA compatible one */ |
2450 | 2498 |
cylinders = nb_sectors / (16 * 63); |
... | ... | |
2456 | 2504 |
s->heads = 16; |
2457 | 2505 |
s->sectors = 63; |
2458 | 2506 |
} |
2459 |
s->nb_sectors = nb_sectors; |
|
2460 | 2507 |
} |
2461 | 2508 |
s->irq = 14; |
2462 | 2509 |
ide_reset(s); |
... | ... | |
3136 | 3183 |
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |
3137 | 3184 |
|INLCR|IGNCR|ICRNL|IXON); |
3138 | 3185 |
tty.c_oflag |= OPOST; |
3139 |
tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); |
|
3186 |
tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); |
|
3187 |
/* if graphical mode, we allow Ctrl-C handling */ |
|
3188 |
if (nographic) |
|
3189 |
tty.c_lflag &= ~ISIG; |
|
3140 | 3190 |
tty.c_cflag &= ~(CSIZE|PARENB); |
3141 | 3191 |
tty.c_cflag |= CS8; |
3142 | 3192 |
tty.c_cc[VMIN] = 1; |
... | ... | |
3238 | 3288 |
uint8_t ch; |
3239 | 3289 |
CPUState *env = global_env; |
3240 | 3290 |
|
3241 |
if (nodisp && !term_inited) {
|
|
3291 |
if (!term_inited) { |
|
3242 | 3292 |
/* initialize terminal only there so that the user has a |
3243 | 3293 |
chance to stop QEMU with Ctrl-C before the gdb connection |
3244 | 3294 |
is launched */ |
... | ... | |
3328 | 3378 |
|
3329 | 3379 |
void help(void) |
3330 | 3380 |
{ |
3331 |
printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
|
|
3332 |
"usage: vl [options] [bzImage [kernel parameters...]]\n"
|
|
3381 |
printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
|
|
3382 |
"usage: qemu [options] [disk_image]\n"
|
|
3333 | 3383 |
"\n" |
3334 |
"'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n" |
|
3335 |
"to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n" |
|
3384 |
"'disk_image' is a raw hard image image for IDE hard disk 0\n" |
|
3336 | 3385 |
"\n" |
3337 |
"General options:\n" |
|
3338 |
"-initrd file use 'file' as initial ram disk\n" |
|
3339 |
"-hda file use 'file' as hard disk 0 image\n" |
|
3340 |
"-hdb file use 'file' as hard disk 1 image\n" |
|
3341 |
"-snapshot write to temporary files instead of disk image files\n" |
|
3342 |
"-m megs set virtual RAM size to megs MB\n" |
|
3343 |
"-n script set network init script [default=%s]\n" |
|
3386 |
"Standard options:\n" |
|
3387 |
"-hda file use 'file' as IDE hard disk 0 image\n" |
|
3388 |
"-hdb file use 'file' as IDE hard disk 1 image\n" |
|
3389 |
"-snapshot write to temporary files instead of disk image files\n" |
|
3390 |
"-m megs set virtual RAM size to megs MB\n" |
|
3391 |
"-n script set network init script [default=%s]\n" |
|
3392 |
"-nographic disable graphical output\n" |
|
3393 |
"\n" |
|
3394 |
"Linux boot specific (does not require PC BIOS):\n" |
|
3395 |
"-kernel bzImage use 'bzImage' as kernel image\n" |
|
3396 |
"-append cmdline use 'cmdline' as kernel command line\n" |
|
3397 |
"-initrd file use 'file' as initial ram disk\n" |
|
3344 | 3398 |
"\n" |
3345 | 3399 |
"Debug/Expert options:\n" |
3346 |
"-s wait gdb connection to port %d\n" |
|
3347 |
"-p port change gdb connection port\n" |
|
3348 |
"-d output log in /tmp/vl.log\n" |
|
3349 |
"-hdachs c,h,s force hard disk 0 geometry for non LBA disk images\n"
|
|
3350 |
"-L path set the directory for the BIOS and VGA BIOS\n" |
|
3400 |
"-s wait gdb connection to port %d\n"
|
|
3401 |
"-p port change gdb connection port\n"
|
|
3402 |
"-d output log in /tmp/vl.log\n"
|
|
3403 |
"-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
|
|
3404 |
"-L path set the directory for the BIOS and VGA BIOS\n"
|
|
3351 | 3405 |
"\n" |
3352 | 3406 |
"During emulation, use C-a h to get terminal commands:\n", |
3353 | 3407 |
DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT); |
... | ... | |
3361 | 3415 |
{ "hdb", 1, NULL, 0, }, |
3362 | 3416 |
{ "snapshot", 0, NULL, 0, }, |
3363 | 3417 |
{ "hdachs", 1, NULL, 0, }, |
3364 |
{ "nodisp", 0, NULL, 0, }, |
|
3418 |
{ "nographic", 0, NULL, 0, }, |
|
3419 |
{ "kernel", 1, NULL, 0, }, |
|
3420 |
{ "append", 1, NULL, 0, }, |
|
3365 | 3421 |
{ NULL, 0, NULL, 0 }, |
3366 | 3422 |
}; |
3367 | 3423 |
|
3424 |
#ifdef CONFIG_SDL |
|
3425 |
/* SDL use the pthreads and they modify sigaction. We don't |
|
3426 |
want that. */ |
|
3427 |
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) |
|
3428 |
extern void __libc_sigaction(); |
|
3429 |
#define sigaction(sig, act, oact) __libc_sigaction(sig, act, oact) |
|
3430 |
#else |
|
3431 |
extern void __sigaction(); |
|
3432 |
#define sigaction(sig, act, oact) __sigaction(sig, act, oact) |
|
3433 |
#endif |
|
3434 |
#endif /* CONFIG_SDL */ |
|
3435 |
|
|
3368 | 3436 |
int main(int argc, char **argv) |
3369 | 3437 |
{ |
3370 | 3438 |
int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index; |
... | ... | |
3375 | 3443 |
CPUX86State *env; |
3376 | 3444 |
const char *tmpdir, *initrd_filename; |
3377 | 3445 |
const char *hd_filename[MAX_DISKS]; |
3446 |
const char *kernel_filename, *kernel_cmdline; |
|
3378 | 3447 |
DisplayState *ds = &display_state; |
3379 | 3448 |
|
3380 | 3449 |
/* we never want that malloc() uses mmap() */ |
... | ... | |
3388 | 3457 |
use_gdbstub = 0; |
3389 | 3458 |
gdbstub_port = DEFAULT_GDBSTUB_PORT; |
3390 | 3459 |
snapshot = 0; |
3391 |
linux_boot = 0; |
|
3392 |
nodisp = 0; |
|
3460 |
nographic = 0; |
|
3461 |
kernel_filename = NULL; |
|
3462 |
kernel_cmdline = ""; |
|
3393 | 3463 |
for(;;) { |
3394 | 3464 |
c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index); |
3395 | 3465 |
if (c == -1) |
... | ... | |
3432 | 3502 |
} |
3433 | 3503 |
break; |
3434 | 3504 |
case 5: |
3435 |
nodisp = 1; |
|
3505 |
nographic = 1; |
|
3506 |
break; |
|
3507 |
case 6: |
|
3508 |
kernel_filename = optarg; |
|
3509 |
break; |
|
3510 |
case 7: |
|
3511 |
kernel_cmdline = optarg; |
|
3436 | 3512 |
break; |
3437 | 3513 |
} |
3438 | 3514 |
break; |
... | ... | |
3467 | 3543 |
} |
3468 | 3544 |
} |
3469 | 3545 |
|
3470 |
linux_boot = (optind < argc); |
|
3546 |
if (optind < argc) { |
|
3547 |
hd_filename[0] = argv[optind++]; |
|
3548 |
} |
|
3549 |
|
|
3550 |
linux_boot = (kernel_filename != NULL); |
|
3471 | 3551 |
|
3472 | 3552 |
if (!linux_boot && hd_filename[0] == '\0') |
3473 | 3553 |
help(); |
... | ... | |
3487 | 3567 |
net_init(); |
3488 | 3568 |
|
3489 | 3569 |
/* init the memory */ |
3490 |
tmpdir = getenv("VLTMPDIR");
|
|
3570 |
tmpdir = getenv("QEMU_TMPDIR");
|
|
3491 | 3571 |
if (!tmpdir) |
3492 | 3572 |
tmpdir = "/tmp"; |
3493 | 3573 |
snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir); |
... | ... | |
3538 | 3618 |
|
3539 | 3619 |
if (linux_boot) { |
3540 | 3620 |
/* now we can load the kernel */ |
3541 |
ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
|
|
3621 |
ret = load_kernel(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
|
|
3542 | 3622 |
if (ret < 0) { |
3543 |
fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]); |
|
3623 |
fprintf(stderr, "vl: could not load kernel '%s'\n", |
|
3624 |
kernel_filename); |
|
3544 | 3625 |
exit(1); |
3545 | 3626 |
} |
3546 | 3627 |
|
... | ... | |
3562 | 3643 |
params->cl_magic = 0xA33F; |
3563 | 3644 |
params->cl_offset = params->commandline - (uint8_t *)params; |
3564 | 3645 |
params->alt_mem_k = (phys_ram_size / 1024) - 1024; |
3565 |
for(i = optind + 1; i < argc; i++) { |
|
3566 |
if (i != optind + 1) |
|
3567 |
pstrcat(params->commandline, sizeof(params->commandline), " "); |
|
3568 |
pstrcat(params->commandline, sizeof(params->commandline), argv[i]); |
|
3569 |
} |
|
3646 |
pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline); |
|
3570 | 3647 |
params->loader_type = 0x01; |
3571 | 3648 |
if (initrd_size > 0) { |
3572 | 3649 |
params->initrd_start = INITRD_LOAD_ADDR; |
... | ... | |
3602 | 3679 |
|
3603 | 3680 |
} else { |
3604 | 3681 |
char buf[1024]; |
3605 |
|
|
3682 |
|
|
3606 | 3683 |
/* RAW PC boot */ |
3607 | 3684 |
|
3608 | 3685 |
/* BIOS load */ |
... | ... | |
3642 | 3719 |
} |
3643 | 3720 |
|
3644 | 3721 |
/* terminal init */ |
3645 |
if (nodisp) {
|
|
3722 |
if (nographic) {
|
|
3646 | 3723 |
dumb_display_init(ds); |
3647 | 3724 |
} else { |
3648 | 3725 |
#ifdef CONFIG_SDL |
3649 | 3726 |
sdl_display_init(ds); |
3650 |
/* SDL use the pthreads and they modify sigaction. We don't |
|
3651 |
want that. */ |
|
3652 |
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) |
|
3653 |
#define sigaction __libc_sigaction |
|
3654 |
#else |
|
3655 |
#define sigaction __sigaction |
|
3656 |
#endif |
|
3657 | 3727 |
#else |
3658 | 3728 |
dumb_display_init(ds); |
3659 | 3729 |
#endif |
Also available in: Unified diff