Skip to content

Commit

Permalink
added basic paging support for kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
M4tsuri committed Dec 28, 2021
1 parent d287e2b commit cd72879
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 96 deletions.
10 changes: 5 additions & 5 deletions bootloader/shared/src/kctx.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! The module holds the data structure for passing nessessary information to kernel.
use i386::{
driver::mem::e820::E820MemInfo,
driver::disk::ata::pio::ATADiskInfo
driver::disk::ata::pio::ATADiskInfo, mem::paging::Paging
};
use crate::mem::MEMINFO_MAX;

/// The module holds the data structure for passing nessessary information to kernel.

pub struct KernelContext {
pub disk_info: ATADiskInfo,
pub mem_info: E820MemInfo<MEMINFO_MAX>
pub mem_info: E820MemInfo<MEMINFO_MAX>,
pub kernel_paging: &'static dyn Paging
}
20 changes: 10 additions & 10 deletions bootloader/stage_2/src/mode_switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn to_protect() -> ! {
"mov eax, cr0",
"or eax, 1",
"mov cr0, eax",
// 5. Load DS, SS, ES, FS and GS with corresponding GDT selectors
// 5. Load DS, SS, ES, FS and GS with corresponding GDT selectors
"mov ax, {data}",
"mov ds, ax",
"mov es, ax",
Expand All @@ -48,15 +48,15 @@ pub fn to_protect() -> ! {
"mov esp, {stack_but}",
"mov ax, {null}",
"mov fs, ax",
// 6. re-enable hardware interrupts
// TODO: Enable hardware interrupt.
// Currently directly executing sti instruction causes weird behavior of QEMU
// due to the lack of IDT.
// See https://lists.gnu.org/archive/html/qemu-discuss/2015-01/msg00033.html
// "sti"
// 4. Do a far jump to the next instruction to serialize the processer
// (clear the pipeline, I don't know how does this work =-=)
// This step also sets the cs register.
// 6. re-enable hardware interrupts
// TODO: Enable hardware interrupt.
// Currently directly executing sti instruction causes weird behavior of QEMU
// due to the lack of IDT.
// See https://lists.gnu.org/archive/html/qemu-discuss/2015-01/msg00033.html
// "sti"
// 4. Do a far jump to the next instruction to serialize the processer
// (clear the pipeline, I don't know how does this work =-=)
// This step also sets the cs register.
"jmp {CS}, offset {target}",
data = const GDTSelector::DATA as u16,
stack = const GDTSelector::STACK as u16,
Expand Down
7 changes: 5 additions & 2 deletions bootloader/stage_3/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use shared::{
};
use static_alloc::Bump;

use crate::load_kernel::KERNEL_PTR;
use crate::{load_kernel::KERNEL_PTR, paging::{KERNEL_PAGING, enable_paging}};

#[global_allocator]
static ALLOC: Bump<[u8; 1 << 16]> = Bump::uninit();
Expand Down Expand Up @@ -64,11 +64,14 @@ fn main() -> Result<KernelContext, String> {
.map_err(|x| <FSError<ATAError> as Into<String>>::into(x))?;
load_kernel(&fs)?;
println!("Kernel loaded.");

enable_paging();
// switch to real mode and poweroff, just for illustrating our mode switching works.
// crate::mode_switch::to_real(crate::mode_switch::poweroff as u16);
Ok(KernelContext {
disk_info: fs.get_disk_info(),
mem_info: unsafe { MEMINFO.clone() }
mem_info: unsafe { MEMINFO.clone() },
kernel_paging: &KERNEL_PAGING
})
}

Expand Down
44 changes: 44 additions & 0 deletions bootloader/stage_3/src/paging.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use i386::mem::paging::{
pae::{PDEntry, PDTable, PDPTable, PDPTEntry, PAEPaging},
PATMemoryType, Paging
};

/// kernel occupies 3 2MiB pages, this value can be adjusted accordingly
#[allow(dead_code)]
const KERNEL_PAGENUM: usize = 2;
const MB: u64 = 1 << 20;

/// 4MB kernel PDT page table entry (directly map virtual address to the same physical address)
static KERNEL_PDT: PDTable = PDTable::with_entries([
PDEntry::new_page(
true,
false,
PATMemoryType::new(false, false, false),
false,
0 * MB,
false
),
PDEntry::new_page(
true,
false,
PATMemoryType::new(false, false, false),
false,
2 * MB,
false
)
]);

/// kernel top level page table
static mut KERNEL_PDPT: PDPTable = PDPTable::new();

pub static KERNEL_PAGING: PAEPaging = PAEPaging::new(unsafe { &KERNEL_PDPT });

pub fn enable_paging() {
unsafe { KERNEL_PDPT.entries[0] = PDPTEntry::new(
PATMemoryType::new(false, false, false),
&KERNEL_PDT as *const PDTable as u64
)};

unsafe { KERNEL_PDPT.entries[1] = PDPTEntry(0xffffffffffffffff); }
KERNEL_PAGING.enable();
}
21 changes: 19 additions & 2 deletions i386/src/mem.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::ops::Sub;

/// This module contains code for memory management
#[cfg(feature = "alloc")]
pub mod paging;
pub mod dt;

Expand All @@ -9,4 +10,20 @@ pub mod info;

/// currently this must be u64, DO NOT change it
pub type PhysAddr = u64;
pub type VirtAddr = usize;
pub type VirtAddr = usize;

/// A memory range
pub struct MemRange<T> {
pub start: T,
pub end: T,
pub len: T,
}

impl<T: Sub<Output = T> + Copy> MemRange<T> {
pub fn new(start: T, end: T) -> Self {
Self {
start, end,
len: end - start
}
}
}
20 changes: 1 addition & 19 deletions i386/src/mem/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,13 @@
extern crate alloc;

use core::ops::Sub;

use alloc::vec::Vec;

use crate::{
driver::mem::e820::{E820MemInfo, E820MemType},
mem::PhysAddr
mem::{PhysAddr, MemRange}
};

/// A memory range
pub struct MemRange<T> {
pub start: T,
pub end: T,
pub len: T,
}

impl<T: Sub<Output = T> + Copy> MemRange<T> {
pub fn new(start: T, end: T) -> Self {
Self {
start, end,
len: end - start
}
}
}

pub struct PhysMemInfo {
pub segs: Vec<MemRange<PhysAddr>>
}
Expand Down
8 changes: 6 additions & 2 deletions i386/src/mem/paging.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! This module defines data structures and related utilities about paging.
//! We only support PAE mode paging now.
extern crate alloc;

pub mod pae;

/// supported paging modes
Expand Down Expand Up @@ -36,6 +34,12 @@ pub struct PATMemoryType {
pcd: bool
}

impl PATMemoryType {
pub const fn new(pat: bool, pwt: bool, pcd: bool) -> Self {
Self { pat, pwt, pcd }
}
}

/// The unified interface for paging modes. every paging mode should implement this trait.
pub trait Paging {
/// Enter paging mode
Expand Down
Loading

0 comments on commit cd72879

Please sign in to comment.