Netboot Mailing List (by thread)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FIXED: Intel CA810E mobo doesn't see Etherboot Option ROM




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.