From ebc26d6387d4aa1a6375e8fc599cdcfd917c06fa Mon Sep 17 00:00:00 2001 From: tfx2001 Date: Sun, 21 Jul 2024 15:55:05 +0800 Subject: [PATCH] feat(loader): support load kernel and dtb from flash Signed-off-by: tfx2001 --- src/loader.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 15 ++++++++++---- 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 src/loader.rs diff --git a/src/loader.rs b/src/loader.rs new file mode 100644 index 0000000..ad0f2fd --- /dev/null +++ b/src/loader.rs @@ -0,0 +1,55 @@ +use crate::{DTB_LOAD_ADDRESS, SUPERVISOR_ENTRY}; + +#[derive(PartialEq)] +enum BlobType { + Kernel, + Dts, +} +struct BlobInfo { + type_: BlobType, + start: usize, + length: usize, +} +/// # Blob Info Table +/// +/// | Name | Begin | Length | +/// |--------|------------|--------| +/// | Kernel | 0x80040000 | 2 MB | +/// | DTS | 0x80240000 | 16 KB | +/// +const BLOB_TABLE: &'static [BlobInfo] = &[ + BlobInfo { + type_: BlobType::Kernel, + // Keep 256 KB for SBI firmware. + start: 0x80040000, + length: 2 * 1024 * 1024, + }, + BlobInfo { + type_: BlobType::Dts, + start: 0x80240000, + length: 16 * 1024, + }, +]; + +impl BlobInfo { + unsafe fn load(&self, load_address: *mut u8) { + let src: &[u8] = core::slice::from_raw_parts(self.start as *mut _, self.length); + let dst: &mut [u8] = core::slice::from_raw_parts_mut(load_address, self.length); + dst.copy_from_slice(src); + } +} + +pub unsafe fn load_test_kernel() { + let info: &BlobInfo = &BLOB_TABLE[0]; + assert!(info.type_ == BlobType::Kernel); + assert!(info.start + info.length <= BLOB_TABLE[1].start); + + info.load(SUPERVISOR_ENTRY as *mut u8); +} + +pub unsafe fn load_dtb() { + let info: &BlobInfo = &BLOB_TABLE[1]; + assert!(info.type_ == BlobType::Dts); + + info.load(DTB_LOAD_ADDRESS as *mut u8); +} diff --git a/src/main.rs b/src/main.rs index d26db13..d389ff5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,13 +5,16 @@ mod board; mod extension; +mod loader; mod pmp; mod riscv_spec; mod trap; mod trap_stack; mod constants { /// 特权软件入口。 - pub(crate) const SUPERVISOR_ENTRY: usize = 0x0108_0000; + pub(crate) const SUPERVISOR_ENTRY: usize = 0x4000_0000; + /// 设备树加载地址。 + pub(crate) const DTB_LOAD_ADDRESS: usize = 0x4020_0000; /// 每个硬件线程设置 16KiB 栈空间。 pub(crate) const LEN_STACK_PER_HART: usize = 16 * 1024; } @@ -65,12 +68,16 @@ fn main() -> ! { pmp::print_pmps(); // 设置陷入栈 trap_stack::prepare_for_trap(); - // 加载内核 - load_test_kernel(); + unsafe { + // 加载内核 + loader::load_test_kernel(); + // 加载设备树 + loader::load_dtb() + }; // 设置内核入口 local_hsm().prepare(Supervisor { start_addr: SUPERVISOR_ENTRY, - opaque: Default::default(), + opaque: DTB_LOAD_ADDRESS, }); // 准备启动调度 unsafe {