Real PCs try to boot from a CD, then try the hard drive, and finally go to the network. And they let their owner change that order. This patch lets Qemu do the same with "-boot dcn".
I'll be happy to hear comments about it, Dan. diff --git a/hw/an5206.c b/hw/an5206.c index 94ecccb..2134184 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, 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..19689ba 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, 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..971ff37 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, 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..3c552ff 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_device2nible(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, 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_device2nible(boot_device[1]) << 4 | + boot_device2nible(boot_device[0]) ); + rtc_set_memory(s, 0x38, + boot_device2nible(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, 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, 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, char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, diff --git a/hw/ppc.c b/hw/ppc.c index 742d3de..d1bc943 100644 --- a/hw/ppc.c +++ b/hw/ppc.c @@ -1347,7 +1347,7 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count) int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, const unsigned char *arch, - uint32_t RAM_size, int boot_device, + uint32_t RAM_size, char *boot_device, uint32_t kernel_image, uint32_t kernel_size, const char *cmdline, uint32_t initrd_image, uint32_t initrd_size, @@ -1362,7 +1362,7 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, NVRAM_set_word(nvram, 0x14, NVRAM_size); NVRAM_set_string(nvram, 0x20, arch, 16); NVRAM_set_lword(nvram, 0x30, RAM_size); - NVRAM_set_byte(nvram, 0x34, boot_device); + NVRAM_set_byte(nvram, 0x34, boot_device[0]); NVRAM_set_lword(nvram, 0x38, kernel_image); NVRAM_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c index f53c85b..64c0fd1 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, char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, @@ -405,7 +405,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'; + boot_device[0] = 'm'; } else { kernel_base = 0; kernel_size = 0; @@ -571,7 +571,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, char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, @@ -585,7 +585,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, 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..96bfde5 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, char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, @@ -600,7 +600,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'; + boot_device[0] = 'm'; } else { kernel_base = 0; kernel_size = 0; diff --git a/hw/realview.c b/hw/realview.c index 375f78a..3acc96f 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, 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..7481eef 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, + 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, 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, 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, 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, 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..2c1b598 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -203,7 +203,7 @@ extern int nographic; int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, const unsigned char *arch, - uint32_t RAM_size, int boot_device, + uint32_t RAM_size, char *boot_device, uint32_t kernel_image, uint32_t kernel_size, const char *cmdline, uint32_t initrd_image, uint32_t initrd_size, @@ -221,7 +221,7 @@ int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, NVRAM_set_string(nvram, 0x20, arch, 16); NVRAM_set_byte(nvram, 0x2f, nographic & 0xff); NVRAM_set_lword(nvram, 0x30, RAM_size); - NVRAM_set_byte(nvram, 0x34, boot_device); + NVRAM_set_byte(nvram, 0x34, boot_device[0]); NVRAM_set_lword(nvram, 0x38, kernel_image); NVRAM_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { @@ -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, 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/vl.c b/vl.c index 6d8fe35..be0e06a 100644 --- a/vl.c +++ b/vl.c @@ -161,7 +161,7 @@ static DisplayState display_state; int nographic; const char* keyboard_layout = NULL; int64_t ticks_per_sec; -int boot_device = 'c'; +static char *boot_device; int ram_size; int pit_min_timer_count = 0; int nb_nics; @@ -7788,14 +7788,19 @@ int main(int argc, char **argv) } break; case QEMU_OPTION_boot: - boot_device = optarg[0]; - if (boot_device != 'a' && + if (strlen(optarg) > 3) { + fprintf(stderr, "qemu: too many boot devices\n"); + exit(1); + } + boot_device = strdup(optarg); + if (!strchr(boot_device, 'a') && #if defined(TARGET_SPARC) || defined(TARGET_I386) // Network boot - boot_device != 'n' && + !strchr(boot_device, 'n') && #endif - boot_device != 'c' && boot_device != 'd') { - fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device); + !strchr(boot_device, 'c') && + !strchr(boot_device, 'd')) { + fprintf(stderr, "qemu: invalid boot device sequence '%s'\n", boot_device); exit(1); } break; @@ -8146,20 +8151,21 @@ int main(int argc, char **argv) linux_boot = (kernel_filename != NULL); if (!linux_boot && - boot_device != 'n' && + (!boot_device || !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) { + if (hd_filename[0] != '\0') + boot_device = "c"; + else if (fd_filename[0] != '\0') + boot_device = "a"; else - boot_device = 'd'; + boot_device = "d"; } - setvbuf(stdout, NULL, _IOLBF, 0); init_timers(); @@ -8198,7 +8204,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..4751f2f 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, + 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); @@ -1339,7 +1339,7 @@ void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr, uint32_t start, uint32_t count); int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, const unsigned char *arch, - uint32_t RAM_size, int boot_device, + uint32_t RAM_size, char *boot_device, uint32_t kernel_image, uint32_t kernel_size, const char *cmdline, uint32_t initrd_image, uint32_t initrd_size,