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 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,7 +216,7 @@ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
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,6 +2434,52 @@ void ide_reset(IDEState *s)
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,6 +2491,8 @@ void ide_init(void)
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,7 +2504,6 @@ void ide_init(void)
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,7 +3183,10 @@ static void term_init(void)
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,7 +3288,7 @@ int main_loop(void *opaque)
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,26 +3378,30 @@ int main_loop(void *opaque)
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,10 +3415,24 @@ struct option long_options[] = {
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,6 +3443,7 @@ int main(int argc, char **argv)
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,8 +3457,9 @@ int main(int argc, char **argv)
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,7 +3502,13 @@ int main(int argc, char **argv)
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,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 3552 if (!linux_boot && hd_filename[0] == '\0')
3473 3553 help();
... ... @@ -3487,7 +3567,7 @@ int main(int argc, char **argv)
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,9 +3618,10 @@ int main(int argc, char **argv)
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,11 +3643,7 @@ int main(int argc, char **argv)
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,7 +3679,7 @@ int main(int argc, char **argv)
3602 3679  
3603 3680 } else {
3604 3681 char buf[1024];
3605   -
  3682 +
3606 3683 /* RAW PC boot */
3607 3684  
3608 3685 /* BIOS load */
... ... @@ -3642,18 +3719,11 @@ int main(int argc, char **argv)
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
... ...