Created
December 5, 2018 10:36
-
-
Save dvdhrm/4b9ccec41e7d3fabcc8deb971d533582 to your computer and use it in GitHub Desktop.
UEFI Hello World in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Example: Hello World! | |
// | |
// This is an example UEFI application that prints "Hello World!", then waits for key input before | |
// it exits. It serves as base example how to write UEFI applications without any helper modules | |
// other than the UEFI protocol definitions. | |
// | |
// The `efi_main` function serves as entry-point. Depending on your target-configuration, this | |
// entry point might be called differently. If you use the target-configuration shipped with | |
// r-efi, then `efi_main` is the selected PE/COFF entry point. | |
// | |
// Additionally, a panic handler is provided. This is executed by rust on panic. For simplicity, | |
// we simply end up in an infinite loop. For real applications, this method should probably call | |
// into `SystemTable->boot_services->exit()` to exit the UEFI application. Note, however, that | |
// UEFI applications are likely to run in the same address space as the entire firmware. Hence, | |
// halting the machine might be a viable alternative. All that is out-of-scope of this example, | |
// though. | |
// | |
// Lastly, note that UEFI uses UTF-16 strings. Since rust literals are UTF-8, we have to use an | |
// open-coded, zero-terminated, UTF-16 array as argument to `output_string()`. Similarly to the | |
// panic handler, real applications should rather use UTF-16 modules. | |
// | |
#![no_main] | |
#![no_std] | |
extern crate r_efi; | |
use r_efi::efi; | |
#[panic_handler] | |
fn rust_panic_handler(_info: &core::panic::PanicInfo) -> ! { | |
loop {} | |
} | |
#[no_mangle] | |
pub extern fn efi_main(_h: efi::Handle, st: *mut efi::SystemTable) -> efi::Status { | |
let mut s = [ | |
0x0048u16, 0x0065u16, 0x006cu16, 0x006cu16, 0x006fu16, // "Hello" | |
0x0020u16, // " " | |
0x0057u16, 0x006fu16, 0x0072u16, 0x006cu16, 0x0064u16, // "World" | |
0x0021u16, // "!" | |
0x0000u16, // NUL | |
]; | |
unsafe { | |
// Print "Hello World!". | |
((*(*st).con_out).output_string)((*st).con_out, s.as_mut_ptr()); | |
} | |
unsafe { | |
// Wait for key input, by waiting on the `wait_for_key` event hook. | |
let mut x: usize = 0; | |
((*(*st).boot_services).wait_for_event)(1, &mut (*(*st).con_in).wait_for_key, &mut x); | |
} | |
0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment