T=etherboot-$(EB_VERSION).tar.gz
E=etherboot-build
-TARGETS=eb-rtl8139.zrom.h
+NICS = rtl8139 eepro100
-all: $(TARGETS)
+ROM_ZHS = $(addprefix eb-, $(addsuffix .zrom.h, $(NICS)))
+
+all: eb-roms.h
eb-%.zrom.h: $E/src/Config
$(MAKE) -C $E/src bin/$*.zrom
- ../hvmloader/mkhex etherboot <$E/src/bin/$*.zrom >$@.new
+ ../hvmloader/mkhex etherboot_$* <$E/src/bin/$*.zrom >$@.new
mv -f $@.new $@
-$E/src/Config: $T Config
+eb-rom-list.h: make-eb-rom-list $E/src/bin/Roms
+ ./$^ $(NICS) >$@.new && mv -f $@.new $@
+
+eb-roms.h: eb-rom-list.h $(ROM_ZHS)
+ cat $^ >$@.new && mv -f $@.new $@
+
+$E/src/Config: $T Config
rm -rf $D $E
tar zxf $T
cat Config >>$D/src/Config
mv Config.new Config
mv $D $E
+$E/src/bin/Roms: $E/src/Config
+ $(MAKE) -C $E/src bin/Roms
+
clean:
- rm -rf $D $E *.zrom.h *~
+ rm -rf $D $E *.zrom.h eb-rom-list.h eb-roms.h *~
.PHONY: all clean
}
}
+static int must_load_extboot(void)
+{
+ return (inb(0x404) == 1);
+}
+
/*
- * If the network card is in the boot order, load the Etherboot option ROM.
- * Read the boot order bytes from CMOS and check if any of them are 0x4.
+ * Scan the PCI bus for the first NIC supported by etherboot, and copy
+ * the corresponding rom data to *copy_rom_dest. Returns the length of the
+ * selected rom, or 0 if no NIC found.
*/
-static int must_load_nic(void)
+static int scan_etherboot_nic(void *copy_rom_dest)
{
- uint8_t boot_order;
+ static struct etherboots_table_entry {
+ char *name;
+ void *etherboot_rom;
+ int etherboot_sz;
+ uint16_t vendor, device;
+ } etherboots_table[] = {
+#define ETHERBOOT_ROM(name, vendor, device) \
+ { #name, etherboot_##name, sizeof(etherboot_##name), vendor, device },
+ ETHERBOOT_ROM_LIST
+ { 0 }
+ };
+
+ uint32_t devfn;
+ uint16_t class, vendor_id, device_id;
+ struct etherboots_table_entry *eb;
- /* Read CMOS register 0x3d (boot choices 0 and 1). */
- boot_order = cmos_inb(0x3d);
- if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) )
- return 1;
+ for ( devfn = 0; devfn < 128; devfn++ )
+ {
+ class = pci_readw(devfn, PCI_CLASS_DEVICE);
+ vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
+ device_id = pci_readw(devfn, PCI_DEVICE_ID);
- /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */
- boot_order = cmos_inb(0x38);
- return ((boot_order & 0xf0) == 0x40);
-}
+ if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
+ continue;
-static int must_load_extboot(void)
-{
- return (inb(0x404) == 1);
+ if ( class != 0x0200 ) /* Not a NIC */
+ continue;
+
+ for ( eb = etherboots_table; eb->name; eb++ )
+ if (eb->vendor == vendor_id &&
+ eb->device == device_id)
+ goto found;
+ }
+
+ return 0;
+
+ found:
+ printf("Loading %s Etherboot PXE ROM ...\n", eb->name);
+ memcpy(copy_rom_dest, eb->etherboot_rom, eb->etherboot_sz);
+ return eb->etherboot_sz;
}
/* Replace possibly erroneous memory-size CMOS fields with correct values. */
vgabios_sz = sizeof(vgabios_stdvga);
}
- if ( must_load_nic() )
- {
- printf("Loading ETHERBOOT ...\n");
- memcpy((void *)ETHERBOOT_PHYSICAL_ADDRESS,
- etherboot, sizeof(etherboot));
- etherboot_sz = sizeof(etherboot);
- }
+ etherboot_sz = scan_etherboot_nic((void*)ETHERBOOT_PHYSICAL_ADDRESS);
if ( must_load_extboot() )
{