1# Generic Bootloader Library 2 3This directory hosts the Generic Bootloader Library project. A Bazel 4workspace is setup for building the library as well as an EFI executable that 5can be loaded directly from the firmware. 6 7## Get source tree and build 8 9To successfully get and build the tree your machine must have the following dependencies installed: 10 11``` 12# repo to work with android repositories (https://source.android.com/docs/setup/reference/repo) 13# bazel-bootstrap to build (https://bazel.build/) 14sudo apt install repo bazel-bootstrap 15``` 16 17The GBL project are intended to be built from the 18[Android UEFI Manifest](https://android.googlesource.com/kernel/manifest/+/refs/heads/uefi-gbl-mainline/default.xml) 19checkout: 20 21``` 22repo init -u https://android.googlesource.com/kernel/manifest -b uefi-gbl-mainline 23repo sync -j16 24``` 25 26To build the EFI application: 27 28``` 29./tools/bazel run //bootable/libbootloader:gbl_efi_dist --extra_toolchains=@gbl//toolchain:all 30``` 31 32The above builds the EFI application for all of `x86_64`, `x86_32`, `aarch64` 33and `riscv64` platforms. 34 35To run the set of unit tests: 36 37``` 38./tools/bazel test @gbl//tests --extra_toolchains=@gbl//toolchain:all 39``` 40 41## IDE Setup 42 43For rust development, we recommend use VSCode + rust-analyzer plugin. 44 45rust-analyzer requires `rust-project.json` to work properly. Luckily, bazel has 46support for generating `rust-project.json`: 47 48``` 49./tools/bazel run @rules_rust//tools/rust_analyzer:gen_rust_project --norepository_disable_download -- --bazel ./tools/bazel @gbl//efi/... 50``` 51 52`@gbl//efi/...` is the target to generate rust project for, here it means 53"everything under @gbl//efi/ directory" . Omitting the target specifier would 54result in analyzing "@/..." , which would most likely fail due to some obscure 55reason. Should targets get moved around in the future, this path spec also need 56to be updated. 57 58After generating `rust-project.json`, you would notice that your IDE still 59doesn't offer auto completion. This is because some source file paths pointing 60to bazel-output dir, and you are most likely editing source files in 61`bootable/libbootloader/gbl`. In addition, the generated rust-project.json sets 62"cfg=test" for all targets, which causes certain dependency graph to resolve 63incorrectly. To fix this, run 64 65``` 66python3 bootable/libbootloader/gbl/rewrite_rust_project_path.py rust-project.json 67``` 68 69And reload your IDE. 70 71## Run the EFI application 72 73### Boot Android on Cuttlefish 74 75If you have a main AOSP checkout and is setup to run 76[Cuttlefish](https://source.android.com/docs/setup/create/cuttlefish), you can 77run the EFI image directly with: 78 79``` 80cvd start --android_efi_loader=<path to the EFI image> ... 81``` 82 83The above uses the same setting as a normal `cvd start` run, except that 84instead of booting Android directly, the emulator first hands off to the EFI 85application, which will take over booting android. 86 87Note: For x86 platform, use the EFI image built for `x86_32`. 88 89### Boot Fuchsia on Vim3 90 91Booting Fuchsia on a Vim3 development board is supported. To run the 92application: 93 941. Complete all 95[bootstrap steps](https://fuchsia.dev/fuchsia-src/development/hardware/khadas-vim3?hl=en) 96to setup Vim3 as a Fuchsia device. 972. Reboot the device into fastboot mode. 983. Run fastboot command: 99``` 100fastboot stage <path to the EFI binary> && fastboot oem run-staged-efi 101``` 102 103### Run on standalone QEMU 104 105If you want to test the EFI image directly on QEMU with your custom 106configurations: 107 1081. Install EDK, QEMU and u-boot prebuilts 109 110 ``` 111 sudo apt-get install qemu-system ovmf u-boot-qemu 112 ``` 113 1141. Depending on the target architecture you want to run: 115 116 For `x86_64`: 117 ``` 118 mkdir -p /tmp/esp/EFI/BOOT && \ 119 cp <path to EFI image> /tmp/esp/EFI/BOOT/bootx64.efi && \ 120 qemu-system-x86_64 -nographic \ 121 -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \ 122 -drive format=raw,file=fat:rw:/tmp/esp 123 ``` 124 125 For `aarch64`: 126 ``` 127 mkdir -p /tmp/esp/EFI/BOOT && \ 128 cp <path to EFI image> /tmp/esp/EFI/BOOT/bootaa64.efi && \ 129 qemu-system-aarch64 -nographic -machine virt -m 1G -cpu cortex-a57 \ 130 -drive if=pflash,format=raw,readonly=on,file=/usr/share/AAVMF/AAVMF_CODE.fd \ 131 -drive format=raw,file=fat:rw:/tmp/esp 132 ``` 133 134 For `riscv64`: 135 ``` 136 mkdir -p /tmp/esp/EFI/BOOT && \ 137 cp <path to EFI image> /tmp/esp/EFI/BOOT/bootriscv64.efi && \ 138 qemu-system-riscv64 -nographic -machine virt -m 256M \ 139 -bios /usr/lib/u-boot/qemu-riscv64/u-boot.bin \ 140 -drive format=raw,file=fat:rw:/tmp/esp,id=blk0 \ 141 -device virtio-blk-device,drive=blk0 142 ``` 143 144### Boot Fuchsia on emulator 145 1461. Make sure Fuchsia target pass control to GBL. 147 148 Set path to GBL binary here: [fuchsia/src/firmware/gigaboot/cpp/backends.gni : gigaboot_gbl_efi_app](https://cs.opensource.google/fuchsia/fuchsia/+/main:src/firmware/gigaboot/cpp/backends.gni;l=25?q=gigaboot_gbl_efi_app) 149 150 E.g. in `fuchsia/src/firmware/gigaboot/cpp/backends.gni`: 151 ``` 152 $ cat ./fuchsia/src/firmware/gigaboot/cpp/backends.gni 153 ... 154 declare_args() { 155 ... 156 gigaboot_gbl_efi_app = "<path to EFI image>/gbl_x86_64.efi" 157 } 158 ``` 159 160 Or in `fx set`: 161 ``` 162 fx set core.x64 --args=gigaboot_gbl_efi_app='"<path to EFI image>/gbl_x86_64.efi"' 163 ``` 164 1652. Build: (this has to be done every time if EFI app changes) 166 167 `fx build` 168 1693. Run emulator in UEFI mode with raw disk 170 171 ``` 172 fx qemu -a x64 --uefi --disktype=nvme -D ./out/default/obj/build/images/disk.raw 173 ``` 174 175## EFI Protocols 176 177List of EFI protocols used by GBL and a brief description of each [here](./docs/efi_protocols.md). 178