123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532 |
- use core::intrinsics::unlikely;
- use system_error::SystemError;
- use crate::libs::{
- align::{page_align_down, page_align_up},
- spinlock::{SpinLock, SpinLockGuard},
- };
- use super::{PhysAddr, PhysMemoryArea};
- pub const INITIAL_MEMORY_REGIONS_NUM: usize = 128;
- /// 初始内存区域
- static MEM_BLOCK_MANAGER: MemBlockManager = MemBlockManager::new();
- #[inline(always)]
- pub fn mem_block_manager() -> &'static MemBlockManager {
- &MEM_BLOCK_MANAGER
- }
- /// 内存区域管理器
- #[derive(Debug)]
- pub struct MemBlockManager {
- inner: SpinLock<InnerMemBlockManager>,
- }
- #[derive(Debug)]
- pub struct InnerMemBlockManager {
- /// 初始内存区域
- ///
- /// 用于记录内核启动时的内存布局, 这些区域保持升序、不重叠
- initial_memory_regions: [PhysMemoryArea; INITIAL_MEMORY_REGIONS_NUM],
- initial_memory_regions_num: usize,
- }
- impl MemBlockManager {
- #[allow(dead_code)]
- pub const MIN_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(0);
- #[allow(dead_code)]
- pub const MAX_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(usize::MAX);
- const fn new() -> Self {
- Self {
- inner: SpinLock::new(InnerMemBlockManager {
- initial_memory_regions: [PhysMemoryArea::DEFAULT; INITIAL_MEMORY_REGIONS_NUM],
- initial_memory_regions_num: 0,
- }),
- }
- }
- /// 添加内存区域
- ///
- /// 如果添加的区域与已有区域有重叠,会将重叠的区域合并
- #[allow(dead_code)]
- pub fn add_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
- let r = self.add_range(base, size, MemoryAreaAttr::empty());
- return r;
- }
- /// 添加内存区域
- ///
- /// 如果添加的区域与已有区域有重叠,会将重叠的区域合并
- fn add_range(
- &self,
- base: PhysAddr,
- size: usize,
- flags: MemoryAreaAttr,
- ) -> Result<(), SystemError> {
- if size == 0 {
- return Ok(());
- }
- let mut inner = self.inner.lock();
- if inner.initial_memory_regions_num >= INITIAL_MEMORY_REGIONS_NUM {
- panic!("Too many memory regions!");
- }
- let block = PhysMemoryArea::new(base, size, MemoryAreaAttr::empty());
- // 特判第一个区域
- if inner.initial_memory_regions_num == 0 {
- inner.initial_memory_regions[0] = block;
- inner.initial_memory_regions_num += 1;
- return Ok(());
- }
- // 先计算需要添加的区域数量
- let blocks_to_add = self
- .do_add_block(&mut inner, block, false, flags)
- .expect("Failed to count blocks to add!");
- if inner.initial_memory_regions_num + blocks_to_add > INITIAL_MEMORY_REGIONS_NUM {
- kerror!("Too many memory regions!");
- return Err(SystemError::ENOMEM);
- }
- // 然后添加区域
- self.do_add_block(&mut inner, block, true, flags)
- .expect("Failed to add block!");
- return Ok(());
- }
- fn do_add_block(
- &self,
- inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
- block: PhysMemoryArea,
- insert: bool,
- flags: MemoryAreaAttr,
- ) -> Result<usize, SystemError> {
- let mut base = block.base;
- let end = block.base + block.size;
- let mut i = 0;
- let mut start_index = -1;
- let mut end_index = -1;
- let mut num_to_add = 0;
- while i < inner.initial_memory_regions_num {
- let range_base = inner.initial_memory_regions[i].base;
- let range_end =
- inner.initial_memory_regions[i].base + inner.initial_memory_regions[i].size;
- if range_base >= end {
- break;
- }
- if range_end <= base {
- i += 1;
- continue;
- }
- // 有重叠
- if range_base > base {
- num_to_add += 1;
- if insert {
- if start_index == -1 {
- start_index = i as isize;
- }
- end_index = (i + 1) as isize;
- self.do_insert_area(inner, i, base, range_base - base, flags);
- i += 1;
- }
- }
- i += 1;
- base = core::cmp::min(range_end, end);
- }
- if base < end {
- num_to_add += 1;
- if insert {
- if start_index == -1 {
- start_index = i as isize;
- }
- end_index = (i + 1) as isize;
- self.do_insert_area(inner, i, base, end - base, flags);
- }
- }
- if num_to_add == 0 {
- return Ok(0);
- }
- if insert {
- self.do_merge_blocks(inner, start_index, end_index);
- }
- return Ok(num_to_add);
- }
- fn do_insert_area(
- &self,
- inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
- index: usize,
- base: PhysAddr,
- size: usize,
- flags: MemoryAreaAttr,
- ) {
- let copy_elements = inner.initial_memory_regions_num - index;
- inner
- .initial_memory_regions
- .copy_within(index..index + copy_elements, index + 1);
- inner.initial_memory_regions[index] = PhysMemoryArea::new(base, size, flags);
- inner.initial_memory_regions_num += 1;
- }
- fn do_merge_blocks(
- &self,
- inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
- start_index: isize,
- mut end_index: isize,
- ) {
- let mut i = 0;
- if start_index > 0 {
- i = start_index - 1;
- }
- end_index = core::cmp::min(end_index, inner.initial_memory_regions_num as isize - 1);
- while i < end_index {
- {
- let next_base = inner.initial_memory_regions[(i + 1) as usize].base;
- let next_size = inner.initial_memory_regions[(i + 1) as usize].size;
- let next_flags = inner.initial_memory_regions[(i + 1) as usize].flags;
- let this = &mut inner.initial_memory_regions[i as usize];
- if this.base + this.size != next_base || this.flags != next_flags {
- if unlikely(this.base + this.size > next_base) {
- kBUG!("this->base + this->size > next->base");
- }
- i += 1;
- continue;
- }
- this.size += next_size;
- }
- // 移动后面的区域
- let copy_elements = inner.initial_memory_regions_num - (i + 2) as usize;
- inner.initial_memory_regions.copy_within(
- (i + 2) as usize..(i as usize + 2 + copy_elements),
- (i + 1) as usize,
- );
- inner.initial_memory_regions_num -= 1;
- end_index -= 1;
- }
- }
- /// 移除内存区域
- ///
- /// 如果移除的区域与已有区域有重叠,会将重叠的区域分割
- #[allow(dead_code)]
- pub fn remove_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
- if size == 0 {
- return Ok(());
- }
- let mut inner = self.inner.lock();
- if inner.initial_memory_regions_num == 0 {
- return Ok(());
- }
- let (start_index, end_index) = self
- .isolate_range(&mut inner, base, size)
- .expect("Failed to isolate range!");
- for i in (start_index..end_index).rev() {
- self.do_remove_region(&mut inner, i);
- }
- return Ok(());
- }
- fn do_remove_region(&self, inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, index: usize) {
- let copy_elements = inner.initial_memory_regions_num - index - 1;
- inner
- .initial_memory_regions
- .copy_within(index + 1..index + 1 + copy_elements, index);
- inner.initial_memory_regions_num -= 1;
- if inner.initial_memory_regions_num == 0 {
- inner.initial_memory_regions[0].base = PhysAddr::new(0);
- inner.initial_memory_regions[0].size = 0;
- }
- }
- /// 在一个内存块管理器中找到一个物理地址范围内的
- /// 空闲块,并隔离出所需的内存大小
- ///
- /// ## 返回值
- ///
- /// - Ok((start_index, end_index)) 表示成功找到了一个连续的内存区域来满足所需的 size。这里:
- /// - start_index 是指定的起始内存区域的索引。
- /// - end_index 是指定的结束内存区域的索引,它实际上不包含在返回的连续区域中,但它标志着下一个可能的不连续区域的开始。
- /// - Err(SystemError) 则表示没有找到足够的空间来满足请求的 size,可能是因为内存区域不足或存在其他系统错误
- fn isolate_range(
- &self,
- inner: &mut SpinLockGuard<'_, InnerMemBlockManager>,
- base: PhysAddr,
- size: usize,
- ) -> Result<(usize, usize), SystemError> {
- let end = base + size;
- let mut idx = 0;
- let mut start_index = 0;
- let mut end_index = 0;
- if size == 0 {
- return Ok((0, 0));
- }
- while idx < inner.initial_memory_regions_num {
- let range_base = inner.initial_memory_regions[idx].base;
- let range_end = range_base + inner.initial_memory_regions[idx].size;
- if range_base >= end {
- break;
- }
- if range_end <= base {
- idx = idx.checked_add(1).unwrap_or(0);
- continue;
- }
- if range_base < base {
- // regions[idx] intersects from below
- inner.initial_memory_regions[idx].base = base;
- inner.initial_memory_regions[idx].size -= base - range_base;
- self.do_insert_area(
- inner,
- idx,
- range_base,
- base - range_base,
- inner.initial_memory_regions[idx].flags,
- );
- } else if range_end > end {
- // regions[idx] intersects from above
- inner.initial_memory_regions[idx].base = end;
- inner.initial_memory_regions[idx].size -= end - range_base;
- self.do_insert_area(
- inner,
- idx,
- range_base,
- end - range_base,
- inner.initial_memory_regions[idx].flags,
- );
- if idx == 0 {
- idx = usize::MAX;
- } else {
- idx -= 1;
- }
- } else {
- // regions[idx] is inside the range, record it
- if end_index == 0 {
- start_index = idx;
- }
- end_index = idx + 1;
- }
- idx = idx.checked_add(1).unwrap_or(0);
- }
- return Ok((start_index, end_index));
- }
- /// mark_nomap - 用`MemoryAreaAttr::NOMAP`标志标记内存区域
- ///
- /// ## 参数
- ///
- /// - base: 区域的物理基地址
- /// - size: 区域的大小
- ///
- /// 使用`MemoryAreaAttr::NOMAP`标志标记的内存区域将不会被添加到物理内存的直接映射中。这些区域仍然会被内存映射所覆盖。内存映射中代表NOMAP内存帧的struct page将被PageReserved()。
- /// 注意:如果被标记为`MemoryAreaAttr::NOMAP`的内存是从memblock分配的,调用者必须忽略该内存
- pub fn mark_nomap(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
- return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::NOMAP);
- }
- fn set_or_clear_flags(
- &self,
- mut base: PhysAddr,
- mut size: usize,
- set: bool,
- flags: MemoryAreaAttr,
- ) -> Result<(), SystemError> {
- let rsvd_base = PhysAddr::new(page_align_down(base.data()));
- size = page_align_up((size as usize) + base.data() - rsvd_base.data());
- base = rsvd_base;
- let mut inner = self.inner.lock();
- let (start_index, end_index) = self.isolate_range(&mut inner, base, size)?;
- for i in start_index..end_index {
- if set {
- inner.initial_memory_regions[i].flags |= flags;
- } else {
- inner.initial_memory_regions[i].flags &= !flags;
- }
- }
- let num = inner.initial_memory_regions_num as isize;
- self.do_merge_blocks(&mut inner, 0, num);
- return Ok(());
- }
- /// 标记内存区域为保留区域
- pub fn reserve_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
- return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::RESERVED);
- }
- /// 判断[base, base+size)与已有区域是否有重叠
- pub fn is_overlapped(&self, base: PhysAddr, size: usize) -> bool {
- let inner = self.inner.lock();
- return self.do_is_overlapped(base, size, false, &inner);
- }
- /// 判断[base, base+size)与已有Reserved区域是否有重叠
- pub fn is_overlapped_with_reserved(&self, base: PhysAddr, size: usize) -> bool {
- let inner = self.inner.lock();
- return self.do_is_overlapped(base, size, true, &inner);
- }
- fn do_is_overlapped(
- &self,
- base: PhysAddr,
- size: usize,
- require_reserved: bool,
- inner: &SpinLockGuard<'_, InnerMemBlockManager>,
- ) -> bool {
- let mut res = false;
- for i in 0..inner.initial_memory_regions_num {
- if require_reserved
- && !inner.initial_memory_regions[i]
- .flags
- .contains(MemoryAreaAttr::RESERVED)
- {
- // 忽略非保留区域
- continue;
- }
- let range_base = inner.initial_memory_regions[i].base;
- let range_end = range_base + inner.initial_memory_regions[i].size;
- if (base >= range_base && base < range_end)
- || (base + size > range_base && base + size <= range_end)
- || (base <= range_base && base + size >= range_end)
- {
- res = true;
- break;
- }
- }
- return res;
- }
- /// 生成迭代器
- pub fn to_iter(&self) -> MemBlockIter {
- let inner = self.inner.lock();
- return MemBlockIter {
- inner,
- index: 0,
- usable_only: false,
- };
- }
- /// 生成迭代器,迭代所有可用的物理内存区域
- pub fn to_iter_available(&self) -> MemBlockIter {
- let inner = self.inner.lock();
- return MemBlockIter {
- inner,
- index: 0,
- usable_only: true,
- };
- }
- /// 获取初始内存区域数量
- pub fn total_initial_memory_regions(&self) -> usize {
- let inner = self.inner.lock();
- return inner.initial_memory_regions_num;
- }
- /// 根据索引获取初始内存区域
- pub fn get_initial_memory_region(&self, index: usize) -> Option<PhysMemoryArea> {
- let inner = self.inner.lock();
- return inner.initial_memory_regions.get(index).copied();
- }
- }
- pub struct MemBlockIter<'a> {
- inner: SpinLockGuard<'a, InnerMemBlockManager>,
- index: usize,
- usable_only: bool,
- }
- #[allow(dead_code)]
- impl<'a> MemBlockIter<'a> {
- /// 获取内存区域数量
- pub fn total_num(&self) -> usize {
- self.inner.initial_memory_regions_num
- }
- /// 获取指定索引的内存区域
- pub fn get_area(&self, index: usize) -> &PhysMemoryArea {
- &self.inner.initial_memory_regions[index]
- }
- /// 获取当前索引
- pub fn current_index(&self) -> usize {
- self.index
- }
- }
- impl<'a> Iterator for MemBlockIter<'a> {
- type Item = PhysMemoryArea;
- fn next(&mut self) -> Option<Self::Item> {
- while self.index < self.inner.initial_memory_regions_num {
- if self.usable_only {
- if self.inner.initial_memory_regions[self.index]
- .flags
- .is_empty()
- == false
- {
- self.index += 1;
- if self.index >= self.inner.initial_memory_regions_num {
- return None;
- }
- continue;
- }
- }
- break;
- }
- if self.index >= self.inner.initial_memory_regions_num {
- return None;
- }
- let ret = self.inner.initial_memory_regions[self.index];
- self.index += 1;
- return Some(ret);
- }
- }
- bitflags! {
- /// 内存区域属性
- pub struct MemoryAreaAttr: u32 {
- /// No special request
- const NONE = 0x0;
- /// Hotpluggable region
- const HOTPLUG = (1 << 0);
- /// Mirrored region
- const MIRROR = (1 << 1);
- /// do not add to kenrel direct mapping
- const NOMAP = (1 << 2);
- /// Always detected via a driver
- const DRIVER_MANAGED = (1 << 3);
- /// Memory is reserved
- const RESERVED = (1 << 4);
- }
- }
|