Move EFI and core-rt to their own crates, cleanup a bit

This commit is contained in:
Mark
2020-09-10 22:57:11 +03:00
parent a1fb763878
commit 3fd9a8b428
14 changed files with 226 additions and 148 deletions
Generated
+8 -5
View File
@@ -1,14 +1,17 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
name = "core-rt"
version = "0.1.0"
[[package]]
name = "efi"
version = "0.1.0"
[[package]]
name = "yboot2"
version = "0.1.0"
dependencies = [
"spin",
"core-rt",
"efi",
]
+3 -1
View File
@@ -7,4 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
spin = { version = "0.5.2" }
#spin = { version = "0.5.2" }
efi = { path = "crates/efi" }
core-rt = { path = "crates/core-rt" }
-17
View File
@@ -1,17 +0,0 @@
TARGET=x86_64-unknown-uefi
RUST_SRC=$(shell find src -type f -name "*.rs") \
Cargo.toml
O=target/$(TARGET)/debug
all: $(O)/image.fat32
clean:
cargo clean
$(O)/yboot2.efi: $(RUST_SRC)
cargo build -Z build-std=core
$(O)/image.fat32: $(O)/yboot2.efi
dd if=/dev/zero of=$@ bs=1M count=64
mkfs.vfat -F32 $@
mcopy -i $@ $(O)/yboot2.efi ::app.efi
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "core-rt"
version = "0.1.0"
authors = ["Mark <alnyan@airmail.cc>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+32
View File
@@ -0,0 +1,32 @@
#![no_std]
#[no_mangle]
unsafe extern "C" fn memcpy(dst: *mut u8, src: *const u8, cnt: usize) -> *mut u8 {
let mut i = 0isize;
while i < cnt as isize {
*(dst.offset(i)) = *(src.offset(i));
i += 1;
}
return dst;
}
#[no_mangle]
unsafe extern "C" fn memset(dst: *mut u8, val: i32, cnt: usize) -> *mut u8 {
let mut i = 0isize;
while i < cnt as isize {
*(dst.offset(i)) = val as u8;
i += 1;
}
return dst;
}
#[no_mangle]
unsafe extern "C" fn memcmp(a: *const u8, b: *const u8, cnt: usize) -> i32 {
let mut i = 0isize;
while i < cnt as isize {
let diff = *(a.offset(i)) - *(b.offset(i));
if diff != 0u8 {
return diff as i32;
}
i += 1;
}
return 0;
}
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "efi"
version = "0.1.0"
authors = ["Mark <alnyan@airmail.cc>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+23
View File
@@ -0,0 +1,23 @@
use core::ffi::c_void;
pub type Handle = *mut c_void;
pub enum Status {
Success,
Err
}
impl Status {
pub fn to_isize(self) -> isize {
match self {
Status::Success => 0,
Status::Err => -1,
}
}
pub fn from_isize(v: isize) -> Status {
match v {
0 => Status::Success,
_ => Status::Err
}
}
}
+54
View File
@@ -0,0 +1,54 @@
#![no_std]
use core::ffi::c_void;
pub mod proto;
pub use proto::stop::*;
pub mod base;
pub use base::*;
#[repr(C)]
pub struct TableHeader {
signature: u64,
revision: u32,
header_size: u32,
crc32: u32,
reserved: u32
}
#[repr(C)]
pub struct SystemTable {
hdr: TableHeader,
pub firmware_vendor: *const i16,
pub firmware_revision: u32,
console_in_handle: Handle,
con_in: *mut c_void, // TODO
console_out_handle: Handle,
con_out: *mut SimpleTextOutputProtocol,
standard_error_handle: Handle,
std_err: *mut SimpleTextOutputProtocol,
runtime_services: *mut c_void, // TODO
boot_services: *mut c_void, // TODO
number_of_table_entries: usize,
configuration_table: *mut c_void // TODO
}
impl SystemTable {
pub fn con_out(&self) -> &'static mut SimpleTextOutputProtocol {
unsafe { &mut *self.con_out }
}
}
static mut SYSTEM_TABLE: Option<*mut SystemTable> = None;
pub fn init_tables(st: *mut SystemTable) {
if st.is_null() {
panic!();
}
unsafe { SYSTEM_TABLE = Some(st); }
}
pub fn system_table() -> &'static mut SystemTable {
unsafe { &mut *SYSTEM_TABLE.unwrap() }
}
+1
View File
@@ -0,0 +1 @@
pub mod stop;
+48
View File
@@ -0,0 +1,48 @@
use crate::Status;
use core::ffi::c_void;
use core::fmt;
#[repr(C)]
pub struct SimpleTextOutputProtocol {
fn_reset: *mut c_void,
fn_output_string: unsafe fn(&SimpleTextOutputProtocol, s: *const i16) -> isize
}
impl SimpleTextOutputProtocol {
// Not the original name provided by EFI, but whatever
pub fn output_char16_string(&self, s: *const i16) -> Status {
unsafe { Status::from_isize((self.fn_output_string)(self, s)) }
}
pub fn output_string(&self, s: &str) {
let mut buf = [0i16; 64];
let mut iter = s.bytes();
let mut i = 0;
while let Some(byte) = iter.next() {
if i == 63 {
buf[i] = 0;
i = 0;
// Output chunk
self.output_char16_string(buf.as_ptr());
} else {
buf[i] = byte as i16;
i += 1;
}
}
if i != 0 {
buf[i] = 0;
self.output_char16_string(buf.as_ptr());
}
}
}
impl fmt::Write for SimpleTextOutputProtocol {
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
self.output_string(s);
Ok(())
}
}
+7 -1
View File
@@ -3,7 +3,13 @@
BIOS=/usr/share/edk2-ovmf/OVMF_CODE.fd
IMAGE=target/x86_64-unknown-uefi/debug/image.fat32
make
set -e
cargo build -Z build-std=core
dd if=/dev/zero of=${IMAGE} bs=1M count=64
mkfs.vfat -F32 ${IMAGE}
mcopy -i ${IMAGE} target/x86_64-unknown-uefi/debug/yboot2.efi ::app.efi
qemu-system-x86_64 \
-drive format=raw,file=$BIOS,readonly=on,if=pflash \
-88
View File
@@ -1,88 +0,0 @@
use core::ffi::c_void;
use spin::Mutex;
pub enum Status {
Success,
Err
}
impl Status {
pub fn to_isize(self) -> isize {
match self {
Status::Success => 0,
Status::Err => -1,
}
}
pub fn from_isize(v: isize) -> Status {
match v {
0 => Status::Success,
_ => Status::Err
}
}
}
#[repr(C)]
pub struct TableHeader {
signature: u64,
revision: u32,
header_size: u32,
crc32: u32,
reserved: u32
}
#[repr(C)]
pub struct SimpleTextOutputProtocol {
fn_reset: *mut c_void,
fn_output_string: unsafe fn(&SimpleTextOutputProtocol, s: *const i16) -> isize
}
impl SimpleTextOutputProtocol {
pub fn output_string(&self, s: *const i16) -> Status {
unsafe { Status::from_isize((self.fn_output_string)(self, s)) }
}
}
#[repr(C)]
pub struct SystemTable {
hdr: TableHeader,
firmware_vendor: *const i16,
firmware_revision: u32,
console_in_handle: *mut c_void,
con_in: *mut c_void,
console_out_handle: *mut c_void,
con_out: *mut SimpleTextOutputProtocol,
standard_error_handle: *mut c_void,
std_err: *mut c_void,
runtime_services: *mut c_void,
boot_services: *mut c_void,
number_of_table_entries: usize,
configuration_table: *mut c_void
}
impl SystemTable {
pub fn con_out(&self) -> &'static mut SimpleTextOutputProtocol {
unsafe { &mut *self.con_out }
}
}
static mut SYSTEM_TABLE: Option<*mut SystemTable> = None;
pub fn init_tables(st: *mut SystemTable) {
unsafe { SYSTEM_TABLE = Some(st); }
}
pub fn system_table() -> &'static mut SystemTable {
unsafe { &mut *SYSTEM_TABLE.unwrap() }
}
pub fn con_output_string(text: &str) {
let mut buf = [0i16; 512];
let mut i = 0;
for byte in text.bytes() {
buf[i] = byte as i16;
i += 1;
}
system_table().con_out().output_string(buf.as_ptr());
}
+14 -36
View File
@@ -1,52 +1,30 @@
#![no_main]
#![no_std]
mod efi;
extern crate efi;
extern crate core_rt;
use core::ffi::c_void;
use efi::{Status, SystemTable};
use efi::{Status, Handle, SystemTable, system_table};
#[no_mangle]
unsafe extern "C" fn memcpy(dst: *mut u8, src: *const u8, cnt: usize) -> *mut u8 {
let mut i = 0isize;
while i < cnt as isize {
*(dst.offset(i)) = *(src.offset(i));
i += 1;
}
return dst;
}
#[no_mangle]
unsafe extern "C" fn memset(dst: *mut u8, val: i32, cnt: usize) -> *mut u8 {
let mut i = 0isize;
while i < cnt as isize {
*(dst.offset(i)) = val as u8;
i += 1;
}
return dst;
}
#[no_mangle]
unsafe extern "C" fn memcmp(a: *const u8, b: *const u8, cnt: usize) -> i32 {
let mut i = 0isize;
while i < cnt as isize {
let diff = *(a.offset(i)) - *(b.offset(i));
if diff != 0u8 {
return diff as i32;
}
i += 1;
}
return 0;
}
#[macro_use]
mod println;
fn main() -> Status {
efi::con_output_string("Test\n");
let con_out = system_table().con_out();
print!("Firmware vendor: ");
con_out.output_char16_string(system_table().firmware_vendor);
print!(", revision: {}.{}",
system_table().firmware_revision >> 16,
system_table().firmware_revision & 0xFFFF);
println!();
return Status::Success;
}
#[no_mangle]
extern "C" fn efi_main(_ih: *mut c_void, st: *mut SystemTable) -> isize {
extern "C" fn efi_main(_ih: Handle, st: *mut SystemTable) -> isize {
efi::init_tables(st);
return main().to_isize();
}
+18
View File
@@ -0,0 +1,18 @@
use efi::system_table;
use core::fmt;
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::println::do_println(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! println {
() => (print!("\r\n"));
($($arg:tt)*) => (print!("{}\r\n", format_args!($($arg)*)));
}
pub fn do_println(args: fmt::Arguments) {
use core::fmt::Write;
system_table().con_out().write_fmt(args).unwrap();
}