From 2fd70b0ff4c95158b7b65c06b38fb3ff06628ba3 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Wed, 2 Dec 2020 10:32:26 +0800 Subject: [PATCH] Heap test passed on k210/qemu, heap size = 3M. --- os/Cargo.lock | 18 ++++++++++++++- os/Cargo.toml | 1 + os/build.rs | 16 +++++-------- os/src/config.rs | 1 + os/src/main.rs | 7 ++++++ os/src/mm/heap_allocator.rs | 45 +++++++++++++++++++++++++++++++++++++ os/src/mm/mod.rs | 4 ++++ 7 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 os/src/mm/heap_allocator.rs create mode 100644 os/src/mm/mod.rs diff --git a/os/Cargo.lock b/os/Cargo.lock index 85e21762..0f37abff 100644 --- a/os/Cargo.lock +++ b/os/Cargo.lock @@ -30,13 +30,22 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "buddy_system_allocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4e85e760e105b46ae0bd1236578793c6c147ae7463fe95c8350296b8bfcb830" +dependencies = [ + "spin 0.7.0", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -49,6 +58,7 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" name = "os" version = "0.1.0" dependencies = [ + "buddy_system_allocator", "lazy_static", "riscv", ] @@ -122,6 +132,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652ac3743312871a5fb703f0337e68ffa3cdc28c863efad0b8dc858fa10c991b" + [[package]] name = "thread_local" version = "1.0.1" diff --git a/os/Cargo.toml b/os/Cargo.toml index 0d1bb342..14b9b69b 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -9,6 +9,7 @@ edition = "2018" [dependencies] riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } lazy_static = { version = "1.4.0", features = ["spin_no_std"] } +buddy_system_allocator = "0.6" [features] board_qemu = [] diff --git a/os/build.rs b/os/build.rs index 4a996053..52eb20cb 100644 --- a/os/build.rs +++ b/os/build.rs @@ -6,7 +6,7 @@ fn main() { insert_app_data().unwrap(); } -static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/debug/"; +static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/"; fn insert_app_data() -> Result<()> { let mut f = File::create("src/link_app.S").unwrap(); @@ -26,17 +26,14 @@ fn insert_app_data() -> Result<()> { .section .data .global _num_app _num_app: - .quad {} - "#, apps.len())?; + .quad {}"#, apps.len())?; for i in 0..apps.len() { writeln!(f, r#" - .quad app_{}_start - "#, i)?; + .quad app_{}_start"#, i)?; } writeln!(f, r#" - .quad app_{}_end - "#, apps.len() - 1)?; + .quad app_{}_end"#, apps.len() - 1)?; for (idx, app) in apps.iter().enumerate() { println!("app_{}: {}", idx, app); @@ -45,9 +42,8 @@ _num_app: .global app_{0}_start .global app_{0}_end app_{0}_start: - .incbin "{2}{1}.bin" -app_{0}_end: - "#, idx, app, TARGET_PATH)?; + .incbin "{2}{1}" +app_{0}_end:"#, idx, app, TARGET_PATH)?; } Ok(()) } \ No newline at end of file diff --git a/os/src/config.rs b/os/src/config.rs index 07c30246..eca451bb 100644 --- a/os/src/config.rs +++ b/os/src/config.rs @@ -3,6 +3,7 @@ pub const KERNEL_STACK_SIZE: usize = 4096 * 2; pub const MAX_APP_NUM: usize = 4; pub const APP_BASE_ADDRESS: usize = 0x80100000; pub const APP_SIZE_LIMIT: usize = 0x20000; +pub const KERNEL_HEAP_SIZE: usize = 0x30_0000; #[cfg(feature = "board_k210")] pub const CPU_FREQ: usize = 10000000; diff --git a/os/src/main.rs b/os/src/main.rs index 64855732..23891178 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -4,6 +4,9 @@ #![feature(llvm_asm)] #![feature(panic_info_message)] #![feature(const_in_array_repeat_expressions)] +#![feature(alloc_error_handler)] + +extern crate alloc; #[macro_use] mod console; @@ -15,6 +18,7 @@ mod loader; mod config; mod task; mod timer; +mod mm; global_asm!(include_str!("entry.asm")); global_asm!(include_str!("link_app.S")); @@ -33,6 +37,9 @@ fn clear_bss() { pub fn rust_main() -> ! { clear_bss(); println!("[kernel] Hello, world!"); + mm::init_heap(); + mm::heap_test(); + loop {} trap::init(); loader::load_apps(); trap::enable_interrupt(); diff --git a/os/src/mm/heap_allocator.rs b/os/src/mm/heap_allocator.rs new file mode 100644 index 00000000..2c7468f2 --- /dev/null +++ b/os/src/mm/heap_allocator.rs @@ -0,0 +1,45 @@ +use buddy_system_allocator::LockedHeap; +use crate::config::KERNEL_HEAP_SIZE; + +#[global_allocator] +static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); + +#[alloc_error_handler] +pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! { + panic!("Heap allocation error, layout = {:?}", layout); +} + +static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE]; + +pub fn init_heap() { + unsafe { + HEAP_ALLOCATOR + .lock() + .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE); + } +} + +#[allow(unused)] +pub fn heap_test() { + use alloc::boxed::Box; + use alloc::vec::Vec; + extern "C" { + fn sbss(); + fn ebss(); + } + let bss_range = sbss as usize..ebss as usize; + let a = Box::new(5); + assert_eq!(*a, 5); + assert!(bss_range.contains(&(a.as_ref() as *const _ as usize))); + drop(a); + let mut v: Vec = Vec::new(); + for i in 0..500 { + v.push(i); + } + for i in 0..500 { + assert_eq!(v[i], i); + } + assert!(bss_range.contains(&(v.as_ptr() as usize))); + drop(v); + println!("heap_test passed!"); +} diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs new file mode 100644 index 00000000..192e27e9 --- /dev/null +++ b/os/src/mm/mod.rs @@ -0,0 +1,4 @@ +mod heap_allocator; + +pub use heap_allocator::init_heap; +pub use heap_allocator::heap_test;