|  |  |  | @ -1,21 +1,15 @@ | 
			
		
	
		
			
				
					|  |  |  |  | use super::{PageTable, PageTableEntry, PTEFlags}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{VirtPageNum, VirtAddr, PhysPageNum, PhysAddr}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{FrameTracker, frame_alloc}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{VPNRange, StepByOne}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{frame_alloc, FrameTracker}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{PTEFlags, PageTable, PageTableEntry}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; | 
			
		
	
		
			
				
					|  |  |  |  | use super::{StepByOne, VPNRange}; | 
			
		
	
		
			
				
					|  |  |  |  | use crate::config::{MEMORY_END, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE}; | 
			
		
	
		
			
				
					|  |  |  |  | use crate::sync::UPSafeCell; | 
			
		
	
		
			
				
					|  |  |  |  | use alloc::collections::BTreeMap; | 
			
		
	
		
			
				
					|  |  |  |  | use alloc::vec::Vec; | 
			
		
	
		
			
				
					|  |  |  |  | use riscv::register::satp; | 
			
		
	
		
			
				
					|  |  |  |  | use alloc::sync::Arc; | 
			
		
	
		
			
				
					|  |  |  |  | use lazy_static::*; | 
			
		
	
		
			
				
					|  |  |  |  | use crate::sync::UPSafeCell; | 
			
		
	
		
			
				
					|  |  |  |  | use crate::config::{ | 
			
		
	
		
			
				
					|  |  |  |  |     MEMORY_END, | 
			
		
	
		
			
				
					|  |  |  |  |     PAGE_SIZE, | 
			
		
	
		
			
				
					|  |  |  |  |     TRAMPOLINE, | 
			
		
	
		
			
				
					|  |  |  |  |     TRAP_CONTEXT, | 
			
		
	
		
			
				
					|  |  |  |  |     USER_STACK_SIZE | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | use alloc::vec::Vec; | 
			
		
	
		
			
				
					|  |  |  |  | use core::arch::asm; | 
			
		
	
		
			
				
					|  |  |  |  | use lazy_static::*; | 
			
		
	
		
			
				
					|  |  |  |  | use riscv::register::satp; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | extern "C" { | 
			
		
	
		
			
				
					|  |  |  |  |     fn stext(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -31,9 +25,8 @@ extern "C" { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | lazy_static! { | 
			
		
	
		
			
				
					|  |  |  |  |     pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> = Arc::new(unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         UPSafeCell::new(MemorySet::new_kernel()) | 
			
		
	
		
			
				
					|  |  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |  |     pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> = | 
			
		
	
		
			
				
					|  |  |  |  |         Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) }); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub struct MemorySet { | 
			
		
	
	
		
			
				
					|  |  |  | @ -52,17 +45,24 @@ impl MemorySet { | 
			
		
	
		
			
				
					|  |  |  |  |         self.page_table.token() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /// Assume that no conflicts.
 | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn insert_framed_area(&mut self, start_va: VirtAddr, end_va: VirtAddr, permission: MapPermission) { | 
			
		
	
		
			
				
					|  |  |  |  |         self.push(MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |             start_va, | 
			
		
	
		
			
				
					|  |  |  |  |             end_va, | 
			
		
	
		
			
				
					|  |  |  |  |             MapType::Framed, | 
			
		
	
		
			
				
					|  |  |  |  |             permission, | 
			
		
	
		
			
				
					|  |  |  |  |         ), None); | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn insert_framed_area( | 
			
		
	
		
			
				
					|  |  |  |  |         &mut self, | 
			
		
	
		
			
				
					|  |  |  |  |         start_va: VirtAddr, | 
			
		
	
		
			
				
					|  |  |  |  |         end_va: VirtAddr, | 
			
		
	
		
			
				
					|  |  |  |  |         permission: MapPermission, | 
			
		
	
		
			
				
					|  |  |  |  |     ) { | 
			
		
	
		
			
				
					|  |  |  |  |         self.push( | 
			
		
	
		
			
				
					|  |  |  |  |             MapArea::new(start_va, end_va, MapType::Framed, permission), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) { | 
			
		
	
		
			
				
					|  |  |  |  |         if let Some((idx, area)) = self.areas.iter_mut().enumerate() | 
			
		
	
		
			
				
					|  |  |  |  |             .find(|(_, area)| area.vpn_range.get_start() == start_vpn) { | 
			
		
	
		
			
				
					|  |  |  |  |         if let Some((idx, area)) = self | 
			
		
	
		
			
				
					|  |  |  |  |             .areas | 
			
		
	
		
			
				
					|  |  |  |  |             .iter_mut() | 
			
		
	
		
			
				
					|  |  |  |  |             .enumerate() | 
			
		
	
		
			
				
					|  |  |  |  |             .find(|(_, area)| area.vpn_range.get_start() == start_vpn) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             area.unmap(&mut self.page_table); | 
			
		
	
		
			
				
					|  |  |  |  |             self.areas.remove(idx); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -91,42 +91,60 @@ impl MemorySet { | 
			
		
	
		
			
				
					|  |  |  |  |         println!(".text [{:#x}, {:#x})", stext as usize, etext as usize); | 
			
		
	
		
			
				
					|  |  |  |  |         println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize); | 
			
		
	
		
			
				
					|  |  |  |  |         println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize); | 
			
		
	
		
			
				
					|  |  |  |  |         println!(".bss [{:#x}, {:#x})", sbss_with_stack as usize, ebss as usize); | 
			
		
	
		
			
				
					|  |  |  |  |         println!( | 
			
		
	
		
			
				
					|  |  |  |  |             ".bss [{:#x}, {:#x})", | 
			
		
	
		
			
				
					|  |  |  |  |             sbss_with_stack as usize, ebss as usize | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         println!("mapping .text section"); | 
			
		
	
		
			
				
					|  |  |  |  |         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( | 
			
		
	
		
			
				
					|  |  |  |  |                 (stext as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 (etext as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 MapType::Identical, | 
			
		
	
		
			
				
					|  |  |  |  |                 MapPermission::R | MapPermission::X, | 
			
		
	
		
			
				
					|  |  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         println!("mapping .rodata section"); | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push(MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |             (srodata as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |             (erodata as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |             MapType::Identical, | 
			
		
	
		
			
				
					|  |  |  |  |             MapPermission::R, | 
			
		
	
		
			
				
					|  |  |  |  |         ), None); | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push( | 
			
		
	
		
			
				
					|  |  |  |  |             MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |                 (srodata as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 (erodata as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 MapType::Identical, | 
			
		
	
		
			
				
					|  |  |  |  |                 MapPermission::R, | 
			
		
	
		
			
				
					|  |  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         println!("mapping .data section"); | 
			
		
	
		
			
				
					|  |  |  |  |         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( | 
			
		
	
		
			
				
					|  |  |  |  |                 (sdata as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 (edata as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 MapType::Identical, | 
			
		
	
		
			
				
					|  |  |  |  |                 MapPermission::R | MapPermission::W, | 
			
		
	
		
			
				
					|  |  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         println!("mapping .bss section"); | 
			
		
	
		
			
				
					|  |  |  |  |         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( | 
			
		
	
		
			
				
					|  |  |  |  |                 (sbss_with_stack as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 (ebss as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 MapType::Identical, | 
			
		
	
		
			
				
					|  |  |  |  |                 MapPermission::R | MapPermission::W, | 
			
		
	
		
			
				
					|  |  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         println!("mapping physical memory"); | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push(MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |             (ekernel as usize).into(), | 
			
		
	
		
			
				
					|  |  |  |  |             MEMORY_END.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, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /// Include sections in elf and trampoline and TrapContext and user stack,
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -149,19 +167,20 @@ impl MemorySet { | 
			
		
	
		
			
				
					|  |  |  |  |                 let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let mut map_perm = MapPermission::U; | 
			
		
	
		
			
				
					|  |  |  |  |                 let ph_flags = ph.flags(); | 
			
		
	
		
			
				
					|  |  |  |  |                 if ph_flags.is_read() { map_perm |= MapPermission::R; } | 
			
		
	
		
			
				
					|  |  |  |  |                 if ph_flags.is_write() { map_perm |= MapPermission::W; } | 
			
		
	
		
			
				
					|  |  |  |  |                 if ph_flags.is_execute() { map_perm |= MapPermission::X; } | 
			
		
	
		
			
				
					|  |  |  |  |                 let map_area = MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |                     start_va, | 
			
		
	
		
			
				
					|  |  |  |  |                     end_va, | 
			
		
	
		
			
				
					|  |  |  |  |                     MapType::Framed, | 
			
		
	
		
			
				
					|  |  |  |  |                     map_perm, | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 if ph_flags.is_read() { | 
			
		
	
		
			
				
					|  |  |  |  |                     map_perm |= MapPermission::R; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 if ph_flags.is_write() { | 
			
		
	
		
			
				
					|  |  |  |  |                     map_perm |= MapPermission::W; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 if ph_flags.is_execute() { | 
			
		
	
		
			
				
					|  |  |  |  |                     map_perm |= MapPermission::X; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |                 let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm); | 
			
		
	
		
			
				
					|  |  |  |  |                 max_end_vpn = map_area.vpn_range.get_end(); | 
			
		
	
		
			
				
					|  |  |  |  |                 memory_set.push( | 
			
		
	
		
			
				
					|  |  |  |  |                     map_area, | 
			
		
	
		
			
				
					|  |  |  |  |                     Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]) | 
			
		
	
		
			
				
					|  |  |  |  |                     Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]), | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -171,20 +190,30 @@ impl MemorySet { | 
			
		
	
		
			
				
					|  |  |  |  |         // guard page
 | 
			
		
	
		
			
				
					|  |  |  |  |         user_stack_bottom += PAGE_SIZE; | 
			
		
	
		
			
				
					|  |  |  |  |         let user_stack_top = user_stack_bottom + USER_STACK_SIZE; | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push(MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |             user_stack_bottom.into(), | 
			
		
	
		
			
				
					|  |  |  |  |             user_stack_top.into(), | 
			
		
	
		
			
				
					|  |  |  |  |             MapType::Framed, | 
			
		
	
		
			
				
					|  |  |  |  |             MapPermission::R | MapPermission::W | MapPermission::U, | 
			
		
	
		
			
				
					|  |  |  |  |         ), None); | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push( | 
			
		
	
		
			
				
					|  |  |  |  |             MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |                 user_stack_bottom.into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 user_stack_top.into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 MapType::Framed, | 
			
		
	
		
			
				
					|  |  |  |  |                 MapPermission::R | MapPermission::W | MapPermission::U, | 
			
		
	
		
			
				
					|  |  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         // map TrapContext
 | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push(MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |             TRAP_CONTEXT.into(), | 
			
		
	
		
			
				
					|  |  |  |  |             TRAMPOLINE.into(), | 
			
		
	
		
			
				
					|  |  |  |  |             MapType::Framed, | 
			
		
	
		
			
				
					|  |  |  |  |             MapPermission::R | MapPermission::W, | 
			
		
	
		
			
				
					|  |  |  |  |         ), None); | 
			
		
	
		
			
				
					|  |  |  |  |         (memory_set, user_stack_top, elf.header.pt2.entry_point() as usize) | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set.push( | 
			
		
	
		
			
				
					|  |  |  |  |             MapArea::new( | 
			
		
	
		
			
				
					|  |  |  |  |                 TRAP_CONTEXT.into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 TRAMPOLINE.into(), | 
			
		
	
		
			
				
					|  |  |  |  |                 MapType::Framed, | 
			
		
	
		
			
				
					|  |  |  |  |                 MapPermission::R | MapPermission::W, | 
			
		
	
		
			
				
					|  |  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |  |             None, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |         ( | 
			
		
	
		
			
				
					|  |  |  |  |             memory_set, | 
			
		
	
		
			
				
					|  |  |  |  |             user_stack_top, | 
			
		
	
		
			
				
					|  |  |  |  |             elf.header.pt2.entry_point() as usize, | 
			
		
	
		
			
				
					|  |  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn from_existed_user(user_space: &MemorySet) -> MemorySet { | 
			
		
	
		
			
				
					|  |  |  |  |         let mut memory_set = Self::new_bare(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -198,7 +227,9 @@ impl MemorySet { | 
			
		
	
		
			
				
					|  |  |  |  |             for vpn in area.vpn_range { | 
			
		
	
		
			
				
					|  |  |  |  |                 let src_ppn = user_space.translate(vpn).unwrap().ppn(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let dst_ppn = memory_set.translate(vpn).unwrap().ppn(); | 
			
		
	
		
			
				
					|  |  |  |  |                 dst_ppn.get_bytes_array().copy_from_slice(src_ppn.get_bytes_array()); | 
			
		
	
		
			
				
					|  |  |  |  |                 dst_ppn | 
			
		
	
		
			
				
					|  |  |  |  |                     .get_bytes_array() | 
			
		
	
		
			
				
					|  |  |  |  |                     .copy_from_slice(src_ppn.get_bytes_array()); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         memory_set | 
			
		
	
	
		
			
				
					|  |  |  | @ -231,7 +262,7 @@ impl MapArea { | 
			
		
	
		
			
				
					|  |  |  |  |         start_va: VirtAddr, | 
			
		
	
		
			
				
					|  |  |  |  |         end_va: VirtAddr, | 
			
		
	
		
			
				
					|  |  |  |  |         map_type: MapType, | 
			
		
	
		
			
				
					|  |  |  |  |         map_perm: MapPermission | 
			
		
	
		
			
				
					|  |  |  |  |         map_perm: MapPermission, | 
			
		
	
		
			
				
					|  |  |  |  |     ) -> Self { | 
			
		
	
		
			
				
					|  |  |  |  |         let start_vpn: VirtPageNum = start_va.floor(); | 
			
		
	
		
			
				
					|  |  |  |  |         let end_vpn: VirtPageNum = end_va.ceil(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -330,15 +361,27 @@ pub fn remap_test() { | 
			
		
	
		
			
				
					|  |  |  |  |     let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into(); | 
			
		
	
		
			
				
					|  |  |  |  |     let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into(); | 
			
		
	
		
			
				
					|  |  |  |  |     assert_eq!( | 
			
		
	
		
			
				
					|  |  |  |  |         kernel_space.page_table.translate(mid_text.floor()).unwrap().writable(), | 
			
		
	
		
			
				
					|  |  |  |  |         kernel_space | 
			
		
	
		
			
				
					|  |  |  |  |             .page_table | 
			
		
	
		
			
				
					|  |  |  |  |             .translate(mid_text.floor()) | 
			
		
	
		
			
				
					|  |  |  |  |             .unwrap() | 
			
		
	
		
			
				
					|  |  |  |  |             .writable(), | 
			
		
	
		
			
				
					|  |  |  |  |         false | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  |     assert_eq!( | 
			
		
	
		
			
				
					|  |  |  |  |         kernel_space.page_table.translate(mid_rodata.floor()).unwrap().writable(), | 
			
		
	
		
			
				
					|  |  |  |  |         kernel_space | 
			
		
	
		
			
				
					|  |  |  |  |             .page_table | 
			
		
	
		
			
				
					|  |  |  |  |             .translate(mid_rodata.floor()) | 
			
		
	
		
			
				
					|  |  |  |  |             .unwrap() | 
			
		
	
		
			
				
					|  |  |  |  |             .writable(), | 
			
		
	
		
			
				
					|  |  |  |  |         false, | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  |     assert_eq!( | 
			
		
	
		
			
				
					|  |  |  |  |         kernel_space.page_table.translate(mid_data.floor()).unwrap().executable(), | 
			
		
	
		
			
				
					|  |  |  |  |         kernel_space | 
			
		
	
		
			
				
					|  |  |  |  |             .page_table | 
			
		
	
		
			
				
					|  |  |  |  |             .translate(mid_data.floor()) | 
			
		
	
		
			
				
					|  |  |  |  |             .unwrap() | 
			
		
	
		
			
				
					|  |  |  |  |             .executable(), | 
			
		
	
		
			
				
					|  |  |  |  |         false, | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  |     println!("remap_test passed!"); | 
			
		
	
	
		
			
				
					|  |  |  | 
 |