mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-21 08:06:31 +00:00
新的内存管理模块 (#301)
  实现了具有优秀架构设计的新的内存管理模块,对内核空间和用户空间的内存映射、分配、释放、管理等操作进行了封装,使得内核开发者可以更加方便地进行内存管理。   内存管理模块主要由以下类型的组件组成: - **硬件抽象层(MemoryManagementArch)** - 提供对具体处理器架构的抽象,使得内存管理模块可以在不同的处理器架构上运行 - **页面映射器(PageMapper)**- 提供对虚拟地址和物理地址的映射,以及页表的创建、填写、销毁、权限管理等操作。分为两种类型:内核页表映射器(KernelMapper)和用户页表映射器(位于具体的用户地址空间结构中) - **页面刷新器(PageFlusher)** - 提供对页表的刷新操作(整表刷新、单页刷新、跨核心刷新) - **页帧分配器(FrameAllocator)** - 提供对页帧的分配、释放、管理等操作。具体来说,包括BumpAllocator、BuddyAllocator - **小对象分配器** - 提供对小内存对象的分配、释放、管理等操作。指的是内核里面的SlabAllocator (SlabAllocator的实现目前还没有完成) - **MMIO空间管理器** - 提供对MMIO地址空间的分配、管理操作。(目前这个模块待进一步重构) - **用户地址空间管理机制** - 提供对用户地址空间的管理。 - VMA机制 - 提供对用户地址空间的管理,包括VMA的创建、销毁、权限管理等操作 - 用户映射管理 - 与VMA机制共同作用,管理用户地址空间的映射 - **系统调用层** - 提供对用户空间的内存管理系统调用,包括mmap、munmap、mprotect、mremap等 - **C接口兼容层** - 提供对原有的C代码的接口,是的C代码能够正常运行。 除上面的新增内容以外,其它的更改内容: - 新增二进制加载器,以及elf的解析器 - 解决由于local_irq_save、local_irq_restore函数的汇编不规范导致影响栈行为的bug。 - 解决local_irq_save未关中断的错误。 - 修复sys_gettimeofday对timezone参数的处理的bug
This commit is contained in:
123
kernel/src/mm/allocator/slab.rs
Normal file
123
kernel/src/mm/allocator/slab.rs
Normal file
@ -0,0 +1,123 @@
|
||||
//! 当前slab分配器暂时不使用,等待后续完善后合并主线
|
||||
#![allow(dead_code)]
|
||||
|
||||
use core::alloc::Layout;
|
||||
|
||||
// 定义Slab,用来存放空闲块
|
||||
pub struct Slab {
|
||||
block_size: usize,
|
||||
free_block_list: FreeBlockList,
|
||||
}
|
||||
|
||||
impl Slab {
|
||||
/// @brief: 初始化一个slab
|
||||
/// @param {usize} start_addr
|
||||
/// @param {usize} slab_size
|
||||
/// @param {usize} block_size
|
||||
pub unsafe fn new(start_addr: usize, slab_size: usize, block_size: usize) -> Slab {
|
||||
let blocks_num = slab_size / block_size;
|
||||
return Slab {
|
||||
block_size: block_size,
|
||||
free_block_list: FreeBlockList::new(start_addr, block_size, blocks_num),
|
||||
};
|
||||
}
|
||||
|
||||
/// @brief: 获取slab中可用的block数
|
||||
pub fn used_blocks(&self) -> usize {
|
||||
return self.free_block_list.len();
|
||||
}
|
||||
|
||||
/// @brief: 扩大free_block_list
|
||||
/// @param {*} mut
|
||||
/// @param {usize} start_addr
|
||||
/// @param {usize} slab_size
|
||||
pub fn grow(&mut self, start_addr: usize, slab_size: usize) {
|
||||
let num_of_blocks = slab_size / self.block_size;
|
||||
let mut block_list =
|
||||
unsafe { FreeBlockList::new(start_addr, self.block_size, num_of_blocks) };
|
||||
// 将新链表接到原链表的后面
|
||||
while let Some(block) = block_list.pop() {
|
||||
self.free_block_list.push(block);
|
||||
}
|
||||
}
|
||||
/// @brief: 从slab中分配一个block
|
||||
/// @return 分配的内存地址
|
||||
pub fn allocate(&mut self, _layout: Layout) -> Option<*mut u8> {
|
||||
match self.free_block_list.pop() {
|
||||
Some(block) => return Some(block.addr() as *mut u8),
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
/// @brief: 将block归还给slab
|
||||
pub fn free(&mut self, ptr: *mut u8) {
|
||||
let ptr = ptr as *mut FreeBlock;
|
||||
unsafe {
|
||||
self.free_block_list.push(&mut *ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// slab中的空闲块
|
||||
struct FreeBlockList {
|
||||
len: usize,
|
||||
head: Option<&'static mut FreeBlock>,
|
||||
}
|
||||
|
||||
impl FreeBlockList {
|
||||
unsafe fn new(start_addr: usize, block_size: usize, num_of_blocks: usize) -> FreeBlockList {
|
||||
let mut new_list = FreeBlockList::new_empty();
|
||||
for i in (0..num_of_blocks).rev() {
|
||||
// 从后往前分配,避免内存碎片
|
||||
let new_block = (start_addr + i * block_size) as *mut FreeBlock;
|
||||
new_list.push(&mut *new_block);
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
fn new_empty() -> FreeBlockList {
|
||||
return FreeBlockList { len: 0, head: None };
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
return self.len;
|
||||
}
|
||||
|
||||
/// @brief: 将空闲块从链表中弹出
|
||||
fn pop(&mut self) -> Option<&'static mut FreeBlock> {
|
||||
// 从链表中弹出一个空闲块
|
||||
let block = self.head.take().map(|node| {
|
||||
self.head = node.next.take();
|
||||
self.len -= 1;
|
||||
node
|
||||
});
|
||||
return block;
|
||||
}
|
||||
|
||||
/// @brief: 将空闲块压入链表
|
||||
fn push(&mut self, free_block: &'static mut FreeBlock) {
|
||||
free_block.next = self.head.take();
|
||||
self.len += 1;
|
||||
self.head = Some(free_block);
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
return self.head.is_none();
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FreeBlockList {
|
||||
fn drop(&mut self) {
|
||||
while let Some(_) = self.pop() {}
|
||||
}
|
||||
}
|
||||
|
||||
struct FreeBlock {
|
||||
next: Option<&'static mut FreeBlock>,
|
||||
}
|
||||
|
||||
impl FreeBlock {
|
||||
/// @brief: 获取FreeBlock的地址
|
||||
/// @return {*}
|
||||
fn addr(&self) -> usize {
|
||||
return self as *const _ as usize;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user