diff --git a/blog/content/second-edition/posts/10-advanced-paging/index.md b/blog/content/second-edition/posts/10-advanced-paging/index.md index 4ae71ba7..9a914ea4 100644 --- a/blog/content/second-edition/posts/10-advanced-paging/index.md +++ b/blog/content/second-edition/posts/10-advanced-paging/index.md @@ -189,41 +189,50 @@ use x86_64::structures::paging::PageTable; /// Returns the physical address for the given virtual address, or `None` if the /// virtual address is not mapped. -/// -/// Safety: This requires level_4_table_addr to be the address of a valid -/// level-4 PageTable -pub unsafe fn translate_addr(addr: usize, level_4_table_addr: usize) -> Option { +pub fn translate_addr(addr: usize) -> Option { + // introduce variables for the recursive index and the sign extension bits + // TODO: Don't hardcode these values + let r = 0o777; // recursive index + let sign = 0o177777 << 48; // sign extension + // retrieve the page table indices of the address that we want to translate - let level_4_index = (addr >> 39) & 0o777; - let level_3_index = (addr >> 30) & 0o777; - let level_2_index = (addr >> 21) & 0o777; - let level_1_index = (addr >> 12) & 0o777; + let l4_idx = (addr >> 39) & 0o777; // level 4 index + let l3_idx = (addr >> 30) & 0o777; // level 3 index + let l2_idx = (addr >> 21) & 0o777; // level 2 index + let l1_idx = (addr >> 12) & 0o777; // level 1 index let page_offset = addr & 0o7777; + // calculate the table addresses + let level_4_table_addr = + sign | (r << 39) | (r << 30) | (r << 21) | (r << 12); + let level_3_table_addr = + sign | (r << 39) | (r << 30) | (r << 21) | (l4_idx << 12); + let level_2_table_addr = + sign | (r << 39) | (r << 30) | (l4_idx << 21) | (l3_idx << 12); + let level_1_table_addr = + sign | (r << 39) | (l4_idx << 30) | (l3_idx << 21) | (l2_idx << 12); + // check that level 4 entry is mapped - let level_4_table = unsafe {&*(level_4_table_addr as *const PageTable)}; - if level_4_table[level_4_index].addr().is_null() { + let level_4_table = unsafe { &*(level_4_table_addr as *const PageTable) }; + if level_4_table[l4_idx].addr().is_null() { return None; } - let level_3_table_addr = (level_4_table_addr << 9) | (level_4_index << 12); // check that level 3 entry is mapped - let level_3_table = unsafe {&*(level_3_table_addr as *const PageTable)}; - if level_3_table[level_3_index].addr().is_null() { + let level_3_table = unsafe { &*(level_3_table_addr as *const PageTable) }; + if level_3_table[l3_idx].addr().is_null() { return None; } - let level_2_table_addr = (level_3_table_addr << 9) | (level_3_index << 12); // check that level 2 entry is mapped - let level_2_table = unsafe {&*(level_2_table_addr as *const PageTable)}; - if level_2_table[level_2_index].addr().is_null() { + let level_2_table = unsafe { &*(level_2_table_addr as *const PageTable) }; + if level_2_table[l2_idx].addr().is_null() { return None; } - let level_1_table_addr = (level_2_table_addr << 9) | (level_2_index << 12); // check that level 1 entry is mapped and retrieve physical address from it - let level_1_table = unsafe {&*(level_1_table_addr as *const PageTable)}; - let phys_addr = level_1_table[level_1_index].addr(); + let level_1_table = unsafe { &*(level_1_table_addr as *const PageTable) }; + let phys_addr = level_1_table[l1_idx].addr(); if phys_addr.is_null() { return None; } @@ -232,17 +241,16 @@ pub unsafe fn translate_addr(addr: usize, level_4_table_addr: usize) -> Option

! { use blog_os::memory::translate_addr; - const LEVEL_4_TABLE_ADDR: usize = 0o_177777_777_777_777_777_0000; + // the identity-mapped vga buffer page + println!("0xb8000 -> {:?}", translate_addr(0xb8000)); + // some code page + println!("0x20010a -> {:?}", translate_addr(0x20010a)); + // some stack page + println!("0x57ac001ffe48 -> {:?}", translate_addr(0x57ac001ffe48)); - unsafe { - // the identity-mapped vga buffer page - println!("0xb8000 -> {:?}", translate_addr(0xb8000, LEVEL_4_TABLE_ADDR)); - // some code page - println!("0x20010a -> {:?}", translate_addr(0x20010a, LEVEL_4_TABLE_ADDR)); - // some stack page - println!("0x57ac001ffe48 -> {:?}", translate_addr(0x57ac001ffe48, - LEVEL_4_TABLE_ADDR)); - } println!("It did not crash!"); blog_os::hlt_loop();