Name Date Size #Lines LOC

..--

docs/H25-Apr-2025-2,6041,881

efi/H25-Apr-2025-3,6272,655

integration/aosp_uefi-gbl-mainline/H25-Apr-2025-424370

libabr/H25-Apr-2025-1,436921

libasync/H25-Apr-2025-456329

libavb/H25-Apr-2025-354270

libboot/H25-Apr-2025-802427

libbootimg/H25-Apr-2025-173137

libbootparams/H25-Apr-2025-682474

libc/H25-Apr-2025-1,154703

libdttable/H25-Apr-2025-452320

libefi/H25-Apr-2025-7,8645,090

libefi_types/H25-Apr-2025-1,647994

libelf/H25-Apr-2025-563360

liberror/H25-Apr-2025-416255

libfastboot/H25-Apr-2025-1,8501,286

libfdt/H25-Apr-2025-1,259953

libgbl/H25-Apr-2025-12,5648,691

libmisc/H25-Apr-2025-207145

libsafemath/H25-Apr-2025-574362

libstorage/H25-Apr-2025-3,2222,224

libutils/H25-Apr-2025-172105

smoltcp/H25-Apr-2025-318238

tests/H25-Apr-2025-4240

toolchain/H25-Apr-2025-1,1491,024

tools/H25-Apr-2025-197141

BUILDH A D25-Apr-20251.3 KiB4138

MODULE.bazelH A D25-Apr-2025399 76

OWNERSH A D25-Apr-2025118 76

README.mdH A D25-Apr-20255.5 KiB178130

WORKSPACE.bazelH A D25-Apr-2025624 1614

bazel.MODULE.bazelH A D25-Apr-20251.9 KiB8772

bazel.WORKSPACEH A D25-Apr-20251.2 KiB3829

bazel.bazelrcH A D25-Apr-20252.7 KiB6653

bazel.pyH A D25-Apr-20256.9 KiB192123

bazel.shH A D25-Apr-2025870 235

readme.bzlH A D25-Apr-20253.2 KiB123110

rewrite_rust_project_path.pyH A D25-Apr-20252.6 KiB7439

rustfmt.tomlH A D25-Apr-202593 64

README.md

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

readme.bzl

1# Copyright (C) 2024 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""
16Action that verifies all EFI protocols used by GBL are explicitly listed in README.md
17"""
18
19load("@rules_rust//rust/private:providers.bzl", "CrateInfo")
20
21def _readme_test_rule_impl(ctx):
22    shell_script = """
23while [[ $# -gt 0 ]]; do
24  case $1 in
25    --in)
26      INPUT=$2
27      shift
28      shift
29      ;;
30    --out)
31      OUTPUT=$2
32      shift
33      shift
34      ;;
35    --readme)
36      README=$2
37      shift
38      shift
39      ;;
40    *)
41      echo "Unexpected argument: $1"
42      exit 1
43      ;;
44  esac
45done
46
47if [ ! -f $README ]; then
48  echo "README file doesn't exist: ${README}"
49  exit 1
50fi
51
52ALL_INPUTS=$(echo ${INPUT} | sed 's/,/ /g')
53
54# Look for protocols in the source code that do not exist in the documentation.
55# The protocol name we match on here is the Rust struct name.
56DOCLESS_PROTOCOLS=""
57PROTOCOLS=($(grep -hE 'impl ProtocolInfo for .* \\{' ${ALL_INPUTS} | awk '{print $4}' | sort))
58for P in ${PROTOCOLS[@]}
59do
60  grep -Lq $P ${README} || DOCLESS_PROTOCOLS+="\n\t$P"
61done
62
63if [ ! -z "${DOCLESS_PROTOCOLS}" ]; then
64  echo -e "Missing documentation for protocol(s):$DOCLESS_PROTOCOLS"
65  exit 1
66fi
67
68# Look for protocols in the documentation that are not in the source, to try to
69# prevent stale docs referring to protocols we are no longer using.
70# Here we're matching on words ending in "Protocol", except "Protocol" itself.
71UNUSED_PROTOCOLS=""
72README_PROTOCOLS=($(grep -P " ?[^ ]+Protocol$" ${README} | awk '{print $NF}' | sort | uniq))
73for P in ${README_PROTOCOLS[@]}
74do
75  grep -qhE "impl ProtocolInfo for $P" ${ALL_INPUTS} || UNUSED_PROTOCOLS+="\n\t$P"
76done
77
78if [ ! -z "${UNUSED_PROTOCOLS}" ]; then
79  echo -e "Unused protocol(s) found in documentation:$UNUSED_PROTOCOLS"
80  exit 1
81fi
82
83touch $OUTPUT
84"""
85
86    out_file = ctx.actions.declare_file("%s.script" % ctx.attr.name)
87    in_files = [s for d in ctx.attr.deps for s in d[CrateInfo].srcs.to_list()]
88    readme = ctx.attr.readme
89    args = ctx.actions.args()
90    args.add_joined(
91        "--in",
92        in_files,
93        join_with = ",",
94    )
95    args.add(
96        "--out",
97        out_file,
98    )
99    args.add(
100        "--readme",
101        readme[DefaultInfo].files.to_list()[0],
102    )
103    ctx.actions.run_shell(
104        inputs = in_files + readme[DefaultInfo].files.to_list(),
105        outputs = [out_file],
106        arguments = [args],
107        command = shell_script,
108    )
109    return [DefaultInfo(executable = out_file)]
110
111readme_test = rule(
112    implementation = _readme_test_rule_impl,
113    attrs = {
114        "deps": attr.label_list(
115            providers = [CrateInfo],
116        ),
117        "readme": attr.label(
118            allow_single_file = [".md"],
119        ),
120    },
121    test = True,
122)
123