1 use core::intrinsics::unlikely; 2 3 use system_error::SystemError; 4 5 use crate::libs::{ 6 align::{page_align_down, page_align_up}, 7 spinlock::{SpinLock, SpinLockGuard}, 8 }; 9 10 use super::{PhysAddr, PhysMemoryArea}; 11 12 pub const INITIAL_MEMORY_REGIONS_NUM: usize = 128; 13 14 /// 初始内存区域 15 static MEM_BLOCK_MANAGER: MemBlockManager = MemBlockManager::new(); 16 17 #[inline(always)] 18 pub fn mem_block_manager() -> &'static MemBlockManager { 19 &MEM_BLOCK_MANAGER 20 } 21 22 /// 内存区域管理器 23 #[derive(Debug)] 24 pub struct MemBlockManager { 25 inner: SpinLock<InnerMemBlockManager>, 26 } 27 28 #[derive(Debug)] 29 pub struct InnerMemBlockManager { 30 /// 初始内存区域 31 /// 32 /// 用于记录内核启动时的内存布局, 这些区域保持升序、不重叠 33 initial_memory_regions: [PhysMemoryArea; INITIAL_MEMORY_REGIONS_NUM], 34 initial_memory_regions_num: usize, 35 } 36 37 impl MemBlockManager { 38 #[allow(dead_code)] 39 pub const MIN_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(0); 40 #[allow(dead_code)] 41 pub const MAX_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(usize::MAX); 42 const fn new() -> Self { 43 Self { 44 inner: SpinLock::new(InnerMemBlockManager { 45 initial_memory_regions: [PhysMemoryArea::DEFAULT; INITIAL_MEMORY_REGIONS_NUM], 46 initial_memory_regions_num: 0, 47 }), 48 } 49 } 50 51 /// 添加内存区域 52 /// 53 /// 如果添加的区域与已有区域有重叠,会将重叠的区域合并 54 #[allow(dead_code)] 55 pub fn add_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> { 56 let r = self.add_range(base, size, MemoryAreaAttr::empty()); 57 return r; 58 } 59 60 /// 添加内存区域 61 /// 62 /// 如果添加的区域与已有区域有重叠,会将重叠的区域合并 63 fn add_range( 64 &self, 65 base: PhysAddr, 66 size: usize, 67 flags: MemoryAreaAttr, 68 ) -> Result<(), SystemError> { 69 if size == 0 { 70 return Ok(()); 71 } 72 let mut inner = self.inner.lock(); 73 if inner.initial_memory_regions_num >= INITIAL_MEMORY_REGIONS_NUM { 74 panic!("Too many memory regions!"); 75 } 76 77 let block = PhysMemoryArea::new(base, size, MemoryAreaAttr::empty()); 78 // 特判第一个区域 79 if inner.initial_memory_regions_num == 0 { 80 inner.initial_memory_regions[0] = block; 81 inner.initial_memory_regions_num += 1; 82 return Ok(()); 83 } 84 85 // 先计算需要添加的区域数量 86 let blocks_to_add = self 87 .do_add_block(&mut inner, block, false, flags) 88 .expect("Failed to count blocks to add!"); 89 90 if inner.initial_memory_regions_num + blocks_to_add > INITIAL_MEMORY_REGIONS_NUM { 91 kerror!("Too many memory regions!"); 92 return Err(SystemError::ENOMEM); 93 } 94 95 // 然后添加区域 96 self.do_add_block(&mut inner, block, true, flags) 97 .expect("Failed to add block!"); 98 99 return Ok(()); 100 } 101 102 fn do_add_block( 103 &self, 104 inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, 105 block: PhysMemoryArea, 106 insert: bool, 107 flags: MemoryAreaAttr, 108 ) -> Result<usize, SystemError> { 109 let mut base = block.base; 110 let end = block.base + block.size; 111 let mut i = 0; 112 let mut start_index = -1; 113 let mut end_index = -1; 114 115 let mut num_to_add = 0; 116 117 while i < inner.initial_memory_regions_num { 118 let range_base = inner.initial_memory_regions[i].base; 119 let range_end = 120 inner.initial_memory_regions[i].base + inner.initial_memory_regions[i].size; 121 122 if range_base >= end { 123 break; 124 } 125 if range_end <= base { 126 i += 1; 127 continue; 128 } 129 130 // 有重叠 131 132 if range_base > base { 133 num_to_add += 1; 134 if insert { 135 if start_index == -1 { 136 start_index = i as isize; 137 } 138 end_index = (i + 1) as isize; 139 self.do_insert_area(inner, i, base, range_base - base, flags); 140 i += 1; 141 } 142 } 143 144 i += 1; 145 base = core::cmp::min(range_end, end); 146 } 147 148 if base < end { 149 num_to_add += 1; 150 if insert { 151 if start_index == -1 { 152 start_index = i as isize; 153 } 154 end_index = (i + 1) as isize; 155 self.do_insert_area(inner, i, base, end - base, flags); 156 } 157 } 158 159 if num_to_add == 0 { 160 return Ok(0); 161 } 162 163 if insert { 164 self.do_merge_blocks(inner, start_index, end_index); 165 } 166 return Ok(num_to_add); 167 } 168 169 fn do_insert_area( 170 &self, 171 inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, 172 index: usize, 173 base: PhysAddr, 174 size: usize, 175 flags: MemoryAreaAttr, 176 ) { 177 let copy_elements = inner.initial_memory_regions_num - index; 178 inner 179 .initial_memory_regions 180 .copy_within(index..index + copy_elements, index + 1); 181 inner.initial_memory_regions[index] = PhysMemoryArea::new(base, size, flags); 182 inner.initial_memory_regions_num += 1; 183 } 184 185 fn do_merge_blocks( 186 &self, 187 inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, 188 start_index: isize, 189 mut end_index: isize, 190 ) { 191 let mut i = 0; 192 if start_index > 0 { 193 i = start_index - 1; 194 } 195 end_index = core::cmp::min(end_index, inner.initial_memory_regions_num as isize - 1); 196 197 while i < end_index { 198 { 199 let next_base = inner.initial_memory_regions[(i + 1) as usize].base; 200 let next_size = inner.initial_memory_regions[(i + 1) as usize].size; 201 let next_flags = inner.initial_memory_regions[(i + 1) as usize].flags; 202 let this = &mut inner.initial_memory_regions[i as usize]; 203 204 if this.base + this.size != next_base || this.flags != next_flags { 205 if unlikely(this.base + this.size > next_base) { 206 kBUG!("this->base + this->size > next->base"); 207 } 208 i += 1; 209 continue; 210 } 211 this.size += next_size; 212 } 213 // 移动后面的区域 214 let copy_elements = inner.initial_memory_regions_num - (i + 2) as usize; 215 inner.initial_memory_regions.copy_within( 216 (i + 2) as usize..(i as usize + 2 + copy_elements), 217 (i + 1) as usize, 218 ); 219 220 inner.initial_memory_regions_num -= 1; 221 end_index -= 1; 222 } 223 } 224 225 /// 移除内存区域 226 /// 227 /// 如果移除的区域与已有区域有重叠,会将重叠的区域分割 228 #[allow(dead_code)] 229 pub fn remove_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> { 230 if size == 0 { 231 return Ok(()); 232 } 233 let mut inner = self.inner.lock(); 234 if inner.initial_memory_regions_num == 0 { 235 return Ok(()); 236 } 237 238 let (start_index, end_index) = self 239 .isolate_range(&mut inner, base, size) 240 .expect("Failed to isolate range!"); 241 242 for i in (start_index..end_index).rev() { 243 self.do_remove_region(&mut inner, i); 244 } 245 return Ok(()); 246 } 247 248 fn do_remove_region(&self, inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, index: usize) { 249 let copy_elements = inner.initial_memory_regions_num - index - 1; 250 inner 251 .initial_memory_regions 252 .copy_within(index + 1..index + 1 + copy_elements, index); 253 254 inner.initial_memory_regions_num -= 1; 255 256 if inner.initial_memory_regions_num == 0 { 257 inner.initial_memory_regions[0].base = PhysAddr::new(0); 258 inner.initial_memory_regions[0].size = 0; 259 } 260 } 261 262 /// 在一个内存块管理器中找到一个物理地址范围内的 263 /// 空闲块,并隔离出所需的内存大小 264 /// 265 /// ## 返回值 266 /// 267 /// - Ok((start_index, end_index)) 表示成功找到了一个连续的内存区域来满足所需的 size。这里: 268 /// - start_index 是指定的起始内存区域的索引。 269 /// - end_index 是指定的结束内存区域的索引,它实际上不包含在返回的连续区域中,但它标志着下一个可能的不连续区域的开始。 270 /// - Err(SystemError) 则表示没有找到足够的空间来满足请求的 size,可能是因为内存区域不足或存在其他系统错误 271 fn isolate_range( 272 &self, 273 inner: &mut SpinLockGuard<'_, InnerMemBlockManager>, 274 base: PhysAddr, 275 size: usize, 276 ) -> Result<(usize, usize), SystemError> { 277 let end = base + size; 278 279 let mut idx = 0; 280 281 let mut start_index = 0; 282 let mut end_index = 0; 283 284 if size == 0 { 285 return Ok((0, 0)); 286 } 287 288 while idx < inner.initial_memory_regions_num { 289 let range_base = inner.initial_memory_regions[idx].base; 290 let range_end = range_base + inner.initial_memory_regions[idx].size; 291 292 if range_base >= end { 293 break; 294 } 295 if range_end <= base { 296 idx = idx.checked_add(1).unwrap_or(0); 297 continue; 298 } 299 300 if range_base < base { 301 // regions[idx] intersects from below 302 inner.initial_memory_regions[idx].base = base; 303 inner.initial_memory_regions[idx].size -= base - range_base; 304 self.do_insert_area( 305 inner, 306 idx, 307 range_base, 308 base - range_base, 309 inner.initial_memory_regions[idx].flags, 310 ); 311 } else if range_end > end { 312 // regions[idx] intersects from above 313 inner.initial_memory_regions[idx].base = end; 314 inner.initial_memory_regions[idx].size -= end - range_base; 315 316 self.do_insert_area( 317 inner, 318 idx, 319 range_base, 320 end - range_base, 321 inner.initial_memory_regions[idx].flags, 322 ); 323 if idx == 0 { 324 idx = usize::MAX; 325 } else { 326 idx -= 1; 327 } 328 } else { 329 // regions[idx] is inside the range, record it 330 if end_index == 0 { 331 start_index = idx; 332 } 333 end_index = idx + 1; 334 } 335 336 idx = idx.checked_add(1).unwrap_or(0); 337 } 338 339 return Ok((start_index, end_index)); 340 } 341 342 /// mark_nomap - 用`MemoryAreaAttr::NOMAP`标志标记内存区域 343 /// 344 /// ## 参数 345 /// 346 /// - base: 区域的物理基地址 347 /// - size: 区域的大小 348 /// 349 /// 使用`MemoryAreaAttr::NOMAP`标志标记的内存区域将不会被添加到物理内存的直接映射中。这些区域仍然会被内存映射所覆盖。内存映射中代表NOMAP内存帧的struct page将被PageReserved()。 350 /// 注意:如果被标记为`MemoryAreaAttr::NOMAP`的内存是从memblock分配的,调用者必须忽略该内存 351 pub fn mark_nomap(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> { 352 return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::NOMAP); 353 } 354 355 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/mm/memblock.c?fi=memblock_mark_mirror#940 356 pub fn mark_mirror(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> { 357 return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::MIRROR); 358 } 359 360 fn set_or_clear_flags( 361 &self, 362 mut base: PhysAddr, 363 mut size: usize, 364 set: bool, 365 flags: MemoryAreaAttr, 366 ) -> Result<(), SystemError> { 367 let rsvd_base = PhysAddr::new(page_align_down(base.data())); 368 size = page_align_up(size + base.data() - rsvd_base.data()); 369 base = rsvd_base; 370 371 let mut inner = self.inner.lock(); 372 let (start_index, end_index) = self.isolate_range(&mut inner, base, size)?; 373 for i in start_index..end_index { 374 if set { 375 inner.initial_memory_regions[i].flags |= flags; 376 } else { 377 inner.initial_memory_regions[i].flags &= !flags; 378 } 379 } 380 381 let num = inner.initial_memory_regions_num as isize; 382 self.do_merge_blocks(&mut inner, 0, num); 383 return Ok(()); 384 } 385 386 /// 标记内存区域为保留区域 387 pub fn reserve_block(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> { 388 return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::RESERVED); 389 } 390 391 /// 判断[base, base+size)与已有区域是否有重叠 392 pub fn is_overlapped(&self, base: PhysAddr, size: usize) -> bool { 393 let inner = self.inner.lock(); 394 return self.do_is_overlapped(base, size, false, &inner); 395 } 396 397 /// 判断[base, base+size)与已有Reserved区域是否有重叠 398 pub fn is_overlapped_with_reserved(&self, base: PhysAddr, size: usize) -> bool { 399 let inner = self.inner.lock(); 400 return self.do_is_overlapped(base, size, true, &inner); 401 } 402 403 fn do_is_overlapped( 404 &self, 405 base: PhysAddr, 406 size: usize, 407 require_reserved: bool, 408 inner: &SpinLockGuard<'_, InnerMemBlockManager>, 409 ) -> bool { 410 let mut res = false; 411 for i in 0..inner.initial_memory_regions_num { 412 if require_reserved 413 && !inner.initial_memory_regions[i] 414 .flags 415 .contains(MemoryAreaAttr::RESERVED) 416 { 417 // 忽略非保留区域 418 continue; 419 } 420 421 let range_base = inner.initial_memory_regions[i].base; 422 let range_end = range_base + inner.initial_memory_regions[i].size; 423 if (base >= range_base && base < range_end) 424 || (base + size > range_base && base + size <= range_end) 425 || (base <= range_base && base + size >= range_end) 426 { 427 res = true; 428 break; 429 } 430 } 431 432 return res; 433 } 434 435 /// 生成迭代器 436 pub fn to_iter(&self) -> MemBlockIter { 437 let inner = self.inner.lock(); 438 return MemBlockIter { 439 inner, 440 index: 0, 441 usable_only: false, 442 }; 443 } 444 445 /// 生成迭代器,迭代所有可用的物理内存区域 446 pub fn to_iter_available(&self) -> MemBlockIter { 447 let inner = self.inner.lock(); 448 return MemBlockIter { 449 inner, 450 index: 0, 451 usable_only: true, 452 }; 453 } 454 455 /// 获取初始内存区域数量 456 pub fn total_initial_memory_regions(&self) -> usize { 457 let inner = self.inner.lock(); 458 return inner.initial_memory_regions_num; 459 } 460 461 /// 根据索引获取初始内存区域 462 pub fn get_initial_memory_region(&self, index: usize) -> Option<PhysMemoryArea> { 463 let inner = self.inner.lock(); 464 return inner.initial_memory_regions.get(index).copied(); 465 } 466 } 467 468 pub struct MemBlockIter<'a> { 469 inner: SpinLockGuard<'a, InnerMemBlockManager>, 470 index: usize, 471 usable_only: bool, 472 } 473 474 #[allow(dead_code)] 475 impl<'a> MemBlockIter<'a> { 476 /// 获取内存区域数量 477 pub fn total_num(&self) -> usize { 478 self.inner.initial_memory_regions_num 479 } 480 481 /// 获取指定索引的内存区域 482 pub fn get_area(&self, index: usize) -> &PhysMemoryArea { 483 &self.inner.initial_memory_regions[index] 484 } 485 486 /// 获取当前索引 487 pub fn current_index(&self) -> usize { 488 self.index 489 } 490 } 491 492 impl<'a> Iterator for MemBlockIter<'a> { 493 type Item = PhysMemoryArea; 494 495 fn next(&mut self) -> Option<Self::Item> { 496 while self.index < self.inner.initial_memory_regions_num { 497 if self.usable_only 498 && !self.inner.initial_memory_regions[self.index] 499 .flags 500 .is_empty() 501 { 502 self.index += 1; 503 if self.index >= self.inner.initial_memory_regions_num { 504 return None; 505 } 506 continue; 507 } 508 break; 509 } 510 if self.index >= self.inner.initial_memory_regions_num { 511 return None; 512 } 513 let ret = self.inner.initial_memory_regions[self.index]; 514 self.index += 1; 515 return Some(ret); 516 } 517 } 518 519 bitflags! { 520 /// 内存区域属性 521 #[allow(clippy::bad_bit_mask)] 522 pub struct MemoryAreaAttr: u32 { 523 /// No special request 524 const NONE = 0x0; 525 /// Hotpluggable region 526 const HOTPLUG = (1 << 0); 527 /// Mirrored region 528 const MIRROR = (1 << 1); 529 /// do not add to kenrel direct mapping 530 const NOMAP = (1 << 2); 531 /// Always detected via a driver 532 const DRIVER_MANAGED = (1 << 3); 533 /// Memory is reserved 534 const RESERVED = (1 << 4); 535 } 536 } 537