Commit a20dd508aa3895b2e5f4d4f255a4d6306b5e2631

Authored by bellard
1 parent 6180a181

simplified invocation - added automatic IDE disk geometry guessing to reuse old disk images directly


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@392 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 113 additions and 43 deletions
@@ -44,7 +44,7 @@ @@ -44,7 +44,7 @@
44 #include <linux/if.h> 44 #include <linux/if.h>
45 #include <linux/if_tun.h> 45 #include <linux/if_tun.h>
46 46
47 -#include "cpu-i386.h" 47 +#include "cpu.h"
48 #include "disas.h" 48 #include "disas.h"
49 #include "thunk.h" 49 #include "thunk.h"
50 50
@@ -216,7 +216,7 @@ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; @@ -216,7 +216,7 @@ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
216 BlockDriverState *bs_table[MAX_DISKS]; 216 BlockDriverState *bs_table[MAX_DISKS];
217 int vga_ram_size; 217 int vga_ram_size;
218 static DisplayState display_state; 218 static DisplayState display_state;
219 -int nodisp; 219 +int nographic;
220 int term_inited; 220 int term_inited;
221 int64_t ticks_per_sec; 221 int64_t ticks_per_sec;
222 222
@@ -2434,6 +2434,52 @@ void ide_reset(IDEState *s) @@ -2434,6 +2434,52 @@ void ide_reset(IDEState *s)
2434 s->select = 0xa0; 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 void ide_init(void) 2483 void ide_init(void)
2438 { 2484 {
2439 IDEState *s; 2485 IDEState *s;
@@ -2445,6 +2491,8 @@ void ide_init(void) @@ -2445,6 +2491,8 @@ void ide_init(void)
2445 s->bs = bs_table[i]; 2491 s->bs = bs_table[i];
2446 if (s->bs) { 2492 if (s->bs) {
2447 bdrv_get_geometry(s->bs, &nb_sectors); 2493 bdrv_get_geometry(s->bs, &nb_sectors);
  2494 + s->nb_sectors = nb_sectors;
  2495 + ide_guess_geometry(s);
2448 if (s->cylinders == 0) { 2496 if (s->cylinders == 0) {
2449 /* if no geometry, use a LBA compatible one */ 2497 /* if no geometry, use a LBA compatible one */
2450 cylinders = nb_sectors / (16 * 63); 2498 cylinders = nb_sectors / (16 * 63);
@@ -2456,7 +2504,6 @@ void ide_init(void) @@ -2456,7 +2504,6 @@ void ide_init(void)
2456 s->heads = 16; 2504 s->heads = 16;
2457 s->sectors = 63; 2505 s->sectors = 63;
2458 } 2506 }
2459 - s->nb_sectors = nb_sectors;  
2460 } 2507 }
2461 s->irq = 14; 2508 s->irq = 14;
2462 ide_reset(s); 2509 ide_reset(s);
@@ -3136,7 +3183,10 @@ static void term_init(void) @@ -3136,7 +3183,10 @@ static void term_init(void)
3136 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP 3183 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
3137 |INLCR|IGNCR|ICRNL|IXON); 3184 |INLCR|IGNCR|ICRNL|IXON);
3138 tty.c_oflag |= OPOST; 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 tty.c_cflag &= ~(CSIZE|PARENB); 3190 tty.c_cflag &= ~(CSIZE|PARENB);
3141 tty.c_cflag |= CS8; 3191 tty.c_cflag |= CS8;
3142 tty.c_cc[VMIN] = 1; 3192 tty.c_cc[VMIN] = 1;
@@ -3238,7 +3288,7 @@ int main_loop(void *opaque) @@ -3238,7 +3288,7 @@ int main_loop(void *opaque)
3238 uint8_t ch; 3288 uint8_t ch;
3239 CPUState *env = global_env; 3289 CPUState *env = global_env;
3240 3290
3241 - if (nodisp && !term_inited) { 3291 + if (!term_inited) {
3242 /* initialize terminal only there so that the user has a 3292 /* initialize terminal only there so that the user has a
3243 chance to stop QEMU with Ctrl-C before the gdb connection 3293 chance to stop QEMU with Ctrl-C before the gdb connection
3244 is launched */ 3294 is launched */
@@ -3328,26 +3378,30 @@ int main_loop(void *opaque) @@ -3328,26 +3378,30 @@ int main_loop(void *opaque)
3328 3378
3329 void help(void) 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 "\n" 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 "\n" 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 "\n" 3398 "\n"
3345 "Debug/Expert options:\n" 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 "\n" 3405 "\n"
3352 "During emulation, use C-a h to get terminal commands:\n", 3406 "During emulation, use C-a h to get terminal commands:\n",
3353 DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT); 3407 DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);
@@ -3361,10 +3415,24 @@ struct option long_options[] = { @@ -3361,10 +3415,24 @@ struct option long_options[] = {
3361 { "hdb", 1, NULL, 0, }, 3415 { "hdb", 1, NULL, 0, },
3362 { "snapshot", 0, NULL, 0, }, 3416 { "snapshot", 0, NULL, 0, },
3363 { "hdachs", 1, NULL, 0, }, 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 { NULL, 0, NULL, 0 }, 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 int main(int argc, char **argv) 3436 int main(int argc, char **argv)
3369 { 3437 {
3370 int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index; 3438 int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
@@ -3375,6 +3443,7 @@ int main(int argc, char **argv) @@ -3375,6 +3443,7 @@ int main(int argc, char **argv)
3375 CPUX86State *env; 3443 CPUX86State *env;
3376 const char *tmpdir, *initrd_filename; 3444 const char *tmpdir, *initrd_filename;
3377 const char *hd_filename[MAX_DISKS]; 3445 const char *hd_filename[MAX_DISKS];
  3446 + const char *kernel_filename, *kernel_cmdline;
3378 DisplayState *ds = &display_state; 3447 DisplayState *ds = &display_state;
3379 3448
3380 /* we never want that malloc() uses mmap() */ 3449 /* we never want that malloc() uses mmap() */
@@ -3388,8 +3457,9 @@ int main(int argc, char **argv) @@ -3388,8 +3457,9 @@ int main(int argc, char **argv)
3388 use_gdbstub = 0; 3457 use_gdbstub = 0;
3389 gdbstub_port = DEFAULT_GDBSTUB_PORT; 3458 gdbstub_port = DEFAULT_GDBSTUB_PORT;
3390 snapshot = 0; 3459 snapshot = 0;
3391 - linux_boot = 0;  
3392 - nodisp = 0; 3460 + nographic = 0;
  3461 + kernel_filename = NULL;
  3462 + kernel_cmdline = "";
3393 for(;;) { 3463 for(;;) {
3394 c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index); 3464 c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);
3395 if (c == -1) 3465 if (c == -1)
@@ -3432,7 +3502,13 @@ int main(int argc, char **argv) @@ -3432,7 +3502,13 @@ int main(int argc, char **argv)
3432 } 3502 }
3433 break; 3503 break;
3434 case 5: 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 break; 3512 break;
3437 } 3513 }
3438 break; 3514 break;
@@ -3467,7 +3543,11 @@ int main(int argc, char **argv) @@ -3467,7 +3543,11 @@ int main(int argc, char **argv)
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 if (!linux_boot && hd_filename[0] == '\0') 3552 if (!linux_boot && hd_filename[0] == '\0')
3473 help(); 3553 help();
@@ -3487,7 +3567,7 @@ int main(int argc, char **argv) @@ -3487,7 +3567,7 @@ int main(int argc, char **argv)
3487 net_init(); 3567 net_init();
3488 3568
3489 /* init the memory */ 3569 /* init the memory */
3490 - tmpdir = getenv("VLTMPDIR"); 3570 + tmpdir = getenv("QEMU_TMPDIR");
3491 if (!tmpdir) 3571 if (!tmpdir)
3492 tmpdir = "/tmp"; 3572 tmpdir = "/tmp";
3493 snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir); 3573 snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir);
@@ -3538,9 +3618,10 @@ int main(int argc, char **argv) @@ -3538,9 +3618,10 @@ int main(int argc, char **argv)
3538 3618
3539 if (linux_boot) { 3619 if (linux_boot) {
3540 /* now we can load the kernel */ 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 if (ret < 0) { 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 exit(1); 3625 exit(1);
3545 } 3626 }
3546 3627
@@ -3562,11 +3643,7 @@ int main(int argc, char **argv) @@ -3562,11 +3643,7 @@ int main(int argc, char **argv)
3562 params->cl_magic = 0xA33F; 3643 params->cl_magic = 0xA33F;
3563 params->cl_offset = params->commandline - (uint8_t *)params; 3644 params->cl_offset = params->commandline - (uint8_t *)params;
3564 params->alt_mem_k = (phys_ram_size / 1024) - 1024; 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 params->loader_type = 0x01; 3647 params->loader_type = 0x01;
3571 if (initrd_size > 0) { 3648 if (initrd_size > 0) {
3572 params->initrd_start = INITRD_LOAD_ADDR; 3649 params->initrd_start = INITRD_LOAD_ADDR;
@@ -3602,7 +3679,7 @@ int main(int argc, char **argv) @@ -3602,7 +3679,7 @@ int main(int argc, char **argv)
3602 3679
3603 } else { 3680 } else {
3604 char buf[1024]; 3681 char buf[1024];
3605 - 3682 +
3606 /* RAW PC boot */ 3683 /* RAW PC boot */
3607 3684
3608 /* BIOS load */ 3685 /* BIOS load */
@@ -3642,18 +3719,11 @@ int main(int argc, char **argv) @@ -3642,18 +3719,11 @@ int main(int argc, char **argv)
3642 } 3719 }
3643 3720
3644 /* terminal init */ 3721 /* terminal init */
3645 - if (nodisp) { 3722 + if (nographic) {
3646 dumb_display_init(ds); 3723 dumb_display_init(ds);
3647 } else { 3724 } else {
3648 #ifdef CONFIG_SDL 3725 #ifdef CONFIG_SDL
3649 sdl_display_init(ds); 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 #else 3727 #else
3658 dumb_display_init(ds); 3728 dumb_display_init(ds);
3659 #endif 3729 #endif