mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-17 06:47:49 +00:00
Format using rustfmt-nightly
This commit is contained in:
@@ -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 {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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()];
|
||||||
|
|||||||
@@ -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 */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user