mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 16:23:55 -06:00
custom option parsing to have same behavior on all OSes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@805 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b939777cec
commit
cd6f11693a
1 changed files with 176 additions and 97 deletions
273
vl.c
273
vl.c
|
@ -23,7 +23,6 @@
|
||||||
*/
|
*/
|
||||||
#include "vl.h"
|
#include "vl.h"
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -1908,6 +1907,7 @@ void help(void)
|
||||||
"-initrd file use 'file' as initial ram disk\n"
|
"-initrd file use 'file' as initial ram disk\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Debug/Expert options:\n"
|
"Debug/Expert options:\n"
|
||||||
|
"-S freeze CPU at startup (use 'c' to start execution)\n"
|
||||||
"-s wait gdb connection to port %d\n"
|
"-s wait gdb connection to port %d\n"
|
||||||
"-p port change gdb connection port\n"
|
"-p port change gdb connection port\n"
|
||||||
"-d item1,... output log to %s (use -d ? for a list of log items)\n"
|
"-d item1,... output log to %s (use -d ? for a list of log items)\n"
|
||||||
|
@ -1937,29 +1937,85 @@ void help(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct option long_options[] = {
|
#define HAS_ARG 0x0001
|
||||||
{ "initrd", 1, NULL, 0, },
|
|
||||||
{ "hda", 1, NULL, 0, },
|
enum {
|
||||||
{ "hdb", 1, NULL, 0, },
|
QEMU_OPTION_h,
|
||||||
{ "snapshot", 0, NULL, 0, },
|
|
||||||
{ "hdachs", 1, NULL, 0, },
|
QEMU_OPTION_fda,
|
||||||
{ "nographic", 0, NULL, 0, },
|
QEMU_OPTION_fdb,
|
||||||
{ "kernel", 1, NULL, 0, },
|
QEMU_OPTION_hda,
|
||||||
{ "append", 1, NULL, 0, },
|
QEMU_OPTION_hdb,
|
||||||
{ "tun-fd", 1, NULL, 0, },
|
QEMU_OPTION_hdc,
|
||||||
{ "hdc", 1, NULL, 0, },
|
QEMU_OPTION_hdd,
|
||||||
{ "hdd", 1, NULL, 0, },
|
QEMU_OPTION_cdrom,
|
||||||
{ "cdrom", 1, NULL, 0, },
|
QEMU_OPTION_boot,
|
||||||
{ "boot", 1, NULL, 0, },
|
QEMU_OPTION_snapshot,
|
||||||
{ "fda", 1, NULL, 0, },
|
QEMU_OPTION_m,
|
||||||
{ "fdb", 1, NULL, 0, },
|
QEMU_OPTION_nographic,
|
||||||
{ "no-code-copy", 0, NULL, 0 },
|
QEMU_OPTION_enable_audio,
|
||||||
{ "nics", 1, NULL, 0 },
|
|
||||||
{ "macaddr", 1, NULL, 0 },
|
QEMU_OPTION_nics,
|
||||||
{ "user-net", 0, NULL, 0 },
|
QEMU_OPTION_macaddr,
|
||||||
{ "dummy-net", 0, NULL, 0 },
|
QEMU_OPTION_n,
|
||||||
{ "enable-audio", 0, NULL, 0 },
|
QEMU_OPTION_tun_fd,
|
||||||
{ NULL, 0, NULL, 0 },
|
QEMU_OPTION_user_net,
|
||||||
|
QEMU_OPTION_dummy_net,
|
||||||
|
|
||||||
|
QEMU_OPTION_kernel,
|
||||||
|
QEMU_OPTION_append,
|
||||||
|
QEMU_OPTION_initrd,
|
||||||
|
|
||||||
|
QEMU_OPTION_S,
|
||||||
|
QEMU_OPTION_s,
|
||||||
|
QEMU_OPTION_p,
|
||||||
|
QEMU_OPTION_d,
|
||||||
|
QEMU_OPTION_hdachs,
|
||||||
|
QEMU_OPTION_L,
|
||||||
|
QEMU_OPTION_no_code_copy,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct QEMUOption {
|
||||||
|
const char *name;
|
||||||
|
int flags;
|
||||||
|
int index;
|
||||||
|
} QEMUOption;
|
||||||
|
|
||||||
|
const QEMUOption qemu_options[] = {
|
||||||
|
{ "h", 0, QEMU_OPTION_h },
|
||||||
|
|
||||||
|
{ "fda", HAS_ARG, QEMU_OPTION_fda },
|
||||||
|
{ "fdb", HAS_ARG, QEMU_OPTION_fdb },
|
||||||
|
{ "hda", HAS_ARG, QEMU_OPTION_hda },
|
||||||
|
{ "hdb", HAS_ARG, QEMU_OPTION_hdb },
|
||||||
|
{ "hdc", HAS_ARG, QEMU_OPTION_hdc },
|
||||||
|
{ "hdd", HAS_ARG, QEMU_OPTION_hdd },
|
||||||
|
{ "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
|
||||||
|
{ "boot", HAS_ARG, QEMU_OPTION_boot },
|
||||||
|
{ "snapshot", 0, QEMU_OPTION_snapshot },
|
||||||
|
{ "m", HAS_ARG, QEMU_OPTION_m },
|
||||||
|
{ "nographic", 0, QEMU_OPTION_nographic },
|
||||||
|
{ "enable-audio", 0, QEMU_OPTION_enable_audio },
|
||||||
|
|
||||||
|
{ "nics", HAS_ARG, QEMU_OPTION_nics},
|
||||||
|
{ "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
|
||||||
|
{ "n", HAS_ARG, QEMU_OPTION_d },
|
||||||
|
{ "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
|
||||||
|
{ "user-net", 0, QEMU_OPTION_user_net },
|
||||||
|
{ "dummy-net", 0, QEMU_OPTION_dummy_net },
|
||||||
|
|
||||||
|
{ "kernel", HAS_ARG, QEMU_OPTION_kernel },
|
||||||
|
{ "append", HAS_ARG, QEMU_OPTION_append },
|
||||||
|
{ "initrd", HAS_ARG, QEMU_OPTION_initrd },
|
||||||
|
|
||||||
|
{ "S", 0, QEMU_OPTION_S },
|
||||||
|
{ "s", 0, QEMU_OPTION_s },
|
||||||
|
{ "p", HAS_ARG, QEMU_OPTION_p },
|
||||||
|
{ "d", HAS_ARG, QEMU_OPTION_d },
|
||||||
|
{ "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
|
||||||
|
{ "L", HAS_ARG, QEMU_OPTION_L },
|
||||||
|
{ "no-code-copy", 0, QEMU_OPTION_no_code_copy },
|
||||||
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
|
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
|
||||||
|
@ -1980,7 +2036,7 @@ int main(int argc, char **argv)
|
||||||
#ifdef CONFIG_GDBSTUB
|
#ifdef CONFIG_GDBSTUB
|
||||||
int use_gdbstub, gdbstub_port;
|
int use_gdbstub, gdbstub_port;
|
||||||
#endif
|
#endif
|
||||||
int c, i, long_index, has_cdrom;
|
int i, has_cdrom;
|
||||||
int snapshot, linux_boot;
|
int snapshot, linux_boot;
|
||||||
CPUState *env;
|
CPUState *env;
|
||||||
const char *initrd_filename;
|
const char *initrd_filename;
|
||||||
|
@ -1991,7 +2047,9 @@ int main(int argc, char **argv)
|
||||||
int start_emulation = 1;
|
int start_emulation = 1;
|
||||||
uint8_t macaddr[6];
|
uint8_t macaddr[6];
|
||||||
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
||||||
|
int optind;
|
||||||
|
const char *r, *optarg;
|
||||||
|
|
||||||
#if !defined(CONFIG_SOFTMMU)
|
#if !defined(CONFIG_SOFTMMU)
|
||||||
/* we never want that malloc() uses mmap() */
|
/* we never want that malloc() uses mmap() */
|
||||||
mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
|
mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
|
||||||
|
@ -2026,27 +2084,53 @@ int main(int argc, char **argv)
|
||||||
macaddr[4] = 0x34;
|
macaddr[4] = 0x34;
|
||||||
macaddr[5] = 0x56;
|
macaddr[5] = 0x56;
|
||||||
|
|
||||||
|
optind = 1;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index);
|
if (optind >= argc)
|
||||||
if (c == -1)
|
|
||||||
break;
|
break;
|
||||||
switch(c) {
|
r = argv[optind];
|
||||||
case 0:
|
if (r[0] != '-') {
|
||||||
switch(long_index) {
|
hd_filename[0] = argv[optind++];
|
||||||
case 0:
|
} else {
|
||||||
|
const QEMUOption *popt;
|
||||||
|
|
||||||
|
optind++;
|
||||||
|
popt = qemu_options;
|
||||||
|
for(;;) {
|
||||||
|
if (!popt->name) {
|
||||||
|
fprintf(stderr, "%s: invalid option -- '%s'\n",
|
||||||
|
argv[0], r);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!strcmp(popt->name, r + 1))
|
||||||
|
break;
|
||||||
|
popt++;
|
||||||
|
}
|
||||||
|
if (popt->flags & HAS_ARG) {
|
||||||
|
if (optind >= argc) {
|
||||||
|
fprintf(stderr, "%s: option '%s' requires an argument\n",
|
||||||
|
argv[0], r);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
optarg = argv[optind++];
|
||||||
|
} else {
|
||||||
|
optarg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(popt->index) {
|
||||||
|
case QEMU_OPTION_initrd:
|
||||||
initrd_filename = optarg;
|
initrd_filename = optarg;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case QEMU_OPTION_hda:
|
||||||
hd_filename[0] = optarg;
|
hd_filename[0] = optarg;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case QEMU_OPTION_hdb:
|
||||||
hd_filename[1] = optarg;
|
hd_filename[1] = optarg;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case QEMU_OPTION_snapshot:
|
||||||
snapshot = 1;
|
snapshot = 1;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case QEMU_OPTION_hdachs:
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
p = optarg;
|
p = optarg;
|
||||||
|
@ -2065,16 +2149,16 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case QEMU_OPTION_nographic:
|
||||||
nographic = 1;
|
nographic = 1;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case QEMU_OPTION_kernel:
|
||||||
kernel_filename = optarg;
|
kernel_filename = optarg;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case QEMU_OPTION_append:
|
||||||
kernel_cmdline = optarg;
|
kernel_cmdline = optarg;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case QEMU_OPTION_tun_fd:
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -2089,18 +2173,18 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case QEMU_OPTION_hdc:
|
||||||
hd_filename[2] = optarg;
|
hd_filename[2] = optarg;
|
||||||
has_cdrom = 0;
|
has_cdrom = 0;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case QEMU_OPTION_hdd:
|
||||||
hd_filename[3] = optarg;
|
hd_filename[3] = optarg;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case QEMU_OPTION_cdrom:
|
||||||
hd_filename[2] = optarg;
|
hd_filename[2] = optarg;
|
||||||
has_cdrom = 1;
|
has_cdrom = 1;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case QEMU_OPTION_boot:
|
||||||
boot_device = optarg[0];
|
boot_device = optarg[0];
|
||||||
if (boot_device != 'a' && boot_device != 'b' &&
|
if (boot_device != 'a' && boot_device != 'b' &&
|
||||||
boot_device != 'c' && boot_device != 'd') {
|
boot_device != 'c' && boot_device != 'd') {
|
||||||
|
@ -2108,23 +2192,23 @@ int main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 13:
|
case QEMU_OPTION_fda:
|
||||||
fd_filename[0] = optarg;
|
fd_filename[0] = optarg;
|
||||||
break;
|
break;
|
||||||
case 14:
|
case QEMU_OPTION_fdb:
|
||||||
fd_filename[1] = optarg;
|
fd_filename[1] = optarg;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case QEMU_OPTION_no_code_copy:
|
||||||
code_copy_enabled = 0;
|
code_copy_enabled = 0;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case QEMU_OPTION_nics:
|
||||||
nb_nics = atoi(optarg);
|
nb_nics = atoi(optarg);
|
||||||
if (nb_nics < 0 || nb_nics > MAX_NICS) {
|
if (nb_nics < 0 || nb_nics > MAX_NICS) {
|
||||||
fprintf(stderr, "qemu: invalid number of network interfaces\n");
|
fprintf(stderr, "qemu: invalid number of network interfaces\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 17:
|
case QEMU_OPTION_macaddr:
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
int i;
|
int i;
|
||||||
|
@ -2145,70 +2229,65 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 18:
|
case QEMU_OPTION_user_net:
|
||||||
net_if_type = NET_IF_USER;
|
net_if_type = NET_IF_USER;
|
||||||
break;
|
break;
|
||||||
case 19:
|
case QEMU_OPTION_dummy_net:
|
||||||
net_if_type = NET_IF_DUMMY;
|
net_if_type = NET_IF_DUMMY;
|
||||||
break;
|
break;
|
||||||
case 20:
|
case QEMU_OPTION_enable_audio:
|
||||||
audio_enabled = 1;
|
audio_enabled = 1;
|
||||||
break;
|
break;
|
||||||
}
|
case QEMU_OPTION_h:
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
help();
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
ram_size = atoi(optarg) * 1024 * 1024;
|
|
||||||
if (ram_size <= 0)
|
|
||||||
help();
|
help();
|
||||||
if (ram_size > PHYS_RAM_MAX_SIZE) {
|
break;
|
||||||
fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
|
case QEMU_OPTION_m:
|
||||||
PHYS_RAM_MAX_SIZE / (1024 * 1024));
|
ram_size = atoi(optarg) * 1024 * 1024;
|
||||||
exit(1);
|
if (ram_size <= 0)
|
||||||
}
|
help();
|
||||||
break;
|
if (ram_size > PHYS_RAM_MAX_SIZE) {
|
||||||
case 'd':
|
fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
|
||||||
{
|
PHYS_RAM_MAX_SIZE / (1024 * 1024));
|
||||||
int mask;
|
exit(1);
|
||||||
CPULogItem *item;
|
}
|
||||||
|
break;
|
||||||
mask = cpu_str_to_log_mask(optarg);
|
case QEMU_OPTION_d:
|
||||||
if (!mask) {
|
{
|
||||||
printf("Log items (comma separated):\n");
|
int mask;
|
||||||
|
CPULogItem *item;
|
||||||
|
|
||||||
|
mask = cpu_str_to_log_mask(optarg);
|
||||||
|
if (!mask) {
|
||||||
|
printf("Log items (comma separated):\n");
|
||||||
for(item = cpu_log_items; item->mask != 0; item++) {
|
for(item = cpu_log_items; item->mask != 0; item++) {
|
||||||
printf("%-10s %s\n", item->name, item->help);
|
printf("%-10s %s\n", item->name, item->help);
|
||||||
}
|
}
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
cpu_set_log(mask);
|
||||||
}
|
}
|
||||||
cpu_set_log(mask);
|
break;
|
||||||
}
|
case QEMU_OPTION_n:
|
||||||
break;
|
pstrcpy(network_script, sizeof(network_script), optarg);
|
||||||
case 'n':
|
break;
|
||||||
pstrcpy(network_script, sizeof(network_script), optarg);
|
|
||||||
break;
|
|
||||||
#ifdef CONFIG_GDBSTUB
|
#ifdef CONFIG_GDBSTUB
|
||||||
case 's':
|
case QEMU_OPTION_s:
|
||||||
use_gdbstub = 1;
|
use_gdbstub = 1;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case QEMU_OPTION_p:
|
||||||
gdbstub_port = atoi(optarg);
|
gdbstub_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'L':
|
case QEMU_OPTION_L:
|
||||||
bios_dir = optarg;
|
bios_dir = optarg;
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case QEMU_OPTION_S:
|
||||||
start_emulation = 0;
|
start_emulation = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind < argc) {
|
|
||||||
hd_filename[0] = argv[optind++];
|
|
||||||
}
|
|
||||||
|
|
||||||
linux_boot = (kernel_filename != NULL);
|
linux_boot = (kernel_filename != NULL);
|
||||||
|
|
||||||
if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
|
if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue