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,14 +43,16 @@ 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] =
tss VirtualAddress(double_fault_stack.top());
}); tss
});
let mut code_selector = SegmentSelector(0); let mut code_selector = SegmentSelector(0);
let mut tss_selector = SegmentSelector(0); let mut tss_selector = SegmentSelector(0);
@@ -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!(
stack_frame.instruction_pointer, "\nEXCEPTION: BREAKPOINT at {:#x}\n{:#?}",
stack_frame); stack_frame.instruction_pointer,
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!(
stack_frame.instruction_pointer, "\nEXCEPTION: INVALID OPCODE at {:#x}\n{:#?}",
stack_frame); stack_frame.instruction_pointer,
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!(
{:?}\n{:#?}", "\nEXCEPTION: PAGE FAULT while accessing {:#x}\nerror code: \
control_regs::cr2(), {:?}\n{:#?}",
error_code, control_regs::cr2(),
stack_frame); error_code,
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_end: usize, kernel_start: usize,
multiboot_start: usize, kernel_end: usize,
multiboot_end: usize, multiboot_start: usize,
memory_areas: MemoryAreaIter) multiboot_end: usize,
-> AreaFrameAllocator { memory_areas: MemoryAreaIter,
) -> 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,
@@ -49,9 +50,9 @@ impl AreaFrameAllocator {
self.current_area = self.areas self.current_area = self.areas
.clone() .clone()
.filter(|area| { .filter(|area| {
let address = area.base_addr + area.length - 1; let address = area.base_addr + area.length - 1;
Frame::containing_address(address as usize) >= self.next_free_frame Frame::containing_address(address as usize) >= self.next_free_frame
}) })
.min_by_key(|area| area.base_addr); .min_by_key(|area| area.base_addr);
if let Some(area) = self.current_area { if let Some(area) = self.current_area {

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, "kernel start: {:#x}, kernel end: {:#x}",
kernel_end); kernel_start,
println!("multiboot start: {:#x}, multiboot end: {:#x}", kernel_end
boot_info.start_address(), );
boot_info.end_address()); println!(
"multiboot start: {:#x}, multiboot end: {:#x}",
boot_info.start_address(),
boot_info.end_address()
);
let mut frame_allocator = AreaFrameAllocator::new(kernel_start as usize, let mut frame_allocator = AreaFrameAllocator::new(
kernel_end as usize, kernel_start as usize,
boot_info.start_address(), kernel_end as usize,
boot_info.end_address(), boot_info.start_address(),
memory_map_tag.memory_areas()); boot_info.end_address(),
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 frame_allocator, ref mut active_table,
ref mut stack_allocator } = self; ref mut frame_allocator,
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> {
@@ -51,9 +48,9 @@ impl Mapper {
// address must be 1GiB aligned // address must be 1GiB aligned
assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0); assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
return Some(Frame { return Some(Frame {
number: start_frame.number + page.p2_index() * ENTRY_COUNT + number: start_frame.number + page.p2_index() * ENTRY_COUNT +
page.p1_index(), page.p1_index(),
}); });
} }
} }
if let Some(p2) = p3.next_table(page.p3_index()) { if let Some(p2) = p3.next_table(page.p3_index()) {
@@ -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!(
"invalid address: 0x{:x}", address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
address); "invalid address: 0x{:x}",
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>(
table: &mut InactivePageTable, &mut self,
temporary_page: &mut temporary_page::TemporaryPage, // new table: &mut InactivePageTable,
f: F) temporary_page: &mut temporary_page::TemporaryPage, // new
where F: FnOnce(&mut Mapper) f: F,
) 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(
active_table: &mut ActivePageTable, frame: Frame,
temporary_page: &mut TemporaryPage) active_table: &mut ActivePageTable,
-> InactivePageTable { temporary_page: &mut TemporaryPage,
) -> 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"
section.addr, );
section.size); println!(
"mapping section at addr: {:#x}, size: {:#x}",
section.addr,
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>(
index: usize, &mut self,
allocator: &mut A) index: usize,
-> &mut Table<L::NextLevel> allocator: &mut A,
where A: FrameAllocator ) -> &mut Table<L::NextLevel>
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(
frame: Frame, &mut self,
active_table: &mut ActivePageTable) frame: Frame,
-> &mut Table<Level1> { active_table: &mut ActivePageTable,
) -> &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>(
active_table: &mut ActivePageTable, &mut self,
frame_allocator: &mut FA, active_table: &mut ActivePageTable,
size_in_pages: usize) frame_allocator: &mut FA,
-> Option<Stack> { size_in_pages: usize,
) -> 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

@@ -16,11 +16,10 @@ const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80; 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 _) }, });
});
macro_rules! println { macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n"))); ($fmt:expr) => (print!(concat!($fmt, "\n")));
@@ -86,9 +85,9 @@ impl Writer {
let color_code = self.color_code; let color_code = self.color_code;
self.buffer().chars[row][col].write(ScreenChar { self.buffer().chars[row][col].write(ScreenChar {
ascii_character: byte, ascii_character: byte,
color_code: color_code, color_code: color_code,
}); });
self.column_position += 1; self.column_position += 1;
} }
} }