高地址
+--------------------------------------------------+ 0xFFFFFFFF_FFFFFFFF
| |
| 高位内存区域 |
| |
+--------------------------------------------------+ 0xFFFFFFFF_FFFFF000 (usize::MAX - PAGE_SIZE + 1) |
| 跳板代码 (Trampoline Code) |
| |
+--------------------------------------------------+ 0xFFFFFFFF_FFFFF000 (TRAMPOLINE - PAGE_SIZE)
| 陷阱上下文 (Trap Context) |
| |
+--------------------------------------------------+ 0xFFFFFFFF_FFFF8000
| 应用 1 的内核栈 (8KB) |
| 底部 = 0xFFFFFFFF_FFFF6000 |
| 顶部 = 0xFFFFFFFF_FFFF8000 |
+--------------------------------------------------+ 0xFFFFFFFF_FFFF6000
| 守卫页 (4KB) |
+--------------------------------------------------+ 0xFFFFFFFF_FFFF5000
| 应用 2 的内核栈 (8KB) |
| 底部 = 0xFFFFFFFF_FFFF3000 |
| 顶部 = 0xFFFFFFFF_FFFF5000 |
+--------------------------------------------------+ 0xFFFFFFFF_FFFF3000
| 守卫页 (4KB) |
+--------------------------------------------------+ 0xFFFFFFFF_FFFF2000
低地址
上面只是一个示意图,下面用代码描述一下
全局的初始化
pub fn init() { //全局的堆空间管理, 利用一个伙伴系统,稍后我会分析一下源码 heap_allocator::init_heap(); //配置可利用总的空间,根据自己的硬件情况来配置 frame_allocator::init_frame_allocator(); //会先调用KERNEL_SPACE初始化,然后在, 设置satp 开启内存的分页 KERNEL_SPACE.exclusive_access().activate(); }
KERNEL_SPACE初始化,主要是各个段的映射, 恒等映射的方式
pub fn new_kernel() -> Self { let mut memory_set = Self::new_bare(); memory_set.map_trampoline(); memory_set.push( MapArea::new( (stext as usize).into(), (etext as usize).into(), MapType::Identical, MapPermission::R | MapPermission::X, ), None, ); memory_set.push( MapArea::new( (srodata as usize).into(), (erodata as usize).into(), MapType::Identical, MapPermission::R, ), None, ); memory_set.push( MapArea::new( (sdata as usize).into(), (edata as usize).into(), MapType::Identical, MapPermission::R | MapPermission::W, ), None, ); memory_set.push( MapArea::new( (sbss_with_stack as usize).into(), (ebss as usize).into(), MapType::Identical, MapPermission::R | MapPermission::W, ), None, ); memory_set.push( MapArea::new( (ekernel as usize).into(), MEMORY_END.into(), MapType::Identical, MapPermission::R | MapPermission::W, ), None, ); println!("mapping memory-mapped registers"); for pair in MMIO { memory_set.push( MapArea::new( (*pair).0.into(), ((*pair).0 + (*pair).1).into(), MapType::Identical, MapPermission::R | MapPermission::W, ), None, ); } memory_set }
map_trampoline 映射稍微有些特殊:
fn map_trampoline(&mut self) { self.page_table.map( VirtAddr::from(TRAMPOLINE).into(), PhysAddr::from(strampoline as usize).into(), PTEFlags::R | PTEFlags::X, ); }
TRAMPOLINE:一个虚拟地址
pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1; pub const TRAP_CONTEXT: usize = TRAMPOLINE - PAGE_SIZE;
strampoline 是内核结束之后的一个物理地址
stext = .; .text : { *(.text.entry) . = ALIGN(4K); strampoline = .; *(.text.trampoline); . = ALIGN(4K); *(.text .text.*) }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。