I forward this message to netboot, since the master code is in Etherboot. Please tell us how you feel...
- To: OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
- Subject: [PATCH] Kludge for Intel's PXE scan order
- From: Chip Salzenberg <chip@valinux.com>
- Date: Thu, 8 Jun 2000 19:14:09 -0700
- Cc: bug-grub@gnu.org
- Content-Disposition: inline
- Content-Type: text/plain; charset=us-ascii
- Resent-Date: Thu, 8 Jun 2000 22:42:36 -0400
- Resent-From: bug-grub@gnu.org
- Resent-Message-ID: <"PpVlO1.0.3o6.rL5Gv"@mescaline.gnu.org>
- Resent-Sender: bug-grub-request@gnu.org
- User-Agent: Mutt/1.2i
(Warning: This patch is ugly. But the issue it addresses is important.) Many of the systems with which we will be using GRUB have multiple Ethernet adapters. As it happens, all of them are Intel EEPro100s with Intel's PXE BIOS for netbooting. Unfortunately, PXE insists on always preferring the LOM (LAN On Motherboard), if any; it is unable/unwilling to detect which adapter is actually connected. Even worse, Intel's LOMs almost always show up *last* in a PCI scan, so GRUB never uses it. The upshot of this is that, on a multi-adapter system, PXE insists on loading from the motherboard port, while GRUB insists on using the non-motherboard port. So you can't netboot without two cables. The below patch is the workaround I will use unless/until a better solution is found. It makes a special case of Intel adapters and diskless booting; in that case, it effectively reverses the scan. A much better solution, IMO, would be to give GRUB the ability to send DHCP requests out on *all* adapters *simultaneously*. The Linux kernel does this for its boot-time DHCP support, and it's a wonderful way to prevent headaches for users. PS: The variable "pci_ioaddr" in pci.c seemed unused, so I removed it. 2000-06-08 Chip Salzenberg <chip@valinux.com> Adjust scan order for Intel adapters under diskless boot. * netboot/pci.h (eth_pci_prefer_last): Declare new variable. * netboot/pci.c (eth_pci_prefer_last): Define it, default -1. (scan_bus): Compare it to each adapter's vendor; if it matches, then keep scanning, so the last one found will be used. Also tweak debugging messages. (pci_ioaddr): Eliminate unused variable. * stage2/common.c (setup_diskless_environment): Set eth_pci_prefer_last to PCI_VENDOR_ID_INTEL. Index: netboot/pci.h diff -u -2 -r1.6 pci.h --- netboot/pci.h 2000/05/17 13:55:18 1.6 +++ netboot/pci.h 2000/06/09 01:55:48 @@ -146,4 +146,6 @@ }; +extern unsigned short eth_pci_prefer_last; + extern void eth_pci_init(struct pci_device *); Index: netboot/pci.c diff -u -2 -r1.5 pci.c --- netboot/pci.c 2000/05/31 02:15:13 1.5 +++ netboot/pci.c 2000/06/09 01:55:48 @@ -23,6 +23,7 @@ /*#define DEBUG 1*/ -static unsigned int pci_ioaddr = 0; +unsigned short eth_pci_prefer_last = 0xFFFF; /* no such vendor */ + #ifdef CONFIG_PCI_DIRECT #define PCIBIOS_SUCCESSFUL 0x00 @@ -406,5 +407,4 @@ int i, reg; - pci_ioaddr = 0; buses=1; for (bus = 0; bus < buses; ++bus) { @@ -430,5 +430,5 @@ #if DEBUG - printf("bus %x, function %x, vendor %x, device %x\n", + printf("bus %x, func %x: vendor %x, device %x\n", bus, devfn, vendor, device); #endif @@ -437,4 +437,8 @@ || device != pcidev[i].dev_id) continue; +#if DEBUG + printf("bus %x, func %x: '%s'\n", + bus, devfn, pcidev[i].name); +#endif for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) { pcibios_read_config_dword(bus, devfn, reg, &ioaddr); @@ -453,13 +457,18 @@ pcidev[i].name, ioaddr, romaddr); /* Take the first one or the one that matches in boot ROM address */ - if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) { - pcidev[i].membase = membase; - pcidev[i].ioaddr = ioaddr; - pcidev[i].devfn = devfn; + pcidev[i].membase = membase; + pcidev[i].ioaddr = ioaddr; + pcidev[i].devfn = devfn; + + /* Should we prefer the last eth? */ + if (vendor == eth_pci_prefer_last) + goto next_devfn; - return; - } + /* No, first one is good enough */ + return; } } + + next_devfn: ; } } Index: stage2/common.c diff -u -2 -r1.12 common.c --- stage2/common.c 2000/05/29 16:11:08 1.12 +++ stage2/common.c 2000/06/09 01:55:48 @@ -24,4 +24,5 @@ #ifdef SUPPORT_DISKLESS # include <etherboot.h> +# include <pci.h> #endif @@ -136,4 +137,12 @@ setup_diskless_environment (void) { + /* + * Intel's PXE prefers the LOM (LAN on motherboard). + * If we booted with PXE, then that must be the one connected. + * As it happens, the LOM always shows up last in sequence. + * So preferring the last Intel adapter found is a good strategy. + */ + eth_pci_prefer_last = PCI_VENDOR_ID_INTEL; + /* For now, there is no difference between BOOTP and DHCP in GRUB. */ if (! bootp ()) -- Chip Salzenberg - a.k.a. - <chip@valinux.com> "I wanted to play hopscotch with the impenetrable mystery of existence, but he stepped in a wormhole and had to go in early." // MST3K
For requests or suggestions regarding this mailing list archive please write to netboot@gkminix.han.de.