为内核添加动态内存分配器

ch4
zhangxinyu 2 years ago
parent 8066fafe5d
commit 0e1724297a

@ -12,4 +12,5 @@ debug=true
[dependencies] [dependencies]
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
lazy_static = { version = "1.4.0", features = ["spin_no_std"] } lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
sbi-rt = { version = "0.0.2", features = ["legacy"] } sbi-rt = { version = "0.0.2", features = ["legacy"] }
buddy_system_allocator = "0.6"

@ -1,8 +1,9 @@
pub const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址 pub const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址
pub const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小 pub const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小
pub const MAX_APP_NUM: usize = 10; // 支持最大的用户应用数量 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 USER_STACK_SIZE: usize = 4096 * 2; // 每个应用用户态的栈大小为8kb
pub const KERNEL_STACK_SIZE: usize = 4096 * 2; pub const KERNEL_STACK_SIZE: usize = 4096 * 2; // 每个应用的内核栈
pub use crate::board::*; pub use crate::board::*;

@ -2,6 +2,8 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
extern crate alloc;
use core::arch::global_asm; use core::arch::global_asm;
use sbi::{console_put_char, shutdown}; use sbi::{console_put_char, shutdown};
use lang_items::console; use lang_items::console;
@ -15,6 +17,7 @@ pub mod loader;
pub mod config; pub mod config;
pub mod task; pub mod task;
pub mod timer; pub mod timer;
pub mod mm;
#[path = "boards/qemu.rs"] #[path = "boards/qemu.rs"]
mod board; mod board;
@ -44,12 +47,14 @@ pub fn rust_main(){
println!("sbss: {:#x}, ebss: {:#x}", sbss as usize, ebss as usize); 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); 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(); loader::load_app();
trap::enable_timer_interrupt(); // 允许定时器中断 trap::enable_timer_interrupt(); // 允许定时器中断
timer::set_next_trigger(); // 在进入用户态之前, 设置一个时钟中断, 防止第一个用户任务死循环 timer::set_next_trigger(); // 在进入用户态之前, 设置一个时钟中断, 防止第一个用户任务死循环
task::run_first_task(); // task::run_first_task();
panic!("Disable run here") panic!("Disable run here")
} }

@ -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段中只有这一个 数据
}

@ -0,0 +1 @@
pub mod heap_allocator;
Loading…
Cancel
Save