Summary: There is a problem with the PCI and PNP headers in Etherboot ROMs which causes them not to be recognized by certain modern PNP and "Legacy Free" BIOSes. In my case the motherboard was a current offering by Intel, model CA810EA. It is likely that this issue may affect other motherboards as well, depending on their BIOS revision. This motherboard has 4 PCI slots, onboard video and sound, and is a Micro-ATX form factor. The behavior observed was that the ROM would be recognized by the Setup screen of the BIOS as a potential BOOT device, but the ROM code would not execute when selected as a boot device. I have created a patch for the "loader.S" file in Etherboot which fixes this problem. I have tested this patch by burning ROMs and Etherbooting with an MX98715-based board on 4 different motherboards, some with legacy slots, some without, and with various BIOSes. The patch is available at: http://www.thinguin.org/ With the patch installed, it is possible to use the BIOS setup screen to select, prioritize, or disable numerous boot (IPL) devices, and have them checked in any order. In my case, I first check for a floppy, then for "Etherboot ROM". It is also possible to install two Ethernet cards and select which one to Etherboot from, if they are both capable. Please note that the bug also exists in Netboot version 0.9.0e, and should probably be fixed there as well. Regards, Marty P.S. For those who would like to know how I figured this out, below is a description of the debugging process. I mainly do this for the curious and with the hope that others who have to debug such things can benefit from time I spent gathering information and analyzing the problem. The Tale: Like so many interesting adventures, it started off innocently enough... In preparation for LinuxWorld Expo in New York, I purchased an Intel CA810EA, which is a modern Micro-ATX form factor motherboard. I liked it because it had integrated AGP video, sound, and used PC100 RAM. It would display well because the only PCI device would be an Ethernet card. it also will fit in my suitcase along with a flat screen, so transportation would be easier. I built a machine with the CA810EA motherboard, using a Celeron 566Mhz CPU with a large heat-sink so no CPU fan is needed. The power supply for the case is virtually silent, because as we all know "Thin clients should be seen and not heard". I Etherbooted various PCI cards via floppy, and all looked very good. I was just about to attach plexiglass sides to the case so people at the show could see there was nothing inside except a NIC card with an Etherboot ROM on it. I then burned a ROM for an MX98715-based tulip clone card, and tried to Etherboot with it. It didn't work. It was recognized by the BIOS setup screen, but failed to execute. I tried various BIOS settings, but to no avail. To determine if this was a problem with the boot ROM, I tested the motherboard with an Intel PRO/100+ card and a 3Com 3C905C-TX-M card, both of which have integrated flash memory containing PXE network booting code. Both commercial cards were recognized by the BIOS, and attempted to network boot. Because the MX98715 board's ROM was at least selectable by the BIOS, I suspected that it was at seeing a ROM on the card, but for some reason didn't think it was correct for network booting. Time to take a look inside Using the contrib/3c90xutil/cromutil utility program from the Etherboot package I dumped the Flash memory contents of the working 3Com 3C905C-TX-M board to a file. Using the techniques described in the Etherboot contrib/3c90xutil/eepro100notes file, I dumped the flash memory contents of the pro/100+ adapter as well. I already had the mx98715.lzrom code for Etherboot, of course. Here is a hex dump of the first part of each of those ROM images: -:---F1 mx987x5.lzrom (Hexl)--L3--Top--------------------------- 00000000: 55aa 20eb 4f31 e98c 0045 7468 6572 626f U. .O1...Etherbo 00000010: 6f74 0000 0000 0000 1c00 3400 5043 4952 ot........4.PCIR 00000020: d910 3105 0000 1800 0000 0002 2000 0100 ..1......... ... 00000030: 0080 0000 2450 6e50 0102 0000 0061 0000 ....$PnP.....a.. 00000040: 0000 0000 0000 0000 0214 0000 0000 5400 ..............T. 00000050: 0000 0000 501e 31c0 8ed8 a104 033d 4ce4 ....P.1......=L. -:---F1 3c905c.img (Hexl)--L7--Top----------------------------- 00000000: 55aa 08e9 af07 554c 4452 0000 0003 0000 U.....ULDR...... 00000010: 0000 d006 4005 7000 5800 3800 6d00 0004 ....@.p.X.8.m... 00000020: cc00 0010 0427 10d4 3005 0000 0000 0000 .....'..0....... 00000030: 0000 0000 0000 0000 2450 6e50 0102 0000 ........$PnP.... 00000040: 00e2 0000 0000 c300 c800 0200 0014 0000 ................ 00000050: 0000 4503 0000 0000 5043 4952 b710 0092 ..E.....PCIR.... 00000060: 0000 1800 0002 0000 6d00 0000 0080 0000 ........m....... -:---F1 pro100+.img (Hexl)--L7--Top----------------------------- 00000000: 55aa 14e8 3f23 cbc4 d502 0000 0000 0000 U...?#.......... 00000010: 0000 0000 0000 2000 4000 6000 5503 2001 ...... .@.`.U. . 00000020: 554e 4449 1605 0000 0102 130e 0008 604b UNDI..........`K 00000030: 9020 5043 4952 2e8b c02e 8bc0 2e8b c090 . PCIR.......... 00000040: 5043 4952 8680 2912 0000 1800 0002 0000 PCIR..)......... 00000050: 1400 0102 0080 0000 2e8b c02e 8bc0 8bc0 ................ 00000060: 2450 6e50 0102 0000 0020 0000 0000 9b00 $PnP..... ...... 00000070: bc00 0200 00e4 0000 0000 610d 0000 0000 ..........a..... Decoding the ROMs Using the specifications for Option ROM Headers described in the document: http://www.phoenix.com/products/specs-bbs101.pdf I decoded three headers from each ROM, and created a table to compare the Etherboot ROM to the 3Com and Intel ROMs. I then studied the specifications to see whether the ROM contents made sense for each field. Here is a table showing the decoded headers: A.2 PnP Option ROM Header Etherboot 3Com Intel Offset Size before fix 3C905C PRO/100+ Description 00h B 55h 55h 55h Signature byte 1. 01h B AAh AAh AAh Signature byte 2. 02h B 20h 08h 14h Option ROM len 512byte blks. 03h B*4 eb4f31e9h e9af0755h e83f23cbh Initialization entry point. 07h B*17 Reserved. 18h W 1c00h 5800h 4000h Offset to PCI data struct. 1Ah W 3400h 3800h 6000h Offset to expansion hdr. A.3 PnP Expansion Header Etherboot 3Com Intel Offset Size before fix 3C905C PRO/100+ Description 00h B '$' '$' '$' Signature byte 1. 01h B 'P' 'P' 'P' Signature byte 2. 02h B 'n' 'n' 'n' Signature byte 3. 03h B 'P' 'P' 'P' Signature byte 4. 04h B 01h 01h 01h Structure revision. 05h B 02h 02h 02h Length (16 byte increments). 06h W 0000h 0000h 0000h Offset of next hdr 08h B 00h 00h 00h Reserved. 09h B 61h e2h 20h Checksum. 0Ah DW 00000000h 00000000h 00000000h Device identifier. 0Eh W 0000h c300h 9b00h Ptr to mfgr str. (opt) 10h W 0000h c800h bc00h Ptr to prod name str (Opt) 12h B*3 000002h 020000h 020000h Device type code. 15h B 14h 14h e4h Device indicators. 16h W 0000h 0000h 0000h Boot Connection Vector (BCV) 18h W 0000h 0000h 0000h Disconnect Vector (DV) 1Ah W 5400h 4503h 610dh Bootstrap Entry Vector (BEV) 1Ch W 0000h 0000h 0000h Reserved. 1Eh W 0000h 0000h 0000h Static res info vector A.4 PCI Data Structure Etherboot 3Com Intel Offset Size before fix 3C905C PRO/100+ Description 00h B 'P' 'P' 'P' Signature byte 1. 01h B 'C' 'C' 'C' Signature byte 2. 02h B 'I' 'I' 'I' Signature byte 3. 03h B 'R' 'R' 'R' Signature byte 4. 04h W d910h b710h 8680h Vendor Identification. 06h W 3105h 0092h 2912h Device Identification. 08h W 0000h 0000h 0000h Ptr to Vital Product Data. 0Ah W 1800h 1800h 1800h PCI Data Structure Length. 0Ch B 00h 00h 00h PCI Data Structure Revision. 0Dh B*3 000002h 020000h 020000h Class Code. 10h W 2000h 6d00h 1400h Image Length. 12h W 0100h 0000h 0102h Revision Level of Code/Data. 14h B 00h 00h 00h Code Type. 15h B 80h 80h 80h Indicator. 16h W 0000h 0000h 0000h Reserved. Eureka! Note specifically the values at offet 12h of the PnP Expansion Header and offset 0Dh of the PCI Data Structure. It appears that they are in reverse order in the Etherboot ROM. Referring the the Device ID specification available at: http://www.microsoft.com/hwdev/download/respec/devids.txt we note that the 3 bytes of the Device code should be: Base Type = 2: Network Interface Controller Sub-Type = 0: Ethernet Interface Type = 0: General Ethernet which they are, in the Intel and 3Com ROM images. It seems they are simply reversed in the Etherboot ROM. referring to the relevant portion of src/loader.S in Etherboot, we see: PCI: STRDECL('PCIR') ; signature dw 0x8086 ; vendor ID, filled in by makerom dw 0x1229 ; device ID, filled in by makerom dw 0x0000 ; pointer to vital product data dw 0x0018 ; PCI data structure length db 0 ; PCI data structure revision db 0 ; Class code byte 1 db 0 ; Class code byte 2 db 0x02 ; Class code byte 3 (from hexdumping ; Intel bootrom image) dw 0x0000 ; Image length same as offset 02h dw 0x0001 ; revision level of code /data db 0 ; code type db 0x80 ; indicator (from hexdumping ; Intel bootrom image) dw 0x0000 ; reserved and PnP: STRDECL('$PnP') ; signature db 0x01 ; structure revision db 0x02 ; length (in 16 byte increments) dw 0x0000 ; offset of next header db 0 ; Reserved db 0 ; checksum filled by makerom dd 0x00000000 ; Device identifier dw 0x0000 ; pointer to manufacturer str dw 0x0000 ; pointer to product name db 0 ; device type code byte 1 db 0 ; device type code byte 2 db 2 ; device type code byte 3 (from ; hexdumping Intel bootrom image) db 0x14 ; device indictors (from ; hexdumping Intel bootrom image) dw 0x0000 ; boot connection vector dw 0x0000 ; disconnect vector dw start19h ; bootstrap entry vector dw 0x0000 ; reserved dw 0x0000 ; static resource information vector note the order of the "class code" and "device type code" bytes. It is reversed from the order specified in the PnP specification. >From the file netboot-0.9.0e/bootrom/loader/rom.S file we see: ! Define the PCI data structure to make the netboot bootrom compatible ! with the PCI local bus specification 2.1. This header is actually only ! needed when the bootrom is physically located on the PCI network card. ! Note that the order of the class codes has to be reversed compared to ! what the spec says. pcihdr: .ascii "PCIR" ! signature for PCI data structure .word 0 ! vendor ID (filled in later) .word 0 ! device ID (filled in later) .word 0 ! ptr to vital product data (unused) .word $0018 ! length of PCI data structure .byte $00 ! structure revision 0.0 .byte PCI_IFTYPE ! device programming interface .byte PCI_SUBTYPE ! device subtype code .byte PCI_BASETYPE ! base device type code .word 0 ! rom image length (filled in later) .word PCI_REVISION ! version number of code/data .byte 0 ! code type .byte PCI_DEVIND ! device indicator .word 0 ! reserved ! Define the expansion header to make the netboot bootrom Plug and Play ! compatible according to the Plug and Play BIOS Specification 1.0A. This ! will allow the system BIOS to select wether to boot from the network or ! not, and we dont have to redirect interrupt 18h or 19h by ourselves. ! Note that the order of the class codes has to be reversed compared to ! what the spec says. pnphdr: .ascii "$PnP" ! signature for PnP expansion header .byte $01 ! structure revision 0.1 .byte 2 ! length of header in 16-byte-blocks .word 0 ! pointer to next header (0 = none) .byte 0 ! reserved .byte 0 ! checksum (filled in later) .word PNP_VENDID ! compressed manufacturer code .word PNP_DEVID ! product number and revision, device ID .word 0 ! ptr to manufacturer string (unused) .word prdnam ! ptr to product name .byte PNP_IFTYPE ! device programming interface .byte PNP_SUBTYPE ! device subtype code .byte PNP_BASETYPE ! base device type code .byte PNP_DEVIND ! device indicators .word 0 ! boot connection vector (unused) .word 0 ! disconnect vector (unused) .word dorom ! bootstrap entry vector .word 0 ! reserved .word 0 ! static resource info vector (unused) Note that the author specifically reversed the order of the PCI and PNP class codes. I suspect there must have been a BIOS implementation bug that caused cards following the specification not to work at the time, because the 1.0A specification states: "Device Type Code - This field contains general device type information that will assist the System BIOS in prioritizing the boot devices. The Device Type code is broken down into three byte fields. The byte fields consist of a Base-Type code that indicates the general device type. The second byte is the device Sub-Type and its definition is dependent upon the Base-Type code. The third byte defines the specific device programming interface, IF.-Type, based on the Base-Type and Sub-Type." We have liftoff WIth this information and analysis I reversed the codes in the Etherboot ROM code, burned a ROM, and it was properly recognized by the BIOS. I also added preliminary manufacturer and product strings to the header to allow the string "Etherboot ROM" to appear in the BIOS setup menu for boot device. Without this, it says "Option ROM" which is less descriptive. With a little more work, we could embed the actual ROM type as well at compile time so it would say "Etherboot 4.6.12 MX987x5.lzrom" or something more descriptive. According to the spec, the first 32 bytes are significant, though no length limit for the string is specified. I burned a second ROM (an LC82C115.lzrom) to test a second card type, and it also functioned. The third ROM was an RTL8139.lzrom. This one was not recognized initially by the BIOS. I booted to DOS and ran a utility to enable the ROM socket and specify the size of the ROM. Still no joy. I noted that in this 3rd case, the ROM was not even being seen by the BIOS setup screen. This suggested that there might be something physically wrong with the ROM. Though it was the same speed as the other ROMs it appears that the RTL8139 card was not inserting enough wait states to mediate between the bus speed (66MHZ) and the ROM speed. I burned a faster ROM (150ns vs. 250ns) and the ROM was recognized and booted properly. I then took the three cards and Etherbooted them on four different CPUs with various BIOS and legacy configurations. They seemed to function properly. Cut to the present So, that's where we are now. I can now continue to prepare for LinuxWorld Expo, and show a modern motherboard with various modern PCI cards Etherbooting from a Linux box and running X. Hopefully my experience will help others who are debugging such problems. Network booting is a very useful technology, and I am pleased to be able to contribute to making it more widespread and accessible. Marty --- Try: http://rom-o-matic.net/ to make Etherboot images instantly. Name: Martin D. Connor US Mail: Entity Cyber, Inc.; P.O. Box 391827; Cambridge, MA 02139; USA Voice: (617) 491-6935, Fax: (617) 491-7046 Email: mdc@thinguin.org Web: http://www.thinguin.org/ =========================================================================== This Mail was sent to netboot mailing list by: Marty Connor <mdc@thinguin.org> To get help about this list, send a mail with 'help' as the only string in it's body to majordomo@baghira.han.de. If you have problems with this list, send a mail to netboot-owner@baghira.han.de.
For requests or suggestions regarding this mailing list archive please write to netboot@gkminix.han.de.