aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/pc.c19
-rw-r--r--net.c20
-rw-r--r--net.h2
-rw-r--r--vl.c39
4 files changed, 43 insertions, 37 deletions
diff --git a/hw/pc.c b/hw/pc.c
index 143b697c70..3521d29ae5 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -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 */
diff --git a/net.c b/net.c
index af9de7334d..c83999b03a 100644
--- a/net.c
+++ b/net.c
@@ -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;
diff --git a/net.h b/net.h
index 89e7706be4..a9abf63695 100644
--- a/net.h
+++ b/net.h
@@ -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);
diff --git a/vl.c b/vl.c
index 3242c230ea..2d9f04e4c2 100644
--- a/vl.c
+++ b/vl.c
@@ -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++)