commit 2dede6d9c3a20109127ca3a33c7550821e7fb516 from: Tobias Heider date: Tue May 21 16:37:44 2024 UTC Add U-Boot UEFI testing post commit - 35cbaaed5f07a5d2d955642fab55123d4eba5b7b commit + 2dede6d9c3a20109127ca3a33c7550821e7fb516 blob - 7d57989907724c6adc73371349f72ee664a7bd03 blob + 9cda7327ede882a1b9a4818d23a4c798d24b17e8 --- stuff/index.html +++ stuff/index.html @@ -19,6 +19,10 @@ 2024-02-01, Booting OS X from USB on Apple PowerMacs +
  • + 2024-05-21, + Testing UEFI apps in u-boot sandbox +
  • blob - /dev/null blob + 031e4861ff53a9206f2d0a0cd724d5073b1b2a74 (mode 644) --- /dev/null +++ stuff/u-boot-efi-sandbox.html @@ -0,0 +1,159 @@ + + + + + + + + + + + +

    Testing UEFI apps in the U-Boot sandbox

    + +
      +
    1. Building the U-Boot sandbox
    2. +
    3. Running an UEFI binary
    4. +
    5. Sources
    6. +
    + +

    +This is a neat trick I learnt recently while experimenting with building a +small EFI bootloader shim. +Most guides will recommend testing using qemu and EDK2, but there +actually is an even simpler way to test (some) EFI applications entirely +without qemu or rebooting. + +

    +U-Boot can be compiled as a simple user-space Linux executable using the +"sandbox" pseudo-architecture. This is mostly used in the U-Boot test suite but +we can also use it as a simple user-space EFI test environment. +Obviously only the UEFI subset supported by U-boot will work. + +

    Building the U-Boot sandbox

    + +

    +Building the sandbox binary is as easy as fetching the source code from + + https://github.com/u-boot/u-boot +, selecting the Sandbox configuration and building the binary via: + +

    +$ make sandbox_defconfig all
    +
    + +

    +The resulting u-boot file is a regular ELF Linux binary. +Running it with -h gives us a list of supported command line options. + +

    +$ ./u-boot -h
    +U-Boot 2024.07-rc2 (May 19 2024 - 17:27:46 +0200)
    +
    +u-boot, a command line test interface to U-Boot
    +
    +Usage: u-boot [options]
    +Options:
    +      --autoboot_keyed           Allow keyed autoboot
    +  -b, --boot                     Run distro boot commands
    +  -c, --command          <arg>   Execute U-Boot command
    +  -d, --fdt              <arg>   Specify U-Boot's control FDT
    +  -D, --default_fdt              Use the default u-boot.dtb control FDT in U-Boot directory
    +  -h, --help                     Display help
    +  -i, --interactive              Enter interactive mode
    +  -j, --jump             <arg>   Jumped from previous U-Boot
    +  -k, --select_unittests <arg>   Select unit tests to run
    +  -K, --double_lcd               Double the LCD display size in each direction
    +  -l, --show_lcd                 Show the sandbox LCD display
    +  -L, --log_level        <arg>   Set log level (0=panic, 7=debug)
    +  -m, --memory           <arg>   Read/write ram_buf memory contents from file
    +  -n, --ignore_missing           Ignore missing state on read
    +  -p, --program          <arg>   U-Boot program name
    +  -r, --read                     Read the state FDT on startup
    +      --rm_memory                Remove memory file after reading
    +  -s, --state            <arg>   Specify the sandbox state FDT
    +  -S, --signals                  Handle signals (such as SIGSEGV) in sandbox
    +  -t, --terminal         <arg>   Set terminal to raw/cooked mode
    +  -T, --test_fdt                 Use the test.dtb control FDT in U-Boot directory
    +  -u, --unittests                Run unit tests
    +  -v, --verbose                  Show test output
    +  -w, --write                    Write state FDT on exit
    +
    + +

    +More info on sandbox mode and other interesting configuration options can be +found in the official U-Boot documentation at [1]. + +

    Running an UEFI binary

    + +

    +Running the binary without arguments allows us to access a regular U-Boot shell, +load files and execute them via UEFI. +The last missing puzzle piece is getting the binary from the host file system +into U-Boot. For this we can use the host interface documented at +[2]. + +

    +host load allows as to load a file from the host file system directly +into U-Boot's address space. +The easiest way to load and execute a binary is loading it to the pre-defined +kernel_addr_r address and then executing it via bootefi. + +

    +For simplicity we use the helloworld.efi application that ships +with U-Boot: + +

    +=> host load hostfs - $kernel_addr_r lib/efi_loader/helloworld.efi
    +5632 bytes read in 0 ms
    +=> bootefi $kernel_addr_r
    +No EFI system partition
    +No EFI system partition
    +Failed to persist EFI variables
    +Missing TPMv2 device for EFI_TCG_PROTOCOL
    +Missing RNG device for EFI_RNG_PROTOCOL
    +Booting /lib\efi_loader\helloworld.efi
    +Hello, world!
    +Running on UEFI 2.10
    +Have ACPI 2.0 table
    +Load options: 
    +File path: /lib\efi_loader\helloworld.efi
    +Missing device handle
    +=>
    +
    + +

    +And there we have our "Hello, world!". Of course we can also run more +complex applications than that as long as they work in U-Boot. +Even graphical EFI apps should not be a problem thanks to built-in SDL support. + +

    +Finally, to make things even easier we can use the -c flag to pass +those commands directly to u-boot and skip the interactive session entirely: + +

    +$ ./u-boot -c "host load hostfs - \$kernel_addr_r lib/efi_loader/helloworld.efi; bootefi \$kernel_addr_r"
    +
    + +
    + +

    Sources

    + + [1] U-Boot - Sandbox Documentation + +
    + + [2] U-Boot - host command + + + + + + blob - /dev/null blob + 8437150d0f204ad0c83d41cfed1b882fc3439a65 (mode 644) --- /dev/null +++ stuff/u-boot.svg @@ -0,0 +1,67 @@ + + + + + U-Boot Logo + + + + image/svg+xml + + U-Boot Logo + + + + Heinrich Schuchardt <xypron.glpk@gmx.de> + + + May 21st, 2018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file