mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
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:
parent
6180a1818a
commit
a20dd508aa
1 changed files with 113 additions and 43 deletions
156
vl.c
156
vl.c
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue