Allow thread control block to be moved

This commit is contained in:
Jeremy Soller 2016-09-11 18:25:05 -06:00
parent f0431f4de1
commit bed09d0518
2 changed files with 13 additions and 15 deletions

View file

@ -1,6 +1,7 @@
//! # Paging //! # Paging
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html) //! 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 core::ops::{Deref, DerefMut};
use x86::{msr, tlb}; use x86::{msr, tlb};
@ -22,7 +23,9 @@ pub const ENTRY_COUNT: usize = 512;
pub const PAGE_SIZE: usize = 4096; pub const PAGE_SIZE: usize = 4096;
/// Initialize paging /// 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 { extern {
/// The starting byte of the text (code) data segment. /// The starting byte of the text (code) data segment.
static mut __text_start: u8; static mut __text_start: u8;
@ -145,9 +148,11 @@ pub unsafe fn init(stack_start: usize, stack_end: usize) -> ActivePageTable {
} }
// Map and clear TBSS // Map and clear TBSS
let tcb_offset;
{ {
let start = & __tbss_start as *const _ as usize; let start = & __tbss_start as *const _ as usize;
let end = & __tbss_end as *const _ as usize; let end = & __tbss_end as *const _ as usize;
tcb_offset = end - mem::size_of::<usize>();
if end > start { if end > start {
let start_page = Page::containing_address(VirtualAddress::new(start)); let start_page = Page::containing_address(VirtualAddress::new(start));
let end_page = Page::containing_address(VirtualAddress::new(end - 1)); 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); ::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.flush_all();
active_table (active_table, tcb_offset)
} }
pub struct ActivePageTable { pub struct ActivePageTable {
@ -217,7 +222,7 @@ impl ActivePageTable {
where F: FnOnce(&mut Mapper) where F: FnOnce(&mut Mapper)
{ {
use x86::controlregs; use x86::controlregs;
{ {
let backup = Frame::containing_address(PhysicalAddress::new(unsafe { controlregs::cr3() } as usize)); let backup = Frame::containing_address(PhysicalAddress::new(unsafe { controlregs::cr3() } as usize));

View file

@ -47,8 +47,6 @@ pub unsafe extern fn kstart() -> ! {
static mut __bss_start: u8; static mut __bss_start: u8;
/// The ending byte of the _.bss_ (uninitialized data) segment. /// The ending byte of the _.bss_ (uninitialized data) segment.
static mut __bss_end: u8; static mut __bss_end: u8;
/// The end of the tbss.
static mut __tbss_end: u8;
/// The end of the kernel /// The end of the kernel
static mut __end: u8; static mut __end: u8;
} }
@ -75,10 +73,10 @@ pub unsafe extern fn kstart() -> ! {
let stack_end = 0x0009F000; let stack_end = 0x0009F000;
// Initialize paging // 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 // 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 // Set up IDT
idt::init(); idt::init();
@ -140,19 +138,14 @@ pub unsafe extern fn kstart() -> ! {
/// Entry to rust for an AP /// Entry to rust for an AP
pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { 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!(BSS_TEST_ZERO, 0);
assert_eq!(DATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF); assert_eq!(DATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF);
// Initialize paging // 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 // 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 // Set up IDT for AP
idt::init(); idt::init();