This commit is contained in:
Masato Imai
2025-04-27 09:12:19 +00:00
parent f4bdb36793
commit 6f342db5c2
4 changed files with 83 additions and 3 deletions

View File

@ -4,6 +4,7 @@
#![feature(abi_x86_interrupt)]
#![feature(alloc_error_handler)]
#![feature(naked_functions)]
#![feature(generic_const_exprs)]
#![test_runner(crate::test_runner)]
#![reexport_test_harness_main = "test_main"]

View File

@ -3,6 +3,7 @@
#![feature(custom_test_frameworks)]
#![feature(new_zeroed_alloc)]
#![feature(naked_functions)]
#![feature(generic_const_exprs)]
#![test_runner(nel_os::test_runner)]
#![reexport_test_harness_main = "test_main"]
#![allow(unreachable_code)]
@ -10,7 +11,7 @@
extern crate alloc;
use bootloader::{entry_point, BootInfo};
use core::panic::PanicInfo;
use core::{panic::PanicInfo, sync::atomic::Ordering};
use nel_os::{
allocator, info,
memory::{self, BootInfoFrameAllocator},
@ -43,6 +44,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
nel_os::init();
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 frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) };

View File

@ -1,9 +1,13 @@
use core::sync::atomic::AtomicU64;
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
use x86_64::{
structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB},
PhysAddr, VirtAddr,
};
pub static PHYSICAL_MEMORY_OFFSET: AtomicU64 = AtomicU64::new(0);
pub struct BootInfoFrameAllocator {
memory_map: &'static MemoryMap,
next: usize,

View File

@ -1,6 +1,61 @@
use core::sync::atomic::Ordering;
use bitfield::bitfield;
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! {
pub struct EntryBase(u64);
impl Debug;
@ -25,6 +80,22 @@ impl EntryBase {
pub fn address(&self) -> PhysAddr {
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
}
}