Odi's astoundingly incomplete notes

New entries | Code

bnx2 firmware and PXE bootable kernel

I am building a Linux kernel that is booted via the network with PXE. The machine that runs it has a Broadcom network card that uses the bnx2 driver. That card needs firmware to function, which is normally loaded into the card by udev.

As the kernel boots it obtains an IP via DHCP and mounts its root file system over NFS. For that it needs a working network card and hence the firmware. Of course the firmware can not be on NFS and there is no udev to load it yet. Hence the kernel must load it. If you don't want an initramfs (because it's a PITA to build), you need to build the firmware into the kernel.

The kernel has config options to build firmware blobs into the kernel. They are found under:
 Device Drivers
   Generic Driver Options
     [*] Include in-kernel firmware blobs in kernel binary
     () External firmware blobs to build into the kernel binary
     (/lib/firmware) Firmware blobs root directory
and they map to the .config variables FIRMWARE_IN_KERNEL, EXTRA_FIRMWARE and EXTRA_FIRMWARE_DIR.

EXTRA_FIRMWARE is a space separated list of file names of the firmeware blobs.
EXTRA_FIRMWARE_DIR is a slash terminated directory where those files are.

Now you first need to know which versions of these files are requested by the driver:
# cd drivers/net/ethernet/broadcom/
# grep \\.fw bnx2.c
#define FW_MIPS_FILE_06         "bnx2/bnx2-mips-06-6.2.3.fw"
#define FW_RV2P_FILE_06         "bnx2/bnx2-rv2p-06-6.0.15.fw"
#define FW_MIPS_FILE_09         "bnx2/bnx2-mips-09-6.2.1b.fw"
#define FW_RV2P_FILE_09_Ax      "bnx2/bnx2-rv2p-09ax-6.0.17.fw"
#define FW_RV2P_FILE_09         "bnx2/bnx2-rv2p-09-6.0.17.fw"
So you should list exactly these names in EXTRA_FIRMWARE. To make it extra difficult the kernel itself doesn't even contain these versions:
# ls firmware/bnx2
bnx2-mips-06-6.2.1.fw.ihex   bnx2-rv2p-06-6.0.15.fw.ihex  bnx2-rv2p-09ax-6.0.17.fw.ihex
bnx2-mips-09-6.2.1a.fw.ihex  bnx2-rv2p-09-6.0.17.fw.ihex
But fortunately the firmware is distributed separately and should already be in /lib/firmware. On Gentoo these files are installed by the ebuild sys-kernel/linux-firmware.
# ls /lib/firmware/bnx2
bnx2-mips-06-4.6.16.fw     bnx2-mips-09-5.0.0.j3.fw  bnx2-rv2p-06-6.0.15.fw
bnx2-mips-06-5.0.0.j3.fw   bnx2-mips-09-5.0.0.j9.fw  bnx2-rv2p-09-4.6.15.fw
bnx2-mips-06-5.0.0.j6.fw   bnx2-mips-09-6.0.17.fw    bnx2-rv2p-09-5.0.0.j10.fw
bnx2-mips-06-6.0.15.fw     bnx2-mips-09-6.2.1a.fw    bnx2-rv2p-09-5.0.0.j3.fw
bnx2-mips-06-6.2.1.fw      bnx2-mips-09-6.2.1b.fw    bnx2-rv2p-09-6.0.17.fw
bnx2-mips-06-6.2.3.fw      bnx2-mips-09-6.2.1.fw     bnx2-rv2p-09ax-5.0.0.j10.fw
bnx2-mips-09-4.6.17.fw     bnx2-rv2p-06-4.6.16.fw    bnx2-rv2p-09ax-5.0.0.j3.fw
bnx2-mips-09-5.0.0.j15.fw  bnx2-rv2p-06-5.0.0.j3.fw  bnx2-rv2p-09ax-6.0.17.fw
So you must set EXTRA_FIRMWARE_DIR = /lib/firmware/.

With these options correctly set, such a kernel boots perfectly over PXE.

posted on 2014-05-02 16:56 UTC in Code | 1 comments | permalink
merci Odi