diff options
-rw-r--r-- | hw/pc.c | 19 | ||||
-rw-r--r-- | net.c | 20 | ||||
-rw-r--r-- | net.h | 2 | ||||
-rw-r--r-- | vl.c | 39 |
4 files changed, 43 insertions, 37 deletions
@@ -977,8 +977,23 @@ static void pc_init1(ram_addr_t ram_size, } for (i = 0; i < nb_option_roms; i++) { - oprom_area_size += load_option_rom(option_rom[i], - 0xc0000 + oprom_area_size, 0xe0000); + oprom_area_size += load_option_rom(option_rom[i], 0xc0000 + oprom_area_size, + 0xe0000); + } + + for (i = 0; i < nb_nics; i++) { + char nic_oprom[1024]; + const char *model = nd_table[i].model; + + if (!nd_table[i].bootable) + continue; + + if (model == NULL) + model = "ne2k_pci"; + snprintf(nic_oprom, sizeof(nic_oprom), "pxe-%s.bin", model); + + oprom_area_size += load_option_rom(nic_oprom, 0xc0000 + oprom_area_size, + 0xe0000); } /* map all the bios at the top of memory */ @@ -2457,6 +2457,26 @@ int net_client_parse(const char *str) return net_client_init(NULL, device, p); } +void net_set_boot_mask(int net_boot_mask) +{ + int i; + + /* Only the first four NICs may be bootable */ + net_boot_mask = net_boot_mask & 0xF; + + for (i = 0; i < nb_nics; i++) { + if (net_boot_mask & (1 << i)) { + nd_table[i].bootable = 1; + net_boot_mask &= ~(1 << i); + } + } + + if (net_boot_mask) { + fprintf(stderr, "Cannot boot from non-existent NIC\n"); + exit(1); + } +} + void do_info_network(Monitor *mon) { VLANState *vlan; @@ -91,6 +91,7 @@ struct NICInfo { VLANState *vlan; void *private; int used; + int bootable; }; extern int nb_nics; @@ -126,6 +127,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 void net_cleanup(void); int slirp_is_inited(void); void net_client_check(void); +void net_set_boot_mask(int boot_mask); void net_host_device_add(Monitor *mon, const char *device, const char *opts); void net_host_device_remove(Monitor *mon, int vlan_id, const char *device); @@ -5801,7 +5801,6 @@ int main(int argc, char **argv, char **envp) exit(1); } linux_boot = (kernel_filename != NULL); - net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF; if (!linux_boot && *kernel_cmdline != '\0') { fprintf(stderr, "-append only allowed with -kernel option\n"); @@ -5849,41 +5848,11 @@ int main(int argc, char **argv, char **envp) if (net_client_parse(net_clients[i]) < 0) exit(1); } - net_client_check(); -#ifdef TARGET_I386 - /* XXX: this should be moved in the PC machine instantiation code */ - if (net_boot != 0) { - int netroms = 0; - for (i = 0; i < nb_nics && i < 4; i++) { - const char *model = nd_table[i].model; - char buf[1024]; - char *filename; - if (net_boot & (1 << i)) { - if (model == NULL) - model = "ne2k_pci"; - snprintf(buf, sizeof(buf), "pxe-%s.bin", model); - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf); - if (filename && get_image_size(filename) > 0) { - if (nb_option_roms >= MAX_OPTION_ROMS) { - fprintf(stderr, "Too many option ROMs\n"); - exit(1); - } - option_rom[nb_option_roms] = qemu_strdup(buf); - nb_option_roms++; - netroms++; - } - if (filename) { - qemu_free(filename); - } - } - } - if (netroms == 0) { - fprintf(stderr, "No valid PXE rom found for network device\n"); - exit(1); - } - } -#endif + net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF; + net_set_boot_mask(net_boot); + + net_client_check(); /* init the bluetooth world */ for (i = 0; i < nb_bt_opts; i++) |