diff --git a/ch4/os/Cargo.toml b/ch4/os/Cargo.toml index 41c18f7..7980275 100644 --- a/ch4/os/Cargo.toml +++ b/ch4/os/Cargo.toml @@ -12,4 +12,5 @@ debug=true [dependencies] riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } lazy_static = { version = "1.4.0", features = ["spin_no_std"] } -sbi-rt = { version = "0.0.2", features = ["legacy"] } \ No newline at end of file +sbi-rt = { version = "0.0.2", features = ["legacy"] } +buddy_system_allocator = "0.6" \ No newline at end of file diff --git a/ch4/os/src/config.rs b/ch4/os/src/config.rs index 7e29a68..0afa146 100644 --- a/ch4/os/src/config.rs +++ b/ch4/os/src/config.rs @@ -1,8 +1,9 @@ pub const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址 pub const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小 pub const MAX_APP_NUM: usize = 10; // 支持最大的用户应用数量 +pub const KERNEL_HEAP_SIZE: usize = 0x30_0000; // 内核的堆大小 3M -pub const USER_STACK_SIZE: usize = 4096 * 2; // 栈大小为8kb -pub const KERNEL_STACK_SIZE: usize = 4096 * 2; +pub const USER_STACK_SIZE: usize = 4096 * 2; // 每个应用用户态的栈大小为8kb +pub const KERNEL_STACK_SIZE: usize = 4096 * 2; // 每个应用的内核栈 pub use crate::board::*; \ No newline at end of file diff --git a/ch4/os/src/main.rs b/ch4/os/src/main.rs index f6e00d3..0982f5f 100644 --- a/ch4/os/src/main.rs +++ b/ch4/os/src/main.rs @@ -2,6 +2,8 @@ #![no_std] #![no_main] +extern crate alloc; + use core::arch::global_asm; use sbi::{console_put_char, shutdown}; use lang_items::console; @@ -15,6 +17,7 @@ pub mod loader; pub mod config; pub mod task; pub mod timer; +pub mod mm; #[path = "boards/qemu.rs"] mod board; @@ -44,12 +47,14 @@ pub fn rust_main(){ println!("sbss: {:#x}, ebss: {:#x}", sbss as usize, ebss as usize); println!("boot_stack_top_bound: {:#x}, boot_stack_lower_bound: {:#x}", boot_stack_top_bound as usize, boot_stack_lower_bound as usize); - trap::init(); + // 初始化动态内存分配器, 使我们能在内核中使用动态大小数据类型 + mm::heap_allocator::init_heap(); + trap::init(); loader::load_app(); trap::enable_timer_interrupt(); // 允许定时器中断 timer::set_next_trigger(); // 在进入用户态之前, 设置一个时钟中断, 防止第一个用户任务死循环 - task::run_first_task(); + // task::run_first_task(); panic!("Disable run here") } diff --git a/ch4/os/src/mm/heap_allocator.rs b/ch4/os/src/mm/heap_allocator.rs new file mode 100644 index 0000000..dc073b8 --- /dev/null +++ b/ch4/os/src/mm/heap_allocator.rs @@ -0,0 +1,59 @@ +use alloc::boxed::Box; +use alloc::vec; +use buddy_system_allocator::LockedHeap; +use crate::config::KERNEL_HEAP_SIZE; +use crate::println; + + +// 动态内存分配器 +#[global_allocator] +static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); + +// 堆的空间 +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); + } + // heap_test() +} + +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; + println!("bss_range {:?}", bss_range); + + let a = Box::new(5); + println!("a: {:?} ptr: {:p}", a, a.as_ref()); + let b = Box::new(6); + println!("b: {:?} ptr: {:p}", b, b.as_ref()); + + + unsafe { + println!("HEAP_SPACE: {:?}", HEAP_SPACE.as_ptr()) + } + + let mut v = vec![]; + for i in 0..500{ + v.push(i); + } + + for i in 0..500{ + v.pop(); + } + + println!("{:?}", v); + + // 通过输出打印, 发现 a 和b 均被分配在了 HEAP_SPACE 中, 且 HEAP_SPACE 被分配在了 bss段中, 这个段由我们 linker.ld 进行手动布局 + // 目前整个bss段的大小都是3M, 说明当前bss段中只有这一个 数据 +} \ No newline at end of file diff --git a/ch4/os/src/mm/mod.rs b/ch4/os/src/mm/mod.rs new file mode 100644 index 0000000..e7b4c87 --- /dev/null +++ b/ch4/os/src/mm/mod.rs @@ -0,0 +1 @@ +pub mod heap_allocator; \ No newline at end of file