From bed09d05189683abedb23062d54359707adfa9ca Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 11 Sep 2016 18:25:05 -0600 Subject: [PATCH] Allow thread control block to be moved --- arch/x86_64/src/paging/mod.rs | 13 +++++++++---- arch/x86_64/src/start.rs | 15 ++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/arch/x86_64/src/paging/mod.rs b/arch/x86_64/src/paging/mod.rs index fd02184..8dc9975 100644 --- a/arch/x86_64/src/paging/mod.rs +++ b/arch/x86_64/src/paging/mod.rs @@ -1,6 +1,7 @@ //! # Paging //! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html) +use core::mem; use core::ops::{Deref, DerefMut}; use x86::{msr, tlb}; @@ -22,7 +23,9 @@ pub const ENTRY_COUNT: usize = 512; pub const PAGE_SIZE: usize = 4096; /// Initialize paging -pub unsafe fn init(stack_start: usize, stack_end: usize) -> ActivePageTable { +/// +/// Returns page table and thread control block offset +pub unsafe fn init(stack_start: usize, stack_end: usize) -> (ActivePageTable, usize) { extern { /// The starting byte of the text (code) data segment. static mut __text_start: u8; @@ -145,9 +148,11 @@ pub unsafe fn init(stack_start: usize, stack_end: usize) -> ActivePageTable { } // Map and clear TBSS + let tcb_offset; { let start = & __tbss_start as *const _ as usize; let end = & __tbss_end as *const _ as usize; + tcb_offset = end - mem::size_of::(); if end > start { let start_page = Page::containing_address(VirtualAddress::new(start)); let end_page = Page::containing_address(VirtualAddress::new(end - 1)); @@ -157,13 +162,13 @@ pub unsafe fn init(stack_start: usize, stack_end: usize) -> ActivePageTable { ::externs::memset(page.start_address().get() as *mut u8, 0, 4096); } - *(end as *mut usize).offset(-1) = end; + *(tcb_offset as *mut usize) = end; } } active_table.flush_all(); - active_table + (active_table, tcb_offset) } pub struct ActivePageTable { @@ -217,7 +222,7 @@ impl ActivePageTable { where F: FnOnce(&mut Mapper) { use x86::controlregs; - + { let backup = Frame::containing_address(PhysicalAddress::new(unsafe { controlregs::cr3() } as usize)); diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs index 566f696..72d5280 100644 --- a/arch/x86_64/src/start.rs +++ b/arch/x86_64/src/start.rs @@ -47,8 +47,6 @@ pub unsafe extern fn kstart() -> ! { static mut __bss_start: u8; /// The ending byte of the _.bss_ (uninitialized data) segment. static mut __bss_end: u8; - /// The end of the tbss. - static mut __tbss_end: u8; /// The end of the kernel static mut __end: u8; } @@ -75,10 +73,10 @@ pub unsafe extern fn kstart() -> ! { let stack_end = 0x0009F000; // Initialize paging - let mut active_table = paging::init(stack_start, stack_end); + let (mut active_table, tcb_offset) = paging::init(stack_start, stack_end); // Set up GDT - gdt::init((&__tbss_end as *const u8 as *const usize).offset(-1) as usize, stack_end); + gdt::init(tcb_offset, stack_end); // Set up IDT idt::init(); @@ -140,19 +138,14 @@ pub unsafe extern fn kstart() -> ! { /// Entry to rust for an AP pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { { - extern { - /// The end of the tbss. - static mut __tbss_end: u8; - } - assert_eq!(BSS_TEST_ZERO, 0); assert_eq!(DATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF); // Initialize paging - let mut active_table = paging::init(stack_start, stack_end); + let (mut active_table, tcb_offset) = paging::init(stack_start, stack_end); // Set up GDT for AP - gdt::init_ap((&__tbss_end as *const u8 as *const usize).offset(-1) as usize, stack_end); + gdt::init_ap(tcb_offset, stack_end); // Set up IDT for AP idt::init();