Skip to content

Commit

Permalink
chore(deps): update to uefi v0.32
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Sep 18, 2024
1 parent bc6f370 commit c80fe46
Showing 16 changed files with 69 additions and 101 deletions.
8 changes: 3 additions & 5 deletions docs/labs/0x00/tasks.md
Original file line number Diff line number Diff line change
@@ -335,10 +335,10 @@ extern crate log;
extern crate alloc;

use core::arch::asm;
use uefi::prelude::*;
use uefi::{Status, entry};

#[entry]
fn efi_main(image: uefi::Handle, system_table: SystemTable<Boot>) -> Status {
fn efi_main() -> Status {
uefi::helpers::init().expect("Failed to initialize utilities");
log::set_max_level(log::LevelFilter::Info);

@@ -356,9 +356,7 @@ fn efi_main(image: uefi::Handle, system_table: SystemTable<Boot>) -> Status {
}
```

`efi_main` 通过 `#[entry]` 被指定为 UEFI 程序的入口函数,`efi_main` 函数的参数 `system_table` 是一个 `SystemTable<Boot>` 类型的变量,它包含了 UEFI 程序运行时所需要的各种信息,如内存映射、文件系统、图形界面等。

`efi_main` 函数中,首先对 `system_table``log` 进行初始化,然后进入一个死循环,每次循环输出一条日志后等待一段时间。
`efi_main` 通过 `#[entry]` 被指定为 UEFI 程序的入口函数,在 `efi_main` 函数中,首先对 UEFI 相关功能组件进行初始化,然后进入一个死循环,每次循环输出一条日志后等待一段时间。

在项目根目录下运行 `make run``python ysos.py run`,预期得到如下输出:

11 changes: 3 additions & 8 deletions docs/labs/0x01/tasks.md
Original file line number Diff line number Diff line change
@@ -111,8 +111,8 @@ SECTIONS {
为了方便你的实现,在 `pkg/boot/src/fs.rs` 中,提供了一些函数可供调用,对于一个正常的文件读取流程,你可以参考如下代码:

```rust
let mut file = open_file(bs, file_path);
let buf = load_file(bs, &mut file);
let mut file = open_file(file_path);
let buf = load_file(&mut file);
```

### 更新控制寄存器
@@ -158,12 +158,7 @@ unsafe {
!!! tip "一些提示"

- `physical_memory_offset` 在配置结构体中,它描述了物理地址进行线性映射的偏移量,你可能会使用到。
- 你可以使用如下的代码初始化帧分配器:

```rust
let mut frame_allocator = UEFIFrameAllocator(bs);
```

- 你可以使用 `&mut UEFIFrameAllocator` 表达式作为参数传递帧分配器。
- `pkg/elf/src/lib.rs` 中的 `load_segment` 函数需要你进行补全。**请认真学习实验文档所提供的有关分页内存权限管理、内核 ELF 文件格式的内容,以便你能够完成这一部分的实现。**
- 阅读配置文件定义中有关内核栈的内容,利用相关参数来初始化内核栈。
- 别忘了将你修改过的控制寄存器恢复原样。
28 changes: 4 additions & 24 deletions docs/labs/0x04/tasks.md
Original file line number Diff line number Diff line change
@@ -168,8 +168,8 @@ pub struct BootInfo {
/// Load apps into memory, when no fs implemented in kernel
///
/// List all file under "APP" and load them.
pub fn load_apps(bs: &BootServices) -> AppList {
let mut root = open_root(bs);
pub fn load_apps() -> AppList {
let mut root = open_root();
let mut buf = [0; 8];
let cstr_path = uefi::CStr16::from_str_with_buf("\\APP\\", &mut buf).unwrap();

@@ -218,7 +218,7 @@ pub fn load_apps(bs: &BootServices) -> AppList {

let apps = if config.load_apps {
info!("Loading apps...");
Some(load_apps(system_table.boot_services()))
Some(load_apps())
} else {
info!("Skip loading apps");
None
@@ -966,27 +966,7 @@ The factorial of 999999 under modulo 1000000007 is 128233642.

3. 🤔 基于帧回收器的实现,在 `elf` 中实现 `unmap_range` 函数,从页表中取消映射一段连续的页面,并使用帧回收器进行回收。之后,在合适的地方,结合 `ProcessData` 中存储的页面信息,利用这个函数实现进程栈的回收。其他进程资源(如页表、代码段、数据段等)的回收将会在后续实验中实现,目前暂时不需要考虑。

4. 🤔 尝试利用 `UefiRuntime``chrono` crate,获取当前时间,并将其暴露给用户态,以实现 `sleep` 函数。

`UefiRuntime` 的实现,它可能需要使用锁进行保护:

```rust
pub struct UefiRuntime {
runtime_service: &'static RuntimeServices,
}

impl UefiRuntime {
pub unsafe fn new(boot_info: &'static BootInfo) -> Self {
Self {
runtime_service: boot_info.system_table.runtime_services(),
}
}

pub fn get_time(&self) -> Time {
self.runtime_service.get_time().unwrap()
}
}
```
4. 🤔 尝试利用 `uefi::runtime::get_time()``chrono` crate,获取当前时间,并将其暴露给用户态,以实现 `sleep` 函数。

这里提供一个可能的 `sleep` 函数实现:

2 changes: 1 addition & 1 deletion src/0x00/pkg/boot/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
uefi = { version = "0.31", default-features = false }
uefi = { version = "0.32", default-features = false }
log = "0.4"

[features]
2 changes: 1 addition & 1 deletion src/0x01/pkg/boot/Cargo.toml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ edition = "2021"

[dependencies]
arrayvec = { version = "0.7", default-features = false }
uefi = { version = "0.28", default-features = false }
uefi = { version = "0.32", default-features = false }
log = "0.4"
x86_64 = "0.15"
xmas-elf = "0.9"
12 changes: 5 additions & 7 deletions src/0x01/pkg/boot/src/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use uefi::table::boot::*;
use uefi::boot::{AllocateType, MemoryType};
use x86_64::{structures::paging::*, PhysAddr};

/// Use `BootServices::allocate_pages()` as frame allocator
pub struct UEFIFrameAllocator<'a>(pub &'a BootServices);
pub struct UEFIFrameAllocator;

unsafe impl FrameAllocator<Size4KiB> for UEFIFrameAllocator<'_> {
unsafe impl FrameAllocator<Size4KiB> for UEFIFrameAllocator {
fn allocate_frame(&mut self) -> Option<PhysFrame> {
let addr = self
.0
.allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, 1)
let addr = uefi::boot::allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, 1)
.expect("Failed to allocate frame");
let frame = PhysFrame::containing_address(PhysAddr::new(addr));
let frame = PhysFrame::containing_address(PhysAddr::new(addr.as_ptr() as u64));
Some(frame)
}
}
34 changes: 16 additions & 18 deletions src/0x01/pkg/boot/src/fs.rs
Original file line number Diff line number Diff line change
@@ -4,25 +4,22 @@ use uefi::table::boot::*;
use xmas_elf::ElfFile;

/// Open root directory
pub fn open_root(bs: &BootServices) -> Directory {
let handle = bs
.get_handle_for_protocol::<SimpleFileSystem>()
pub fn open_root() -> Directory {
let handle = uefi::boot::get_handle_for_protocol::<SimpleFileSystem>()
.expect("Failed to get handle for SimpleFileSystem");

let fs = bs
.open_protocol_exclusive::<SimpleFileSystem>(handle)
let mut fs = uefi::boot::open_protocol_exclusive::<SimpleFileSystem>(handle)
.expect("Failed to get FileSystem");
let mut fs = fs;

fs.open_volume().expect("Failed to open volume")
}


/// Open file at `path`
pub fn open_file(bs: &BootServices, path: &str) -> RegularFile {
pub fn open_file(path: &str) -> RegularFile {
let mut buf = [0; 64];
let cstr_path = uefi::CStr16::from_str_with_buf(path, &mut buf).unwrap();

let handle = open_root(bs)
let handle = open_root()
.open(cstr_path, FileMode::Read, FileAttribute::empty())
.expect("Failed to open file");

@@ -33,37 +30,38 @@ pub fn open_file(bs: &BootServices, path: &str) -> RegularFile {
}

/// Load file to new allocated pages
pub fn load_file(bs: &BootServices, file: &mut RegularFile) -> &'static mut [u8] {
pub fn load_file(file: &mut RegularFile) -> &'static mut [u8] {
let mut info_buf = [0u8; 0x100];
let info = file
.get_info::<FileInfo>(&mut info_buf)
.expect("Failed to get file info");

let pages = info.file_size() as usize / 0x1000 + 1;

let mem_start = bs
.allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, pages)
.expect("Failed to allocate pages");
let mem_start =
uefi::boot::allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, pages)
.expect("Failed to allocate pages");

let buf = unsafe { core::slice::from_raw_parts_mut(mem_start as *mut u8, pages * 0x1000) };
let buf = unsafe { core::slice::from_raw_parts_mut(mem_start.as_ptr(), pages * 0x1000) };
let len = file.read(buf).expect("Failed to read file");

info!(
"Load file \"{}\" to memory, size = {}",
info.file_name(),
len
);

&mut buf[..len]
}

/// Free ELF files for which the buffer was created using 'load_file'
pub fn free_elf(bs: &BootServices, elf: ElfFile) {
pub fn free_elf(elf: ElfFile) {
let buffer = elf.input;
let pages = buffer.len() / 0x1000 + 1;
let mem_start = buffer.as_ptr() as u64;
let mem_start = NonNull::new(buffer.as_ptr() as *mut u8).expect("Invalid pointer");

info!("Free ELF file, pages = {}, addr = {:#x?}", pages, mem_start);

unsafe {
bs.free_pages(mem_start, pages).expect("Failed to free pages");
uefi::boot::free_pages(mem_start, pages).expect("Failed to free pages");
}
}
5 changes: 3 additions & 2 deletions src/0x01/pkg/boot/src/lib.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ pub use uefi::table::Runtime;
pub use uefi::Status as UefiStatus;

use arrayvec::ArrayVec;
use core::ptr::NonNull;
use x86_64::VirtAddr;
use x86_64::registers::control::Cr3;
use x86_64::structures::paging::{OffsetPageTable, PageTable};
@@ -35,8 +36,8 @@ pub struct BootInfo {
/// The offset into the virtual address space where the physical memory is mapped.
pub physical_memory_offset: u64,

/// UEFI SystemTable
pub system_table: SystemTable<Runtime>,
/// The system table virtual address
pub system_table: NonNull<core::ffi::c_void>,
}

/// Get current page table from CR3
30 changes: 13 additions & 17 deletions src/0x01/pkg/boot/src/main.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ extern crate alloc;

use alloc::boxed::Box;
use alloc::vec;
use uefi::prelude::*;
use uefi::{entry, Status};
use x86_64::registers::control::*;
use ysos_boot::*;

@@ -17,14 +17,12 @@ mod config;
const CONFIG_PATH: &str = "\\EFI\\BOOT\\boot.conf";

#[entry]
fn efi_main(image: uefi::Handle, mut system_table: SystemTable<Boot>) -> Status {
uefi::helpers::init(&mut system_table).expect("Failed to initialize utilities");
fn efi_main() -> Status {
uefi::helpers::init().expect("Failed to initialize utilities");

log::set_max_level(log::LevelFilter::Info);
info!("Running UEFI bootloader...");

let bs = system_table.boot_services();

// 1. Load config
let config = { /* FIXME: Load config file as Config */ };

@@ -38,14 +36,7 @@ fn efi_main(image: uefi::Handle, mut system_table: SystemTable<Boot>) -> Status
}

// 3. Load MemoryMap
let max_mmap_size = system_table.boot_services().memory_map_size();
let mmap_storage = Box::leak(
vec![0; max_mmap_size.map_size + 10 * max_mmap_size.entry_size].into_boxed_slice(),
);
let mmap = system_table
.boot_services()
.memory_map(mmap_storage)
.expect("Failed to get memory map");
let mmap = uefi::boot::memory_map(MemoryType::LOADER_DATA).expect("Failed to get memory map");

let max_phys_addr = mmap
.entries()
@@ -67,19 +58,24 @@ fn efi_main(image: uefi::Handle, mut system_table: SystemTable<Boot>) -> Status

// FIXME: recover write protect (Cr0)

free_elf(bs, elf);
free_elf(elf);

// 5. Pass system table to kernel
let ptr = uefi::table::system_table_raw().expect("Failed to get system table");
let system_table = ptr.cast::<core::ffi::c_void>();


// 5. Exit boot and jump to ELF entry
// 6. Exit boot and jump to ELF entry
info!("Exiting boot services...");

let (runtime, mmap) = system_table.exit_boot_services(MemoryType::LOADER_DATA);
let mmap = unsafe { uefi::boot::exit_boot_services(MemoryType::LOADER_DATA) };
// NOTE: alloc & log are no longer available

// construct BootInfo
let bootinfo = BootInfo {
memory_map: mmap.entries().copied().collect(),
physical_memory_offset: config.physical_memory_offset,
system_table: runtime,
system_table,
};

// align stack to 8 bytes
1 change: 1 addition & 0 deletions src/0x01/pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
boot = { package = "ysos_boot", path = "../boot", default-features = false }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
uefi = { version = "0.32", default-features = false }
paste = "1.0"
spin = "0.9"
x86 = "0.52"
16 changes: 8 additions & 8 deletions src/0x01/pkg/kernel/src/lib.rs
Original file line number Diff line number Diff line change
@@ -15,21 +15,21 @@ pub use utils::*;
mod drivers;

use boot::BootInfo;
use uefi::{runtime::ResetType, Status};

pub fn init(_boot_info: &'static BootInfo) {
unsafe {
// set uefi system table
uefi::table::set_system_table(boot_info.system_table.cast().as_ptr());
}

drivers::serial::init(); // init serial output
logger::init(); // init logger system

info!("YatSenOS initialized.");
}

pub fn shutdown(boot_info: &'static BootInfo) -> ! {
pub fn shutdown() -> ! {
info!("YatSenOS shutting down.");
unsafe {
boot_info.system_table.runtime_services().reset(
boot::ResetType::SHUTDOWN,
boot::UefiStatus::SUCCESS,
None,
);
}
uefi::runtime::reset(ResetType::SHUTDOWN, Status::SUCCESS, None);
}
1 change: 1 addition & 0 deletions src/0x02/pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
boot = { package = "ysos_boot", path = "../boot", default-features = false }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
uefi = { version = "0.32", default-features = false }
crossbeam-queue = { version = "0.3", default-features = false, features = ["alloc"] }
paste = "1.0"
spin = "0.9"
15 changes: 7 additions & 8 deletions src/0x02/pkg/kernel/src/lib.rs
Original file line number Diff line number Diff line change
@@ -32,6 +32,11 @@ pub use alloc::format;
use boot::BootInfo;

pub fn init(boot_info: &'static BootInfo) {
unsafe {
// set uefi system table
uefi::table::set_system_table(boot_info.system_table.cast().as_ptr());
}

serial::init(); // init serial output
logger::init(); // init logger system
memory::address::init(boot_info);
@@ -46,13 +51,7 @@ pub fn init(boot_info: &'static BootInfo) {
info!("YatSenOS initialized.");
}

pub fn shutdown(boot_info: &'static BootInfo) -> ! {
pub fn shutdown() -> ! {
info!("YatSenOS shutting down.");
unsafe {
boot_info.system_table.runtime_services().reset(
boot::ResetType::SHUTDOWN,
boot::UefiStatus::SUCCESS,
None,
);
}
uefi::runtime::reset(ResetType::SHUTDOWN, Status::SUCCESS, None);
}
1 change: 1 addition & 0 deletions src/0x03/pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
boot = { package = "ysos_boot", path = "../boot", default-features = false }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
uefi = { version = "0.32", default-features = false }
crossbeam-queue = { version = "0.3", default-features = false, features = ["alloc"] }
paste = "1.0"
spin = "0.9"
2 changes: 1 addition & 1 deletion src/0x03/pkg/kernel/src/main.rs
Original file line number Diff line number Diff line change
@@ -38,5 +38,5 @@ pub fn kernel_main(boot_info: &'static boot::BootInfo) -> ! {
}
}

ysos::shutdown(boot_info);
ysos::shutdown();
}
Loading

0 comments on commit c80fe46

Please sign in to comment.