xref: /aosp_15_r20/bootable/libbootloader/gbl/efi/src/lib.rs (revision 5225e6b173e52d2efc6bcf950c27374fd72adabc)
1*5225e6b1SAndroid Build Coastguard Worker // Copyright 2023, The Android Open Source Project
2*5225e6b1SAndroid Build Coastguard Worker //
3*5225e6b1SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*5225e6b1SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*5225e6b1SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*5225e6b1SAndroid Build Coastguard Worker //
7*5225e6b1SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*5225e6b1SAndroid Build Coastguard Worker //
9*5225e6b1SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*5225e6b1SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*5225e6b1SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*5225e6b1SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*5225e6b1SAndroid Build Coastguard Worker // limitations under the License.
14*5225e6b1SAndroid Build Coastguard Worker 
15*5225e6b1SAndroid Build Coastguard Worker //! This EFI application implements a demo for booting Android/Fuchsia from disk. See
16*5225e6b1SAndroid Build Coastguard Worker //! bootable/libbootloader/gbl/README.md for how to run the demo. See comments of
17*5225e6b1SAndroid Build Coastguard Worker //! `android_boot:android_boot_demo()` and `fuchsia_boot:fuchsia_boot_demo()` for
18*5225e6b1SAndroid Build Coastguard Worker //! supported/unsupported features at the moment.
19*5225e6b1SAndroid Build Coastguard Worker 
20*5225e6b1SAndroid Build Coastguard Worker #![cfg_attr(not(test), no_std)]
21*5225e6b1SAndroid Build Coastguard Worker 
22*5225e6b1SAndroid Build Coastguard Worker // For the `vec!` macro
23*5225e6b1SAndroid Build Coastguard Worker #[macro_use]
24*5225e6b1SAndroid Build Coastguard Worker extern crate alloc;
25*5225e6b1SAndroid Build Coastguard Worker 
26*5225e6b1SAndroid Build Coastguard Worker mod efi_blocks;
27*5225e6b1SAndroid Build Coastguard Worker mod error;
28*5225e6b1SAndroid Build Coastguard Worker mod ops;
29*5225e6b1SAndroid Build Coastguard Worker #[macro_use]
30*5225e6b1SAndroid Build Coastguard Worker mod utils;
31*5225e6b1SAndroid Build Coastguard Worker 
32*5225e6b1SAndroid Build Coastguard Worker // Currently un-testable modules.
33*5225e6b1SAndroid Build Coastguard Worker //
34*5225e6b1SAndroid Build Coastguard Worker // The libefi API surface is large and complex; rather than trying to mock it all out at once, we
35*5225e6b1SAndroid Build Coastguard Worker // will selectively enable modules for test as they become mockable.
36*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
37*5225e6b1SAndroid Build Coastguard Worker mod android_boot;
38*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
39*5225e6b1SAndroid Build Coastguard Worker mod fastboot;
40*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
41*5225e6b1SAndroid Build Coastguard Worker mod fuchsia_boot;
42*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
43*5225e6b1SAndroid Build Coastguard Worker mod net;
44*5225e6b1SAndroid Build Coastguard Worker 
45*5225e6b1SAndroid Build Coastguard Worker // In tests, map the `efi_mocks` module as `efi`. This allows other modules to `use crate::efi`
46*5225e6b1SAndroid Build Coastguard Worker // and automatically pick up the correct one.
47*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
48*5225e6b1SAndroid Build Coastguard Worker pub(crate) use efi;
49*5225e6b1SAndroid Build Coastguard Worker #[cfg(test)]
50*5225e6b1SAndroid Build Coastguard Worker pub(crate) use efi_mocks as efi;
51*5225e6b1SAndroid Build Coastguard Worker 
52*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
53*5225e6b1SAndroid Build Coastguard Worker use {
54*5225e6b1SAndroid Build Coastguard Worker     core::fmt::Write,
55*5225e6b1SAndroid Build Coastguard Worker     efi::{efi_print, efi_println, EfiEntry},
56*5225e6b1SAndroid Build Coastguard Worker     libgbl::Result,
57*5225e6b1SAndroid Build Coastguard Worker     utils::loaded_image_path,
58*5225e6b1SAndroid Build Coastguard Worker };
59*5225e6b1SAndroid Build Coastguard Worker 
60*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
61*5225e6b1SAndroid Build Coastguard Worker enum TargetOs {
62*5225e6b1SAndroid Build Coastguard Worker     Android,
63*5225e6b1SAndroid Build Coastguard Worker     Fuchsia,
64*5225e6b1SAndroid Build Coastguard Worker }
65*5225e6b1SAndroid Build Coastguard Worker 
66*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
get_target_os(entry: &EfiEntry) -> TargetOs67*5225e6b1SAndroid Build Coastguard Worker fn get_target_os(entry: &EfiEntry) -> TargetOs {
68*5225e6b1SAndroid Build Coastguard Worker     let mut buf = [0u8; 1];
69*5225e6b1SAndroid Build Coastguard Worker     if entry
70*5225e6b1SAndroid Build Coastguard Worker         .system_table()
71*5225e6b1SAndroid Build Coastguard Worker         .runtime_services()
72*5225e6b1SAndroid Build Coastguard Worker         .get_variable(&efi::GBL_EFI_VENDOR_GUID, efi::GBL_EFI_OS_BOOT_TARGET_VARNAME, &mut buf)
73*5225e6b1SAndroid Build Coastguard Worker         .is_ok()
74*5225e6b1SAndroid Build Coastguard Worker     {
75*5225e6b1SAndroid Build Coastguard Worker         efi_println!(
76*5225e6b1SAndroid Build Coastguard Worker             entry,
77*5225e6b1SAndroid Build Coastguard Worker             "`{}` is set. Proceeding as Fuchsia.",
78*5225e6b1SAndroid Build Coastguard Worker             efi::GBL_EFI_OS_BOOT_TARGET_VARNAME
79*5225e6b1SAndroid Build Coastguard Worker         );
80*5225e6b1SAndroid Build Coastguard Worker         TargetOs::Fuchsia
81*5225e6b1SAndroid Build Coastguard Worker     } else if fuchsia_boot::is_fuchsia_gpt(&entry).is_ok() {
82*5225e6b1SAndroid Build Coastguard Worker         efi_println!(entry, "Partition layout looks like Fuchsia. Proceeding as Fuchsia");
83*5225e6b1SAndroid Build Coastguard Worker         TargetOs::Fuchsia
84*5225e6b1SAndroid Build Coastguard Worker     } else {
85*5225e6b1SAndroid Build Coastguard Worker         efi_println!(entry, "Proceeding as Android");
86*5225e6b1SAndroid Build Coastguard Worker         TargetOs::Android
87*5225e6b1SAndroid Build Coastguard Worker     }
88*5225e6b1SAndroid Build Coastguard Worker }
89*5225e6b1SAndroid Build Coastguard Worker 
90*5225e6b1SAndroid Build Coastguard Worker /// GBL EFI application logic entry point.
91*5225e6b1SAndroid Build Coastguard Worker #[cfg(not(test))]
app_main(entry: EfiEntry) -> Result<()>92*5225e6b1SAndroid Build Coastguard Worker pub fn app_main(entry: EfiEntry) -> Result<()> {
93*5225e6b1SAndroid Build Coastguard Worker     efi_println!(entry, "****Generic Bootloader Application****");
94*5225e6b1SAndroid Build Coastguard Worker     if let Ok(v) = loaded_image_path(&entry) {
95*5225e6b1SAndroid Build Coastguard Worker         efi_println!(entry, "Image path: {}", v);
96*5225e6b1SAndroid Build Coastguard Worker     }
97*5225e6b1SAndroid Build Coastguard Worker 
98*5225e6b1SAndroid Build Coastguard Worker     match get_target_os(&entry) {
99*5225e6b1SAndroid Build Coastguard Worker         TargetOs::Fuchsia => fuchsia_boot::fuchsia_boot_demo(entry)?,
100*5225e6b1SAndroid Build Coastguard Worker         TargetOs::Android => android_boot::android_boot_demo(entry)?,
101*5225e6b1SAndroid Build Coastguard Worker     }
102*5225e6b1SAndroid Build Coastguard Worker 
103*5225e6b1SAndroid Build Coastguard Worker     Ok(())
104*5225e6b1SAndroid Build Coastguard Worker }
105