On Thu, Oct 25, 2007 at 10:49:25AM +0200, Bernhard Kauer wrote: > It is perhaps not the best idea to read behind the > end of the boot_device string. It would be safer to > declare boot_device as 'static char boot_device[4]' > and use a strncpy. > > > Bernhard >
Thanks for the good catch! (and to others who commented) In this "take" has the following changes: 1. QEMUMachineInitFunc uses const char *boot_device 2. correct spelling of `nibble' 3. avoid touching PPC_NVRAM_set_params() API needlessly 4. allocate boot_device statically 5. define MAX_BOOT_DEVICES clearly according to the TARGET. Only three devices are supoorted by the i386 bios 6. reject the boot string if it includes a single unrecognized letter Dan. diff --git a/hw/an5206.c b/hw/an5206.c index 94ecccb..d9931df 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -27,7 +27,7 @@ void DMA_run (void) /* Board init. */ -static void an5206_init(int ram_size, int vga_ram_size, int boot_device, +static void an5206_init(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mcf5208.c b/hw/mcf5208.c index 993a686..8c4181b 100644 --- a/hw/mcf5208.c +++ b/hw/mcf5208.c @@ -197,7 +197,7 @@ static void mcf5208_sys_init(qemu_irq *pic) } } -static void mcf5208evb_init(int ram_size, int vga_ram_size, int boot_device, +static void mcf5208evb_init(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/palm.c b/hw/palm.c index 623fcd6..3101e9e 100644 --- a/hw/palm.c +++ b/hw/palm.c @@ -61,7 +61,7 @@ static void palmte_microwire_setup(struct omap_mpu_state_s *cpu) { } -static void palmte_init(int ram_size, int vga_ram_size, int boot_device, +static void palmte_init(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/pc.c b/hw/pc.c index a0c824f..3e4e06a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -152,8 +152,25 @@ static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd) rtc_set_memory(s, info_ofs + 8, sectors); } +/* convert boot_device letter to something recognizable by the bios */ +static int boot_device2nibble(char boot_device) +{ + switch(boot_device) { + case 'a': + case 'b': + return 0x01; /* floppy boot */ + case 'c': + return 0x02; /* hard drive boot */ + case 'd': + return 0x03; /* CD-ROM boot */ + case 'n': + return 0x04; /* Network boot */ + } + return 0; +} + /* hd_table must contain 4 block drivers */ -static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table) +static void cmos_init(int ram_size, const char *boot_device, BlockDriverState **hd_table) { RTCState *s = rtc_state; int val; @@ -184,24 +201,12 @@ static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table rtc_set_memory(s, 0x34, val); rtc_set_memory(s, 0x35, val >> 8); - switch(boot_device) { - case 'a': - case 'b': - rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */ - if (!fd_bootchk) - rtc_set_memory(s, 0x38, 0x01); /* disable signature check */ - break; - default: - case 'c': - rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */ - break; - case 'd': - rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */ - break; - case 'n': - rtc_set_memory(s, 0x3d, 0x04); /* Network boot */ - break; - } + /* set boot devices, and disable floppy signature check if requested */ + rtc_set_memory(s, 0x3d, + boot_device2nibble(boot_device[1]) << 4 | + boot_device2nibble(boot_device[0]) ); + rtc_set_memory(s, 0x38, + boot_device2nibble(boot_device[2]) << 4 | (fd_bootchk ? 0x0 : 0x1)); /* floppy type */ @@ -663,7 +668,7 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) } /* PC hardware initialisation */ -static void pc_init1(int ram_size, int vga_ram_size, int boot_device, +static void pc_init1(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, @@ -947,7 +952,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, #endif } -static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device, +static void pc_init_pci(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, @@ -961,7 +966,7 @@ static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device, initrd_filename, 1, cpu_model); } -static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device, +static void pc_init_isa(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c index f53c85b..6fbde7f 100644 --- a/hw/ppc_chrp.c +++ b/hw/ppc_chrp.c @@ -300,7 +300,7 @@ void pmac_format_nvram_partition (uint8_t *buf, int len) } /* PowerPC CHRP hardware initialisation */ -static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, +static void ppc_chrp_init (int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, @@ -322,6 +322,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, const char *arch_name; int vga_bios_size, bios_size; qemu_irq *dummy_irq; + int ppc_boot_device = boot_device[0]; linux_boot = (kernel_filename != NULL); @@ -405,7 +406,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, initrd_base = 0; initrd_size = 0; } - boot_device = 'm'; + ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; @@ -558,7 +559,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; - PPC_NVRAM_set_params(nvram, NVRAM_SIZE, arch_name, ram_size, boot_device, + PPC_NVRAM_set_params(nvram, NVRAM_SIZE, arch_name, ram_size, ppc_boot_device, kernel_base, kernel_size, kernel_cmdline, initrd_base, initrd_size, @@ -571,7 +572,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL); } -static void ppc_core99_init (int ram_size, int vga_ram_size, int boot_device, +static void ppc_core99_init (int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, @@ -585,7 +586,7 @@ static void ppc_core99_init (int ram_size, int vga_ram_size, int boot_device, initrd_filename, cpu_model, 0); } -static void ppc_heathrow_init (int ram_size, int vga_ram_size, int boot_device, +static void ppc_heathrow_init (int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 2c4b242..7a92edf 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -518,7 +518,7 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = { #define NVRAM_SIZE 0x2000 /* PowerPC PREP hardware initialisation */ -static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, +static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, @@ -535,6 +535,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, ppc_def_t *def; PCIBus *pci_bus; qemu_irq *i8259; + int ppc_boot_device = boot_device[0]; sysctrl = qemu_mallocz(sizeof(sysctrl_t)); if (sysctrl == NULL) @@ -600,7 +601,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, initrd_base = 0; initrd_size = 0; } - boot_device = 'm'; + ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; @@ -689,7 +690,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, sysctrl->nvram = nvram; /* Initialise NVRAM */ - PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device, + PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device, kernel_base, kernel_size, kernel_cmdline, initrd_base, initrd_size, diff --git a/hw/realview.c b/hw/realview.c index 375f78a..9582c92 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -12,7 +12,7 @@ /* Board init. */ -static void realview_init(int ram_size, int vga_ram_size, int boot_device, +static void realview_init(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/sun4m.c b/hw/sun4m.c index a12aec9..e5511cd 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -158,7 +158,7 @@ static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, extern int nographic; static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, - int boot_device, uint32_t RAM_size, + const char *boot_device, uint32_t RAM_size, uint32_t kernel_size, int width, int height, int depth, int machine_id) @@ -175,7 +175,7 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, m48t59_write(nvram, 0x2E, 0); m48t59_write(nvram, 0x2F, nographic & 0xff); nvram_set_lword(nvram, 0x30, RAM_size); - m48t59_write(nvram, 0x34, boot_device & 0xff); + m48t59_write(nvram, 0x34, boot_device[0] & 0xff); nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR); nvram_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { @@ -408,7 +408,7 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, return nvram; } -static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device, +static void sun4m_load_kernel(long vram_size, int RAM_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, @@ -548,7 +548,7 @@ static const struct hwdef hwdefs[] = { }, }; -static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds, +static void sun4m_common_init(int RAM_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, unsigned int machine, int max_ram) @@ -569,7 +569,7 @@ static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds, } /* SPARCstation 5 hardware initialisation */ -static void ss5_init(int RAM_size, int vga_ram_size, int boot_device, +static void ss5_init(int RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -582,7 +582,7 @@ static void ss5_init(int RAM_size, int vga_ram_size, int boot_device, } /* SPARCstation 10 hardware initialisation */ -static void ss10_init(int RAM_size, int vga_ram_size, int boot_device, +static void ss10_init(int RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/sun4u.c b/hw/sun4u.c index bac0ebf..317ba74 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -331,7 +331,7 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; static fdctrl_t *floppy_controller; /* Sun4u hardware initialisation */ -static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, +static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -456,7 +456,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, i8042_init(NULL/*1*/, NULL/*12*/, 0x60); floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table); nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); - sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device, + sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device[0], KERNEL_LOAD_ADDR, kernel_size, kernel_cmdline, INITRD_LOAD_ADDR, initrd_size, diff --git a/vl.c b/vl.c index 6d8fe35..9a34490 100644 --- a/vl.c +++ b/vl.c @@ -161,7 +161,12 @@ static DisplayState display_state; int nographic; const char* keyboard_layout = NULL; int64_t ticks_per_sec; -int boot_device = 'c'; +#if defined(TARGET_I386) +#define MAX_BOOT_DEVICES 3 +#else +#define MAX_BOOT_DEVICES 1 +#endif +static char boot_device[MAX_BOOT_DEVICES + 1]; int ram_size; int pit_min_timer_count = 0; int nb_nics; @@ -7788,14 +7793,18 @@ int main(int argc, char **argv) } break; case QEMU_OPTION_boot: - boot_device = optarg[0]; - if (boot_device != 'a' && + if (strlen(optarg) > MAX_BOOT_DEVICES) { + fprintf(stderr, "qemu: too many boot devices\n"); + exit(1); + } + strncpy(boot_device, optarg, MAX_BOOT_DEVICES); #if defined(TARGET_SPARC) || defined(TARGET_I386) - // Network boot - boot_device != 'n' && +#define BOOTCHARS "acdn" +#else +#define BOOTCHARS "acd" #endif - boot_device != 'c' && boot_device != 'd') { - fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device); + if (strlen(boot_device) != strspn(boot_device, BOOTCHARS)) { + fprintf(stderr, "qemu: invalid boot device sequence '%s'\n", boot_device); exit(1); } break; @@ -8146,20 +8155,22 @@ int main(int argc, char **argv) linux_boot = (kernel_filename != NULL); if (!linux_boot && - boot_device != 'n' && + (!strchr(boot_device, 'n')) && hd_filename[0] == '\0' && (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') && fd_filename[0] == '\0') help(1); /* boot to floppy or the default cd if no hard disk defined yet */ - if (hd_filename[0] == '\0' && boot_device == 'c') { - if (fd_filename[0] != '\0') - boot_device = 'a'; + if (!boot_device[0]) { + if (hd_filename[0] != '\0') + boot_device[0] = 'c'; + else if (fd_filename[0] != '\0') + boot_device[0] = 'a'; else - boot_device = 'd'; + boot_device[0] = 'd'; + boot_device[1] = 0; } - setvbuf(stdout, NULL, _IOLBF, 0); init_timers(); @@ -8198,7 +8209,7 @@ int main(int argc, char **argv) } #ifdef TARGET_I386 - if (boot_device == 'n') { + if (strchr(boot_device, 'n')) { for (i = 0; i < nb_nics; i++) { const char *model = nd_table[i].model; char buf[1024]; diff --git a/vl.h b/vl.h index adf6004..390d221 100644 --- a/vl.h +++ b/vl.h @@ -725,7 +725,7 @@ void path_combine(char *dest, int dest_size, #ifndef QEMU_TOOL typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size, - int boot_device, + const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model);