mirror of
https://github.com/mii443/nel_os.git
synced 2025-08-22 16:15:38 +00:00
add EPT
This commit is contained in:
@ -4,6 +4,7 @@
|
|||||||
#![feature(abi_x86_interrupt)]
|
#![feature(abi_x86_interrupt)]
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
#![reexport_test_harness_main = "test_main"]
|
#![reexport_test_harness_main = "test_main"]
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#![feature(custom_test_frameworks)]
|
#![feature(custom_test_frameworks)]
|
||||||
#![feature(new_zeroed_alloc)]
|
#![feature(new_zeroed_alloc)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
#![test_runner(nel_os::test_runner)]
|
#![test_runner(nel_os::test_runner)]
|
||||||
#![reexport_test_harness_main = "test_main"]
|
#![reexport_test_harness_main = "test_main"]
|
||||||
#![allow(unreachable_code)]
|
#![allow(unreachable_code)]
|
||||||
@ -10,7 +11,7 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use bootloader::{entry_point, BootInfo};
|
use bootloader::{entry_point, BootInfo};
|
||||||
use core::panic::PanicInfo;
|
use core::{panic::PanicInfo, sync::atomic::Ordering};
|
||||||
use nel_os::{
|
use nel_os::{
|
||||||
allocator, info,
|
allocator, info,
|
||||||
memory::{self, BootInfoFrameAllocator},
|
memory::{self, BootInfoFrameAllocator},
|
||||||
@ -43,6 +44,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
nel_os::init();
|
nel_os::init();
|
||||||
|
|
||||||
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
|
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
|
||||||
|
|
||||||
|
memory::PHYSICAL_MEMORY_OFFSET.store(phys_mem_offset.as_u64(), Ordering::Relaxed);
|
||||||
|
|
||||||
let mut mapper = unsafe { memory::init(phys_mem_offset) };
|
let mut mapper = unsafe { memory::init(phys_mem_offset) };
|
||||||
let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) };
|
let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) };
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
use core::sync::atomic::AtomicU64;
|
||||||
|
|
||||||
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
|
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB},
|
structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB},
|
||||||
PhysAddr, VirtAddr,
|
PhysAddr, VirtAddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub static PHYSICAL_MEMORY_OFFSET: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
pub struct BootInfoFrameAllocator {
|
pub struct BootInfoFrameAllocator {
|
||||||
memory_map: &'static MemoryMap,
|
memory_map: &'static MemoryMap,
|
||||||
next: usize,
|
next: usize,
|
||||||
|
@ -1,6 +1,61 @@
|
|||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
use x86_64::PhysAddr;
|
use x86_64::PhysAddr;
|
||||||
|
|
||||||
|
use crate::memory;
|
||||||
|
|
||||||
|
pub enum Assert<const CHECK: bool> {}
|
||||||
|
|
||||||
|
pub trait IsTrue {}
|
||||||
|
|
||||||
|
impl IsTrue for Assert<true> {}
|
||||||
|
|
||||||
|
pub struct TableEntry<const LEVEL: u8> {
|
||||||
|
pub entry: EntryBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const LEVEL: u8> TableEntry<LEVEL> {
|
||||||
|
pub fn new_map_table<const L: u8>(table: TableEntry<L>) -> Self
|
||||||
|
where
|
||||||
|
Assert<{ LEVEL > L }>: IsTrue,
|
||||||
|
Assert<{ L > 0 }>: IsTrue,
|
||||||
|
Assert<{ LEVEL < 5 }>: IsTrue,
|
||||||
|
{
|
||||||
|
let mut entry = EntryBase::default();
|
||||||
|
entry.set_map_memory(false);
|
||||||
|
entry.set_typ(0);
|
||||||
|
entry.set_phys(
|
||||||
|
(&table as *const _ as u64 + memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed))
|
||||||
|
>> 12,
|
||||||
|
);
|
||||||
|
|
||||||
|
Self { entry }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_map_page<const L: u8>(phys: u64) -> Self
|
||||||
|
where
|
||||||
|
Assert<{ L < 4 }>: IsTrue,
|
||||||
|
Assert<{ L > 0 }>: IsTrue,
|
||||||
|
{
|
||||||
|
let mut entry = EntryBase::default();
|
||||||
|
entry.set_read(true);
|
||||||
|
entry.set_write(true);
|
||||||
|
entry.set_exec_super(true);
|
||||||
|
entry.set_exec_user(true);
|
||||||
|
entry.set_map_memory(true);
|
||||||
|
entry.set_typ(0);
|
||||||
|
entry.set_phys((phys + memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed)) >> 12);
|
||||||
|
|
||||||
|
Self { entry }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Lv4Entry = TableEntry<4>;
|
||||||
|
pub type Lv3Entry = TableEntry<3>;
|
||||||
|
pub type Lv2Entry = TableEntry<2>;
|
||||||
|
pub type Lv1Entry = TableEntry<1>;
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
pub struct EntryBase(u64);
|
pub struct EntryBase(u64);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
@ -25,6 +80,22 @@ impl EntryBase {
|
|||||||
pub fn address(&self) -> PhysAddr {
|
pub fn address(&self) -> PhysAddr {
|
||||||
PhysAddr::new(self.phys() << 12)
|
PhysAddr::new(self.phys() << 12)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn new_map_table() {}
|
|
||||||
|
impl Default for EntryBase {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut entry = EntryBase(0);
|
||||||
|
entry.set_read(true);
|
||||||
|
entry.set_write(true);
|
||||||
|
entry.set_exec_super(true);
|
||||||
|
entry.set_typ(0);
|
||||||
|
entry.set_ignore_pat(false);
|
||||||
|
entry.set_map_memory(false);
|
||||||
|
entry.set_accessed(false);
|
||||||
|
entry.set_dirty(false);
|
||||||
|
entry.set_exec_user(true);
|
||||||
|
entry.set_phys(0);
|
||||||
|
|
||||||
|
entry
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user