Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
[build]
|
||||
target = "x86_64-unknown-uefi"
|
||||
|
||||
[target.x86_64-unknown-uefi]
|
||||
rustflags = ["-Ccode-model=small", "-Clink-arg=/debug:none"]
|
||||
@@ -0,0 +1 @@
|
||||
/target
|
||||
Generated
+14
@@ -0,0 +1,14 @@
|
||||
# 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"
|
||||
|
||||
[[package]]
|
||||
name = "yboot2"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "yboot2"
|
||||
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]
|
||||
spin = { version = "0.5.2" }
|
||||
@@ -0,0 +1,17 @@
|
||||
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
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
BIOS=/usr/share/edk2-ovmf/OVMF_CODE.fd
|
||||
IMAGE=target/x86_64-unknown-uefi/debug/image.fat32
|
||||
|
||||
make
|
||||
|
||||
qemu-system-x86_64 \
|
||||
-drive format=raw,file=$BIOS,readonly=on,if=pflash \
|
||||
-drive format=raw,file=$IMAGE \
|
||||
-net none \
|
||||
-enable-kvm \
|
||||
-M q35 \
|
||||
-cpu host
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
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());
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
mod efi;
|
||||
|
||||
use core::ffi::c_void;
|
||||
use efi::{Status, SystemTable};
|
||||
|
||||
#[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;
|
||||
}
|
||||
|
||||
fn main() -> Status {
|
||||
efi::con_output_string("Test\n");
|
||||
|
||||
return Status::Success;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn efi_main(_ih: *mut c_void, st: *mut SystemTable) -> isize {
|
||||
efi::init_tables(st);
|
||||
|
||||
return main().to_isize();
|
||||
}
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
#[panic_handler]
|
||||
fn panic(_panic: &PanicInfo<'_>) -> ! {
|
||||
loop {}
|
||||
}
|
||||
Reference in New Issue
Block a user