xref: /aosp_15_r20/bootable/libbootloader/gbl/README.md (revision 5225e6b173e52d2efc6bcf950c27374fd72adabc)
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