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
This commit is contained in:
bellard 2003-09-30 21:07:02 +00:00
parent 6180a1818a
commit a20dd508aa

156
vl.c
View file

@ -44,7 +44,7 @@
#include <linux/if.h>
#include <linux/if_tun.h>
#include "cpu-i386.h"
#include "cpu.h"
#include "disas.h"
#include "thunk.h"
@ -216,7 +216,7 @@ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
BlockDriverState *bs_table[MAX_DISKS];
int vga_ram_size;
static DisplayState display_state;
int nodisp;
int nographic;
int term_inited;
int64_t ticks_per_sec;
@ -2434,6 +2434,52 @@ void ide_reset(IDEState *s)
s->select = 0xa0;
}
struct partition {
uint8_t boot_ind; /* 0x80 - active */
uint8_t head; /* starting head */
uint8_t sector; /* starting sector */
uint8_t cyl; /* starting cylinder */
uint8_t sys_ind; /* What partition type */
uint8_t end_head; /* end head */
uint8_t end_sector; /* end sector */
uint8_t end_cyl; /* end cylinder */
uint32_t start_sect; /* starting sector counting from 0 */
uint32_t nr_sects; /* nr of sectors in partition */
} __attribute__((packed));
/* try to guess the IDE geometry from the MSDOS partition table */
void ide_guess_geometry(IDEState *s)
{
uint8_t buf[512];
int ret, i;
struct partition *p;
uint32_t nr_sects;
if (s->cylinders != 0)
return;
ret = bdrv_read(s->bs, 0, buf, 1);
if (ret < 0)
return;
/* test msdos magic */
if (buf[510] != 0x55 || buf[511] != 0xaa)
return;
for(i = 0; i < 4; i++) {
p = ((struct partition *)(buf + 0x1be)) + i;
nr_sects = tswap32(p->nr_sects);
if (nr_sects && p->end_head) {
/* We make the assumption that the partition terminates on
a cylinder boundary */
s->heads = p->end_head + 1;
s->sectors = p->end_sector & 63;
s->cylinders = s->nb_sectors / (s->heads * s->sectors);
#if 0
printf("guessed partition: CHS=%d %d %d\n",
s->cylinders, s->heads, s->sectors);
#endif
}
}
}
void ide_init(void)
{
IDEState *s;
@ -2445,6 +2491,8 @@ void ide_init(void)
s->bs = bs_table[i];
if (s->bs) {
bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors;
ide_guess_geometry(s);
if (s->cylinders == 0) {
/* if no geometry, use a LBA compatible one */
cylinders = nb_sectors / (16 * 63);
@ -2456,7 +2504,6 @@ void ide_init(void)
s->heads = 16;
s->sectors = 63;
}
s->nb_sectors = nb_sectors;
}
s->irq = 14;
ide_reset(s);
@ -3136,7 +3183,10 @@ static void term_init(void)
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
tty.c_oflag |= OPOST;
tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
/* if graphical mode, we allow Ctrl-C handling */
if (nographic)
tty.c_lflag &= ~ISIG;
tty.c_cflag &= ~(CSIZE|PARENB);
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
@ -3238,7 +3288,7 @@ int main_loop(void *opaque)
uint8_t ch;
CPUState *env = global_env;
if (nodisp && !term_inited) {
if (!term_inited) {
/* initialize terminal only there so that the user has a
chance to stop QEMU with Ctrl-C before the gdb connection
is launched */
@ -3328,26 +3378,30 @@ int main_loop(void *opaque)
void help(void)
{
printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
"usage: vl [options] [bzImage [kernel parameters...]]\n"
printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
"usage: qemu [options] [disk_image]\n"
"\n"
"'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"
"to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"
"'disk_image' is a raw hard image image for IDE hard disk 0\n"
"\n"
"General options:\n"
"-initrd file use 'file' as initial ram disk\n"
"-hda file use 'file' as hard disk 0 image\n"
"-hdb file use 'file' as hard disk 1 image\n"
"-snapshot write to temporary files instead of disk image files\n"
"-m megs set virtual RAM size to megs MB\n"
"-n script set network init script [default=%s]\n"
"Standard options:\n"
"-hda file use 'file' as IDE hard disk 0 image\n"
"-hdb file use 'file' as IDE hard disk 1 image\n"
"-snapshot write to temporary files instead of disk image files\n"
"-m megs set virtual RAM size to megs MB\n"
"-n script set network init script [default=%s]\n"
"-nographic disable graphical output\n"
"\n"
"Linux boot specific (does not require PC BIOS):\n"
"-kernel bzImage use 'bzImage' as kernel image\n"
"-append cmdline use 'cmdline' as kernel command line\n"
"-initrd file use 'file' as initial ram disk\n"
"\n"
"Debug/Expert options:\n"
"-s wait gdb connection to port %d\n"
"-p port change gdb connection port\n"
"-d output log in /tmp/vl.log\n"
"-hdachs c,h,s force hard disk 0 geometry for non LBA disk images\n"
"-L path set the directory for the BIOS and VGA BIOS\n"
"-s wait gdb connection to port %d\n"
"-p port change gdb connection port\n"
"-d output log in /tmp/vl.log\n"
"-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
"-L path set the directory for the BIOS and VGA BIOS\n"
"\n"
"During emulation, use C-a h to get terminal commands:\n",
DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);
@ -3361,10 +3415,24 @@ struct option long_options[] = {
{ "hdb", 1, NULL, 0, },
{ "snapshot", 0, NULL, 0, },
{ "hdachs", 1, NULL, 0, },
{ "nodisp", 0, NULL, 0, },
{ "nographic", 0, NULL, 0, },
{ "kernel", 1, NULL, 0, },
{ "append", 1, NULL, 0, },
{ NULL, 0, NULL, 0 },
};
#ifdef CONFIG_SDL
/* SDL use the pthreads and they modify sigaction. We don't
want that. */
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
extern void __libc_sigaction();
#define sigaction(sig, act, oact) __libc_sigaction(sig, act, oact)
#else
extern void __sigaction();
#define sigaction(sig, act, oact) __sigaction(sig, act, oact)
#endif
#endif /* CONFIG_SDL */
int main(int argc, char **argv)
{
int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
@ -3375,6 +3443,7 @@ int main(int argc, char **argv)
CPUX86State *env;
const char *tmpdir, *initrd_filename;
const char *hd_filename[MAX_DISKS];
const char *kernel_filename, *kernel_cmdline;
DisplayState *ds = &display_state;
/* we never want that malloc() uses mmap() */
@ -3388,8 +3457,9 @@ int main(int argc, char **argv)
use_gdbstub = 0;
gdbstub_port = DEFAULT_GDBSTUB_PORT;
snapshot = 0;
linux_boot = 0;
nodisp = 0;
nographic = 0;
kernel_filename = NULL;
kernel_cmdline = "";
for(;;) {
c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);
if (c == -1)
@ -3432,7 +3502,13 @@ int main(int argc, char **argv)
}
break;
case 5:
nodisp = 1;
nographic = 1;
break;
case 6:
kernel_filename = optarg;
break;
case 7:
kernel_cmdline = optarg;
break;
}
break;
@ -3467,7 +3543,11 @@ int main(int argc, char **argv)
}
}
linux_boot = (optind < argc);
if (optind < argc) {
hd_filename[0] = argv[optind++];
}
linux_boot = (kernel_filename != NULL);
if (!linux_boot && hd_filename[0] == '\0')
help();
@ -3487,7 +3567,7 @@ int main(int argc, char **argv)
net_init();
/* init the memory */
tmpdir = getenv("VLTMPDIR");
tmpdir = getenv("QEMU_TMPDIR");
if (!tmpdir)
tmpdir = "/tmp";
snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir);
@ -3538,9 +3618,10 @@ int main(int argc, char **argv)
if (linux_boot) {
/* now we can load the kernel */
ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
ret = load_kernel(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
if (ret < 0) {
fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);
fprintf(stderr, "vl: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
@ -3562,11 +3643,7 @@ int main(int argc, char **argv)
params->cl_magic = 0xA33F;
params->cl_offset = params->commandline - (uint8_t *)params;
params->alt_mem_k = (phys_ram_size / 1024) - 1024;
for(i = optind + 1; i < argc; i++) {
if (i != optind + 1)
pstrcat(params->commandline, sizeof(params->commandline), " ");
pstrcat(params->commandline, sizeof(params->commandline), argv[i]);
}
pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline);
params->loader_type = 0x01;
if (initrd_size > 0) {
params->initrd_start = INITRD_LOAD_ADDR;
@ -3602,7 +3679,7 @@ int main(int argc, char **argv)
} else {
char buf[1024];
/* RAW PC boot */
/* BIOS load */
@ -3642,18 +3719,11 @@ int main(int argc, char **argv)
}
/* terminal init */
if (nodisp) {
if (nographic) {
dumb_display_init(ds);
} else {
#ifdef CONFIG_SDL
sdl_display_init(ds);
/* SDL use the pthreads and they modify sigaction. We don't
want that. */
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
#define sigaction __libc_sigaction
#else
#define sigaction __sigaction
#endif
#else
dumb_display_init(ds);
#endif