Format using rustfmt-nightly

This commit is contained in:
Philipp Oppermann
2017-06-20 17:55:33 +02:00
parent ff8e8e0f8b
commit 559a90ad8b
10 changed files with 168 additions and 111 deletions

View File

@@ -43,12 +43,14 @@ pub fn init(memory_controller: &mut MemoryController) {
use x86_64::instructions::tables::load_tss; use x86_64::instructions::tables::load_tss;
use x86_64::VirtualAddress; use x86_64::VirtualAddress;
let double_fault_stack = let double_fault_stack = memory_controller
memory_controller.alloc_stack(1).expect("could not allocate double fault stack"); .alloc_stack(1)
.expect("could not allocate double fault stack");
let tss = TSS.call_once(|| { let tss = TSS.call_once(|| {
let mut tss = TaskStateSegment::new(); let mut tss = TaskStateSegment::new();
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX] = VirtualAddress(double_fault_stack.top()); tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX] =
VirtualAddress(double_fault_stack.top());
tss tss
}); });
@@ -78,29 +80,41 @@ extern "x86-interrupt" fn divide_by_zero_handler(stack_frame: &mut ExceptionStac
} }
extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut ExceptionStackFrame) { extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut ExceptionStackFrame) {
println!("\nEXCEPTION: BREAKPOINT at {:#x}\n{:#?}", println!(
"\nEXCEPTION: BREAKPOINT at {:#x}\n{:#?}",
stack_frame.instruction_pointer, stack_frame.instruction_pointer,
stack_frame); stack_frame
);
} }
extern "x86-interrupt" fn invalid_opcode_handler(stack_frame: &mut ExceptionStackFrame) { extern "x86-interrupt" fn invalid_opcode_handler(stack_frame: &mut ExceptionStackFrame) {
println!("\nEXCEPTION: INVALID OPCODE at {:#x}\n{:#?}", println!(
"\nEXCEPTION: INVALID OPCODE at {:#x}\n{:#?}",
stack_frame.instruction_pointer, stack_frame.instruction_pointer,
stack_frame); stack_frame
);
loop {} loop {}
} }
extern "x86-interrupt" fn page_fault_handler(stack_frame: &mut ExceptionStackFrame, error_code: PageFaultErrorCode) { extern "x86-interrupt" fn page_fault_handler(
stack_frame: &mut ExceptionStackFrame,
error_code: PageFaultErrorCode,
) {
use x86_64::registers::control_regs; use x86_64::registers::control_regs;
println!("\nEXCEPTION: PAGE FAULT while accessing {:#x}\nerror code: \ println!(
"\nEXCEPTION: PAGE FAULT while accessing {:#x}\nerror code: \
{:?}\n{:#?}", {:?}\n{:#?}",
control_regs::cr2(), control_regs::cr2(),
error_code, error_code,
stack_frame); stack_frame
);
loop {} loop {}
} }
extern "x86-interrupt" fn double_fault_handler(stack_frame: &mut ExceptionStackFrame, _error_code: u64) { extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut ExceptionStackFrame,
_error_code: u64,
) {
println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
loop {} loop {}
} }

View File

@@ -26,12 +26,13 @@ pub struct AreaFrameAllocator {
} }
impl AreaFrameAllocator { impl AreaFrameAllocator {
pub fn new(kernel_start: usize, pub fn new(
kernel_start: usize,
kernel_end: usize, kernel_end: usize,
multiboot_start: usize, multiboot_start: usize,
multiboot_end: usize, multiboot_end: usize,
memory_areas: MemoryAreaIter) memory_areas: MemoryAreaIter,
-> AreaFrameAllocator { ) -> AreaFrameAllocator {
let mut allocator = AreaFrameAllocator { let mut allocator = AreaFrameAllocator {
next_free_frame: Frame::containing_address(0), next_free_frame: Frame::containing_address(0),
current_area: None, current_area: None,

View File

@@ -23,31 +23,41 @@ pub fn init(boot_info: &BootInformation) -> MemoryController {
assert_has_not_been_called!("memory::init must be called only once"); assert_has_not_been_called!("memory::init must be called only once");
let memory_map_tag = boot_info.memory_map_tag().expect("Memory map tag required"); let memory_map_tag = boot_info.memory_map_tag().expect("Memory map tag required");
let elf_sections_tag = boot_info.elf_sections_tag().expect("Elf sections tag required"); let elf_sections_tag = boot_info
.elf_sections_tag()
.expect("Elf sections tag required");
let kernel_start = elf_sections_tag.sections() let kernel_start = elf_sections_tag
.sections()
.filter(|s| s.is_allocated()) .filter(|s| s.is_allocated())
.map(|s| s.addr) .map(|s| s.addr)
.min() .min()
.unwrap(); .unwrap();
let kernel_end = elf_sections_tag.sections() let kernel_end = elf_sections_tag
.sections()
.filter(|s| s.is_allocated()) .filter(|s| s.is_allocated())
.map(|s| s.addr + s.size) .map(|s| s.addr + s.size)
.max() .max()
.unwrap(); .unwrap();
println!("kernel start: {:#x}, kernel end: {:#x}", println!(
"kernel start: {:#x}, kernel end: {:#x}",
kernel_start, kernel_start,
kernel_end); kernel_end
println!("multiboot start: {:#x}, multiboot end: {:#x}", );
println!(
"multiboot start: {:#x}, multiboot end: {:#x}",
boot_info.start_address(), boot_info.start_address(),
boot_info.end_address()); boot_info.end_address()
);
let mut frame_allocator = AreaFrameAllocator::new(kernel_start as usize, let mut frame_allocator = AreaFrameAllocator::new(
kernel_start as usize,
kernel_end as usize, kernel_end as usize,
boot_info.start_address(), boot_info.start_address(),
boot_info.end_address(), boot_info.end_address(),
memory_map_tag.memory_areas()); memory_map_tag.memory_areas(),
);
let mut active_table = paging::remap_the_kernel(&mut frame_allocator, boot_info); let mut active_table = paging::remap_the_kernel(&mut frame_allocator, boot_info);
@@ -83,9 +93,11 @@ pub struct MemoryController {
impl MemoryController { impl MemoryController {
pub fn alloc_stack(&mut self, size_in_pages: usize) -> Option<Stack> { pub fn alloc_stack(&mut self, size_in_pages: usize) -> Option<Stack> {
let &mut MemoryController { ref mut active_table, let &mut MemoryController {
ref mut active_table,
ref mut frame_allocator, ref mut frame_allocator,
ref mut stack_allocator } = self; ref mut stack_allocator,
} = self;
stack_allocator.alloc_stack(active_table, frame_allocator, size_in_pages) stack_allocator.alloc_stack(active_table, frame_allocator, size_in_pages)
} }
} }

View File

@@ -27,7 +27,9 @@ impl Entry {
pub fn pointed_frame(&self) -> Option<Frame> { pub fn pointed_frame(&self) -> Option<Frame> {
if self.flags().contains(PRESENT) { if self.flags().contains(PRESENT) {
Some(Frame::containing_address(self.0 as usize & 0x000fffff_fffff000)) Some(Frame::containing_address(
self.0 as usize & 0x000fffff_fffff000,
))
} else { } else {
None None
} }

View File

@@ -32,11 +32,8 @@ impl Mapper {
pub fn translate(&self, virtual_address: VirtualAddress) -> Option<PhysicalAddress> { pub fn translate(&self, virtual_address: VirtualAddress) -> Option<PhysicalAddress> {
let offset = virtual_address % PAGE_SIZE; let offset = virtual_address % PAGE_SIZE;
self.translate_page(Page::containing_address(virtual_address)).map(|frame| { self.translate_page(Page::containing_address(virtual_address))
frame.number * .map(|frame| frame.number * PAGE_SIZE + offset)
PAGE_SIZE +
offset
})
} }
pub fn translate_page(&self, page: Page) -> Option<Frame> { pub fn translate_page(&self, page: Page) -> Option<Frame> {
@@ -78,7 +75,8 @@ impl Mapper {
} }
pub fn map_to<A>(&mut self, page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A) pub fn map_to<A>(&mut self, page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A)
where A: FrameAllocator where
A: FrameAllocator,
{ {
let mut p3 = self.p4_mut().next_table_create(page.p4_index(), allocator); let mut p3 = self.p4_mut().next_table_create(page.p4_index(), allocator);
let mut p2 = p3.next_table_create(page.p3_index(), allocator); let mut p2 = p3.next_table_create(page.p3_index(), allocator);
@@ -89,21 +87,24 @@ impl Mapper {
} }
pub fn map<A>(&mut self, page: Page, flags: EntryFlags, allocator: &mut A) pub fn map<A>(&mut self, page: Page, flags: EntryFlags, allocator: &mut A)
where A: FrameAllocator where
A: FrameAllocator,
{ {
let frame = allocator.allocate_frame().expect("out of memory"); let frame = allocator.allocate_frame().expect("out of memory");
self.map_to(page, frame, flags, allocator) self.map_to(page, frame, flags, allocator)
} }
pub fn identity_map<A>(&mut self, frame: Frame, flags: EntryFlags, allocator: &mut A) pub fn identity_map<A>(&mut self, frame: Frame, flags: EntryFlags, allocator: &mut A)
where A: FrameAllocator where
A: FrameAllocator,
{ {
let page = Page::containing_address(frame.start_address()); let page = Page::containing_address(frame.start_address());
self.map_to(page, frame, flags, allocator) self.map_to(page, frame, flags, allocator)
} }
pub fn unmap<A>(&mut self, page: Page, allocator: &mut A) pub fn unmap<A>(&mut self, page: Page, allocator: &mut A)
where A: FrameAllocator where
A: FrameAllocator,
{ {
use x86_64::VirtualAddress; use x86_64::VirtualAddress;
use x86_64::instructions::tlb; use x86_64::instructions::tlb;

View File

@@ -31,9 +31,11 @@ pub struct Page {
impl Page { impl Page {
pub fn containing_address(address: VirtualAddress) -> Page { pub fn containing_address(address: VirtualAddress) -> Page {
assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000, assert!(
address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
"invalid address: 0x{:x}", "invalid address: 0x{:x}",
address); address
);
Page { number: address / PAGE_SIZE } Page { number: address / PAGE_SIZE }
} }
@@ -113,11 +115,13 @@ impl ActivePageTable {
ActivePageTable { mapper: Mapper::new() } ActivePageTable { mapper: Mapper::new() }
} }
pub fn with<F>(&mut self, pub fn with<F>(
&mut self,
table: &mut InactivePageTable, table: &mut InactivePageTable,
temporary_page: &mut temporary_page::TemporaryPage, // new temporary_page: &mut temporary_page::TemporaryPage, // new
f: F) f: F,
where F: FnOnce(&mut Mapper) ) where
F: FnOnce(&mut Mapper),
{ {
use x86_64::registers::control_regs; use x86_64::registers::control_regs;
use x86_64::instructions::tlb; use x86_64::instructions::tlb;
@@ -162,10 +166,11 @@ pub struct InactivePageTable {
} }
impl InactivePageTable { impl InactivePageTable {
pub fn new(frame: Frame, pub fn new(
frame: Frame,
active_table: &mut ActivePageTable, active_table: &mut ActivePageTable,
temporary_page: &mut TemporaryPage) temporary_page: &mut TemporaryPage,
-> InactivePageTable { ) -> InactivePageTable {
{ {
let table = temporary_page.map_table_frame(frame.clone(), active_table); let table = temporary_page.map_table_frame(frame.clone(), active_table);
table.zero(); table.zero();
@@ -178,7 +183,8 @@ impl InactivePageTable {
} }
pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation) -> ActivePageTable pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation) -> ActivePageTable
where A: FrameAllocator where
A: FrameAllocator,
{ {
let mut temporary_page = TemporaryPage::new(Page { number: 0xcafebabe }, allocator); let mut temporary_page = TemporaryPage::new(Page { number: 0xcafebabe }, allocator);
@@ -189,7 +195,9 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation) -> Ac
}; };
active_table.with(&mut new_table, &mut temporary_page, |mapper| { active_table.with(&mut new_table, &mut temporary_page, |mapper| {
let elf_sections_tag = boot_info.elf_sections_tag().expect("Memory map tag required"); let elf_sections_tag = boot_info
.elf_sections_tag()
.expect("Memory map tag required");
// identity map the allocated kernel sections // identity map the allocated kernel sections
for section in elf_sections_tag.sections() { for section in elf_sections_tag.sections() {
@@ -198,11 +206,15 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation) -> Ac
continue; continue;
} }
assert!(section.addr as usize % PAGE_SIZE == 0, assert!(
"sections need to be page aligned"); section.addr as usize % PAGE_SIZE == 0,
println!("mapping section at addr: {:#x}, size: {:#x}", "sections need to be page aligned"
);
println!(
"mapping section at addr: {:#x}, size: {:#x}",
section.addr, section.addr,
section.size); section.size
);
let flags = EntryFlags::from_elf_section_flags(section); let flags = EntryFlags::from_elf_section_flags(section);

View File

@@ -21,7 +21,8 @@ pub struct Table<L: TableLevel> {
} }
impl<L> Table<L> impl<L> Table<L>
where L: TableLevel where
L: TableLevel,
{ {
pub fn zero(&mut self) { pub fn zero(&mut self) {
for entry in self.entries.iter_mut() { for entry in self.entries.iter_mut() {
@@ -31,7 +32,8 @@ impl<L> Table<L>
} }
impl<L> Table<L> impl<L> Table<L>
where L: HierarchicalLevel where
L: HierarchicalLevel,
{ {
fn next_table_address(&self, index: usize) -> Option<usize> { fn next_table_address(&self, index: usize) -> Option<usize> {
let entry_flags = self[index].flags(); let entry_flags = self[index].flags();
@@ -44,22 +46,28 @@ impl<L> Table<L>
} }
pub fn next_table(&self, index: usize) -> Option<&Table<L::NextLevel>> { pub fn next_table(&self, index: usize) -> Option<&Table<L::NextLevel>> {
self.next_table_address(index).map(|address| unsafe { &*(address as *const _) }) self.next_table_address(index)
.map(|address| unsafe { &*(address as *const _) })
} }
pub fn next_table_mut(&mut self, index: usize) -> Option<&mut Table<L::NextLevel>> { pub fn next_table_mut(&mut self, index: usize) -> Option<&mut Table<L::NextLevel>> {
self.next_table_address(index).map(|address| unsafe { &mut *(address as *mut _) }) self.next_table_address(index)
.map(|address| unsafe { &mut *(address as *mut _) })
} }
pub fn next_table_create<A>(&mut self, pub fn next_table_create<A>(
&mut self,
index: usize, index: usize,
allocator: &mut A) allocator: &mut A,
-> &mut Table<L::NextLevel> ) -> &mut Table<L::NextLevel>
where A: FrameAllocator where
A: FrameAllocator,
{ {
if self.next_table(index).is_none() { if self.next_table(index).is_none() {
assert!(!self.entries[index].flags().contains(HUGE_PAGE), assert!(
"mapping code does not support huge pages"); !self.entries[index].flags().contains(HUGE_PAGE),
"mapping code does not support huge pages"
);
let frame = allocator.allocate_frame().expect("no frames available"); let frame = allocator.allocate_frame().expect("no frames available");
self.entries[index].set(frame, PRESENT | WRITABLE); self.entries[index].set(frame, PRESENT | WRITABLE);
self.next_table_mut(index).unwrap().zero(); self.next_table_mut(index).unwrap().zero();
@@ -69,7 +77,8 @@ impl<L> Table<L>
} }
impl<L> Index<usize> for Table<L> impl<L> Index<usize> for Table<L>
where L: TableLevel where
L: TableLevel,
{ {
type Output = Entry; type Output = Entry;
@@ -79,7 +88,8 @@ impl<L> Index<usize> for Table<L>
} }
impl<L> IndexMut<usize> for Table<L> impl<L> IndexMut<usize> for Table<L>
where L: TableLevel where
L: TableLevel,
{ {
fn index_mut(&mut self, index: usize) -> &mut Entry { fn index_mut(&mut self, index: usize) -> &mut Entry {
&mut self.entries[index] &mut self.entries[index]

View File

@@ -18,7 +18,8 @@ pub struct TemporaryPage {
impl TemporaryPage { impl TemporaryPage {
pub fn new<A>(page: Page, allocator: &mut A) -> TemporaryPage pub fn new<A>(page: Page, allocator: &mut A) -> TemporaryPage
where A: FrameAllocator where
A: FrameAllocator,
{ {
TemporaryPage { TemporaryPage {
page: page, page: page,
@@ -31,18 +32,21 @@ impl TemporaryPage {
pub fn map(&mut self, frame: Frame, active_table: &mut ActivePageTable) -> VirtualAddress { pub fn map(&mut self, frame: Frame, active_table: &mut ActivePageTable) -> VirtualAddress {
use super::entry::WRITABLE; use super::entry::WRITABLE;
assert!(active_table.translate_page(self.page).is_none(), assert!(
"temporary page is already mapped"); active_table.translate_page(self.page).is_none(),
"temporary page is already mapped"
);
active_table.map_to(self.page, frame, WRITABLE, &mut self.allocator); active_table.map_to(self.page, frame, WRITABLE, &mut self.allocator);
self.page.start_address() self.page.start_address()
} }
/// Maps the temporary page to the given page table frame in the active table. /// Maps the temporary page to the given page table frame in the active table.
/// Returns a reference to the now mapped table. /// Returns a reference to the now mapped table.
pub fn map_table_frame(&mut self, pub fn map_table_frame(
&mut self,
frame: Frame, frame: Frame,
active_table: &mut ActivePageTable) active_table: &mut ActivePageTable,
-> &mut Table<Level1> { ) -> &mut Table<Level1> {
unsafe { &mut *(self.map(frame, active_table) as *mut Table<Level1>) } unsafe { &mut *(self.map(frame, active_table) as *mut Table<Level1>) }
} }
@@ -56,7 +60,8 @@ struct TinyAllocator([Option<Frame>; 3]);
impl TinyAllocator { impl TinyAllocator {
fn new<A>(allocator: &mut A) -> TinyAllocator fn new<A>(allocator: &mut A) -> TinyAllocator
where A: FrameAllocator where
A: FrameAllocator,
{ {
let mut f = || allocator.allocate_frame(); let mut f = || allocator.allocate_frame();
let frames = [f(), f(), f()]; let frames = [f(), f(), f()];

View File

@@ -12,11 +12,12 @@ impl StackAllocator {
} }
impl StackAllocator { impl StackAllocator {
pub fn alloc_stack<FA: FrameAllocator>(&mut self, pub fn alloc_stack<FA: FrameAllocator>(
&mut self,
active_table: &mut ActivePageTable, active_table: &mut ActivePageTable,
frame_allocator: &mut FA, frame_allocator: &mut FA,
size_in_pages: usize) size_in_pages: usize,
-> Option<Stack> { ) -> Option<Stack> {
if size_in_pages == 0 { if size_in_pages == 0 {
return None; /* a zero sized stack makes no sense */ return None; /* a zero sized stack makes no sense */
} }

View File

@@ -17,8 +17,7 @@ const BUFFER_WIDTH: usize = 80;
pub static WRITER: Mutex<Writer> = Mutex::new(Writer { pub static WRITER: Mutex<Writer> = Mutex::new(Writer {
column_position: 0, column_position: 0,
color_code: ColorCode::new(Color::LightGreen, color_code: ColorCode::new(Color::LightGreen, Color::Black),
Color::Black),
buffer: unsafe { Unique::new(0xb8000 as *mut _) }, buffer: unsafe { Unique::new(0xb8000 as *mut _) },
}); });