Jump to content

IPXE

From NixOS Wiki

iPXE is an open-source network boot firmware.

Customize Nix Package

While common iPXE configurations are already built & cached centrally, building custom iPXE images can be useful to make it easier to use in different environments, e.g. equipped with otherwise unsupported hardware. All build configuration options, hardware drivers & pre-configured targets are listed in the official iPXE documentation. This section should help you to “translate“ the instructions from the iPXE documentation to a working nix equivalent.

The iPXE package.nix in Nixpkgs allows you to change the build configuration and/or to build targets with a specific set of drivers. For that the package defines attributes which can be easily overriden.

additionalOptions allows you to define build configuration options. Where iPXE requires you to add a #define OPTION_NAME to a C header file, you can do the same by adding "OPTION_NAME" to the option list. Be aware that the iPXE option does not list all available options by design, you can find others by examining the C header files in src/config in their GitHub repository. additionalTargets allows you to build iPXE artifacts for use in different environments. It is an attribute set, mapping from a target name to the resulting name of the output file. For iPXE, the target name defines which drivers (or set of drivers from a pre-configured target) should be compiled into your additional artifact. The general syntax of the target name is [platform]/[driver].[extension], where multiple drivers are separated with --.[1] The syntax is further explained here, where also a list of pre-configured targets (i.e. set of drivers) designed for common use cases is presented. A list of additional drivers is available there.

Example as Standalone Flake

Following is a flake as a full standalone example. Its intended use is to be able to quickly compile a custom iPXE artifact for use on outside systems.

{
  description = "custom iPXE build for USB network cards";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/unstable";
  outputs =
    { nixpkgs, ... }:
    {
      packages.x86_64-linux.ipxe = nixpkgs.legacyPackages.x86_64-linux.ipxe.override {
        additionalOptions = [
          "USB_HCD_USBIO"
        ];
        additionalTargets = {
          # build for platform: x86_64-efi
          # with driver (sets): ipxe, ecm, ncm
          # build a (normal) efi binary
          "bin-x86_64-efi/ipxe--ecm--ncm.efi" = "ipxe-usbnet.efi";
        };
      };
    };
}

Given the flake above, you can build your additional target by running nix build nixpkgs#ipxe. Then the custom artifact should be available behind the result symlink, in this example as result/ipxe-usbnet.efi. This does also compile the default outputs, but this should not be a big problem as they share nearly all of their code and so the compiler can reuse most of its work for all targets.