PXE Boot Through U-Boot Payload

Some users may prefer to boot their operating system over a network. This guide below shows how to achieve that using U-Boot as a payload for SBL.

We leverage existing PXE functionality in U-Boot to enable PXE boot.

Steps:

  • Set up a TFTP server for serving PXE boot files

  • U-Boot can be built as a payload for Slim Bootloader. Please refer to this page for generic build Instructions.

U-Boot Confiugration to enable PXE Boot Support

  1. Below are steps for enabling PXE Boot support in U-Boot

    • After running make slimbootloader_defconfig according to the guide linked above, run

      $ make menuconfig
      
    • Enable pxe under the Command Line Interface section as shown.

      ../_images/1_cmdline_pxe.png
    • Enable dhcp option under the Network Commands section inside Command Line Interface.

      ../_images/2_dhcp.png
    • Enable Use the 'serverip' env var for tftp under the Networking Support section as shown.

      ../_images/3_serverip.png
    • Additionally, you might need to enable the driver for your system’s network controller.

  2. Save the config through the menu. You can run make savedefconfig to save this configuration. It will be saved in a file named defconfig in the root of your U-Boot source.

U-Boot Device Tree Changes

  1. Now, we need to add a few things to the U-Boot device tree for Slim Bootloader target to make sure that U-Boot is able to find the network device. Below are the steps for QEMU target -

  2. Add the following code block to the pci section of u-boot/arch/x86/dts/slimbootloader.dts so it looks like this -

    pci {
        compatible = "pci-x86";
        #address-cells = <3>;
        #size-cells = <2>;
        u-boot,dm-pre-reloc;
        ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x60000000>;
    };
    
    • The ranges property describes the MMIO window for PCI devices. You can get the starting address for this window from your platform’s BoardConfig.py file. It is listed as self.PCI_MEM32_BASE. In case of QEMU, the window starts at 0x80000000.

    • We can assume that the window extends up to the PCI Express Base Address (self.PCI_EXPRESS_BASE), which is 0xE0000000 for QEMU.

    • The last value in the ranges property describes the size of the MMIO window. Thus, we set it to 0x60000000.

    • For more details on the PCI ranges property, you can refer to the device tree documentation here.

Build Slim Bootloader with U-Boot as Payload

  1. Build U-Boot

  2. Copy the generated u-boot-dtb.bin binary to slimbootloader/PayloadPkg/PayloadBins/u-boot-dtb.bin.

  3. Set SBL’s PayloadId to U-BT.

  4. Build Slim Bootloader with U-Boot as Payload.

    $ python BuildLoader.py build <platform> -p "OsLoader.efi:LLDR:Lzma;u-boot-dtb.bin:U-BT:Lzma"
    

U-Boot Shell PXE Boot Commands

  1. Once booted to U-Boot shell, enter the following commands to boot over the network.

    => dhcp
    => setenv serverip <tftp server address>
    => setenv pxefile_addr_r 0x1000000
    => setenv ramdisk_addr_r 0x2000000
    => setenv initrd_addr_r 0x3000000
    => setenv kernel_addr_r 0x4000000
    => pxe get
    => pxe boot
    
  2. You should now see U-Boot load the operating system.

    ../_images/4_pxeboot_log.png