I DONT KNOW WHAT IM DOING AND IM SCARED
This commit is contained in:
parent
76b7e7b93c
commit
a6c141dda4
@ -4,4 +4,5 @@
|
|||||||
pub mod asm;
|
pub mod asm;
|
||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
|
pub mod paging;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
|
266
src/kernel/arch/x86_64/paging.rs
Normal file
266
src/kernel/arch/x86_64/paging.rs
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use intbits::Bits;
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
pub struct PageMapLevel5 {
|
||||||
|
entries: [PageMapLevel5Entry; 512],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PageMapLevel5Entry {
|
||||||
|
value: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PageMapLevel5Entry {
|
||||||
|
pub fn execute_disable(&self) -> bool {
|
||||||
|
self.value.bit(63)
|
||||||
|
}
|
||||||
|
pub fn present(&self) -> bool {
|
||||||
|
self.value.bit(0)
|
||||||
|
}
|
||||||
|
pub fn set_present(&mut self, present: bool) {
|
||||||
|
self.value.set_bit(0, present);
|
||||||
|
}
|
||||||
|
pub fn writable(&self) -> bool {
|
||||||
|
self.value.bit(1)
|
||||||
|
}
|
||||||
|
pub fn set_writable(&mut self, writable: bool) {
|
||||||
|
self.value.set_bit(1, writable);
|
||||||
|
}
|
||||||
|
pub fn user_accessible(&self) -> bool {
|
||||||
|
self.value.bit(2)
|
||||||
|
}
|
||||||
|
pub fn set_user_accessible(&mut self, accessible: bool) {
|
||||||
|
self.value.set_bit(2, accessible);
|
||||||
|
}
|
||||||
|
pub fn write_through(&self) -> bool {
|
||||||
|
self.value.bit(3)
|
||||||
|
}
|
||||||
|
pub fn set_write_through(&mut self, write_through: bool) {
|
||||||
|
self.value.set_bit(3, write_through);
|
||||||
|
}
|
||||||
|
pub fn cache_disable(&self) -> bool {
|
||||||
|
self.value.bit(4)
|
||||||
|
}
|
||||||
|
pub fn set_cache_disable(&mut self, cache_disable: bool) {
|
||||||
|
self.value.set_bit(4, cache_disable);
|
||||||
|
}
|
||||||
|
pub fn accessed(&self) -> bool {
|
||||||
|
self.value.bit(5)
|
||||||
|
}
|
||||||
|
pub fn set_accessed(&mut self, accessed: bool) {
|
||||||
|
self.value.set_bit(5, accessed);
|
||||||
|
}
|
||||||
|
pub fn physical_address(&self) -> usize {
|
||||||
|
self.value.bits(12..=51) as usize
|
||||||
|
}
|
||||||
|
pub fn set_physical_address(&mut self, address: u64) {
|
||||||
|
self.value &= 0xFFF0000000000FFF;
|
||||||
|
self.value |= (address & 0xFFFFFFFFFF) << 12;
|
||||||
|
}
|
||||||
|
pub fn available(&self) -> usize {
|
||||||
|
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
|
||||||
|
as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
pub struct PageMapLevel4 {
|
||||||
|
entries: [PageMapLevel4Entry; 512],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PageMapLevel4Entry {
|
||||||
|
value: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PageMapLevel4Entry {
|
||||||
|
pub fn execute_disable(&self) -> bool {
|
||||||
|
self.value.bit(63)
|
||||||
|
}
|
||||||
|
pub fn present(&self) -> bool {
|
||||||
|
self.value.bit(0)
|
||||||
|
}
|
||||||
|
pub fn set_present(&mut self, present: bool) {
|
||||||
|
self.value.set_bit(0, present);
|
||||||
|
}
|
||||||
|
pub fn writable(&self) -> bool {
|
||||||
|
self.value.bit(1)
|
||||||
|
}
|
||||||
|
pub fn set_writable(&mut self, writable: bool) {
|
||||||
|
self.value.set_bit(1, writable);
|
||||||
|
}
|
||||||
|
pub fn user_accessible(&self) -> bool {
|
||||||
|
self.value.bit(2)
|
||||||
|
}
|
||||||
|
pub fn set_user_accessible(&mut self, accessible: bool) {
|
||||||
|
self.value.set_bit(2, accessible);
|
||||||
|
}
|
||||||
|
pub fn write_through(&self) -> bool {
|
||||||
|
self.value.bit(3)
|
||||||
|
}
|
||||||
|
pub fn set_write_through(&mut self, write_through: bool) {
|
||||||
|
self.value.set_bit(3, write_through);
|
||||||
|
}
|
||||||
|
pub fn cache_disable(&self) -> bool {
|
||||||
|
self.value.bit(4)
|
||||||
|
}
|
||||||
|
pub fn set_cache_disable(&mut self, cache_disable: bool) {
|
||||||
|
self.value.set_bit(4, cache_disable);
|
||||||
|
}
|
||||||
|
pub fn accessed(&self) -> bool {
|
||||||
|
self.value.bit(5)
|
||||||
|
}
|
||||||
|
pub fn set_accessed(&mut self, accessed: bool) {
|
||||||
|
self.value.set_bit(5, accessed);
|
||||||
|
}
|
||||||
|
pub fn physical_address(&self) -> usize {
|
||||||
|
self.value.bits(12..=51) as usize
|
||||||
|
}
|
||||||
|
pub fn set_physical_address(&mut self, address: u64) {
|
||||||
|
self.value &= 0xFFF0000000000FFF;
|
||||||
|
self.value |= (address & 0xFFFFFFFFFF) << 12;
|
||||||
|
}
|
||||||
|
pub fn set_pointer_table(&mut self, table: &PageDirectoryPointerTable) {
|
||||||
|
self.set_physical_address(&raw const table as u64);
|
||||||
|
}
|
||||||
|
pub fn available(&self) -> usize {
|
||||||
|
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
|
||||||
|
as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
pub struct PageDirectoryPointerTable {
|
||||||
|
entries: [*mut PageDirectory; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PageDirectoryPointer {
|
||||||
|
value: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PageDirectoryPointer {
|
||||||
|
pub fn execute_disable(&self) -> bool {
|
||||||
|
self.value.bit(63)
|
||||||
|
}
|
||||||
|
pub fn present(&self) -> bool {
|
||||||
|
self.value.bit(0)
|
||||||
|
}
|
||||||
|
pub fn set_present(&mut self, present: bool) {
|
||||||
|
self.value.set_bit(0, present);
|
||||||
|
}
|
||||||
|
pub fn writable(&self) -> bool {
|
||||||
|
self.value.bit(1)
|
||||||
|
}
|
||||||
|
pub fn set_writable(&mut self, writable: bool) {
|
||||||
|
self.value.set_bit(1, writable);
|
||||||
|
}
|
||||||
|
pub fn user_accessible(&self) -> bool {
|
||||||
|
self.value.bit(2)
|
||||||
|
}
|
||||||
|
pub fn set_user_accessible(&mut self, accessible: bool) {
|
||||||
|
self.value.set_bit(2, accessible);
|
||||||
|
}
|
||||||
|
pub fn write_through(&self) -> bool {
|
||||||
|
self.value.bit(3)
|
||||||
|
}
|
||||||
|
pub fn set_write_through(&mut self, write_through: bool) {
|
||||||
|
self.value.set_bit(3, write_through);
|
||||||
|
}
|
||||||
|
pub fn cache_disable(&self) -> bool {
|
||||||
|
self.value.bit(4)
|
||||||
|
}
|
||||||
|
pub fn set_cache_disable(&mut self, cache_disable: bool) {
|
||||||
|
self.value.set_bit(4, cache_disable);
|
||||||
|
}
|
||||||
|
pub fn accessed(&self) -> bool {
|
||||||
|
self.value.bit(5)
|
||||||
|
}
|
||||||
|
pub fn set_accessed(&mut self, accessed: bool) {
|
||||||
|
self.value.set_bit(5, accessed);
|
||||||
|
}
|
||||||
|
pub fn physical_address(&self) -> *mut PageDirectory {
|
||||||
|
self.value.bits(12..=51) as *mut PageDirectory
|
||||||
|
}
|
||||||
|
pub fn set_physical_address(&mut self, address: u64) {
|
||||||
|
self.value &= 0xFFF0000000000FFF;
|
||||||
|
self.value |= (address & 0xFFFFFFFFFF) << 12;
|
||||||
|
}
|
||||||
|
pub fn set_page_directory(&mut self, dir: &PageDirectory) {
|
||||||
|
self.set_physical_address(&raw const dir as u64);
|
||||||
|
}
|
||||||
|
pub fn available(&self) -> usize {
|
||||||
|
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
|
||||||
|
as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PageDirectory {
|
||||||
|
entries: [PageDirectoryEntry; 512],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PageDirectoryEntry {
|
||||||
|
value: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PageDirectoryEntry {
|
||||||
|
pub fn execute_disable(&self) -> bool {
|
||||||
|
self.value.bit(63)
|
||||||
|
}
|
||||||
|
pub fn present(&self) -> bool {
|
||||||
|
self.value.bit(0)
|
||||||
|
}
|
||||||
|
pub fn set_present(&mut self, present: bool) {
|
||||||
|
self.value.set_bit(0, present);
|
||||||
|
}
|
||||||
|
pub fn writable(&self) -> bool {
|
||||||
|
self.value.bit(1)
|
||||||
|
}
|
||||||
|
pub fn set_writable(&mut self, writable: bool) {
|
||||||
|
self.value.set_bit(1, writable);
|
||||||
|
}
|
||||||
|
pub fn user_accessible(&self) -> bool {
|
||||||
|
self.value.bit(2)
|
||||||
|
}
|
||||||
|
pub fn set_user_accessible(&mut self, accessible: bool) {
|
||||||
|
self.value.set_bit(2, accessible);
|
||||||
|
}
|
||||||
|
pub fn write_through(&self) -> bool {
|
||||||
|
self.value.bit(3)
|
||||||
|
}
|
||||||
|
pub fn set_write_through(&mut self, write_through: bool) {
|
||||||
|
self.value.set_bit(3, write_through);
|
||||||
|
}
|
||||||
|
pub fn cache_disable(&self) -> bool {
|
||||||
|
self.value.bit(4)
|
||||||
|
}
|
||||||
|
pub fn set_cache_disable(&mut self, cache_disable: bool) {
|
||||||
|
self.value.set_bit(4, cache_disable);
|
||||||
|
}
|
||||||
|
pub fn accessed(&self) -> bool {
|
||||||
|
self.value.bit(5)
|
||||||
|
}
|
||||||
|
pub fn set_accessed(&mut self, accessed: bool) {
|
||||||
|
self.value.set_bit(5, accessed);
|
||||||
|
}
|
||||||
|
pub fn physical_address(&self) -> usize {
|
||||||
|
self.value.bits(12..=51) as usize
|
||||||
|
}
|
||||||
|
pub fn set_physical_address(&mut self, address: u64) {
|
||||||
|
self.value &= 0xFFF0000000000FFF;
|
||||||
|
self.value |= (address & 0xFFFFFFFFFF) << 12;
|
||||||
|
}
|
||||||
|
pub fn available(&self) -> usize {
|
||||||
|
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
|
||||||
|
as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(align(4096))]
|
||||||
|
pub struct PageTable {
|
||||||
|
entries: [PageTableEntry; 512],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
pub struct PageTableEntry {
|
||||||
|
value: u64,
|
||||||
|
}
|
@ -5,6 +5,7 @@ use crate::format;
|
|||||||
use crate::log::LogLevel;
|
use crate::log::LogLevel;
|
||||||
use crate::memory::alloc::string::String;
|
use crate::memory::alloc::string::String;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub static INITRAMFS_DEFAULT_PATH: &str = "/boot/initramfs.tar.lzma";
|
pub static INITRAMFS_DEFAULT_PATH: &str = "/boot/initramfs.tar.lzma";
|
||||||
|
|
||||||
pub static LOG_DEFAULT_LEVEL: LogLevel = LogLevel::Info;
|
pub static LOG_DEFAULT_LEVEL: LogLevel = LogLevel::Info;
|
||||||
|
@ -22,6 +22,7 @@ mod util;
|
|||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
use arch::x86_64::gdt::gdt;
|
use arch::x86_64::gdt::gdt;
|
||||||
|
use arch::x86_64::paging::{self, PageDirectory, PageMapLevel4Entry, PageMapLevel5, PageMapLevel5Entry};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::x86_64::serial::Serialport;
|
use arch::x86_64::serial::Serialport;
|
||||||
|
|
||||||
@ -29,12 +30,11 @@ use arch::asm::*;
|
|||||||
use boot::{modules::*, params, *};
|
use boot::{modules::*, params, *};
|
||||||
use constants::*;
|
use constants::*;
|
||||||
use log::*;
|
use log::*;
|
||||||
use memory::{MEMMAP_REQUEST, HHDM_RESPONSE};
|
|
||||||
use memory::alloc::{format, string::*, vec};
|
use memory::alloc::{format, string::*, vec};
|
||||||
|
use memory::{HHDM_RESPONSE, MEMMAP_REQUEST};
|
||||||
use params::*;
|
use params::*;
|
||||||
|
|
||||||
use intbits::{self, Bits};
|
use intbits::{self, Bits};
|
||||||
use limine::file::File;
|
|
||||||
use limine::memory_map::EntryType;
|
use limine::memory_map::EntryType;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use lzma_rs::lzma_decompress;
|
use lzma_rs::lzma_decompress;
|
||||||
@ -113,27 +113,6 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
log_trace!("{log_msg}")
|
log_trace!("{log_msg}")
|
||||||
}
|
}
|
||||||
|
|
||||||
let irfs_path = {
|
|
||||||
if let Some(key) = PARAMS.get("-initramfs") {
|
|
||||||
key
|
|
||||||
} else {
|
|
||||||
INITRAMFS_DEFAULT_PATH
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
log_trace!("Boot: initramfs path requested: {irfs_path}");
|
|
||||||
let _initramfs = {
|
|
||||||
let mut result: Option<&File> = None;
|
|
||||||
for file in MODULE_RESPONSE.modules() {
|
|
||||||
if file.path().to_string_lossy() == irfs_path {
|
|
||||||
result = Some(file);
|
|
||||||
log_info!("Boot: initramfs found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
.expect("initramfs not found in modules list");
|
|
||||||
|
|
||||||
// Panic if this is absent. It's needed to set up the GDT and paging
|
// Panic if this is absent. It's needed to set up the GDT and paging
|
||||||
let mmap_response = MEMMAP_REQUEST
|
let mmap_response = MEMMAP_REQUEST
|
||||||
.get_response()
|
.get_response()
|
||||||
@ -223,9 +202,22 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
cr3.bits(12..=31)
|
cr3.bits(12..=31)
|
||||||
};
|
};
|
||||||
log_trace!("Boot: Physical address of page directory: 0x{:x}", pd_addr);
|
log_trace!("Boot: Physical address of page directory: 0x{:x}", pd_addr);
|
||||||
log_trace!("Boot: Virtual address of page directory: 0x{:x}", pd_addr + HHDM_RESPONSE.offset());
|
log_trace!(
|
||||||
log_trace!("Boot: GDT: 0x{:x} bytes @ 0x{:x}", unsafe { gdt().0 }, unsafe { gdt().1} );
|
"Boot: Virtual address of page directory: 0x{:x}",
|
||||||
log_trace!("Boot: GDT: 0x{:x}", unsafe { *((gdt().1 + 0x0) as *const u64) })
|
pd_addr + HHDM_RESPONSE.offset()
|
||||||
|
);
|
||||||
|
log_trace!(
|
||||||
|
"Boot: GDT: 0x{:x} bytes @ 0x{:x}",
|
||||||
|
unsafe { gdt().0 },
|
||||||
|
unsafe { gdt().1 }
|
||||||
|
);
|
||||||
|
log_trace!("Boot: GDT: 0x{:x}", unsafe {
|
||||||
|
*((gdt().1 + 0x0) as *const u64)
|
||||||
|
});
|
||||||
|
log_trace!(
|
||||||
|
"Size of page directory: {}",
|
||||||
|
size_of::<PageMapLevel4Entry>()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
panic!("Bailing");
|
panic!("Bailing");
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
use enumflags2::*;
|
use enumflags2::*;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use limine::{request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest}, response::HhdmResponse};
|
use limine::{
|
||||||
|
request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest},
|
||||||
|
response::HhdmResponse,
|
||||||
|
};
|
||||||
|
|
||||||
use core::alloc::{Allocator, Layout};
|
use core::alloc::{Allocator, Layout};
|
||||||
use talc::*;
|
use talc::*;
|
||||||
@ -26,7 +29,9 @@ pub static MEMMAP_REQUEST: MemoryMapRequest = limine::request::MemoryMapRequest:
|
|||||||
pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new();
|
pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new();
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref HHDM_RESPONSE: &'static HhdmResponse = HHDM_REQUEST.get_response().expect("Did not get HHDM response from bootloader");
|
pub static ref HHDM_RESPONSE: &'static HhdmResponse = HHDM_REQUEST
|
||||||
|
.get_response()
|
||||||
|
.expect("Did not get HHDM response from bootloader");
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut ARENA: [u8; 10000] = [0; 10000];
|
static mut ARENA: [u8; 10000] = [0; 10000];
|
||||||
|
Loading…
Reference in New Issue
Block a user