Allow thread control block to be moved
This commit is contained in:
parent
f0431f4de1
commit
bed09d0518
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue