Allocate space and create new page table
Some checks failed
Continuous Integration / Check (push) Successful in 1m7s
Continuous Integration / Clippy (push) Failing after 1m12s

This commit is contained in:
August 2025-11-04 19:58:42 -05:00
parent 2b34fe6912
commit 5a41a9c6a9
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
5 changed files with 88 additions and 19 deletions

View File

@ -5,12 +5,26 @@
use crate::constants::KERNEL_BUILD_PROFILE;
use crate::{LOGGER, LogLevel, format, log_info, log_trace, memory::HHDM_RESPONSE};
use free_list::{PAGE_SIZE, PageLayout};
use x86_64::{
PhysAddr, VirtAddr,
registers::control::*,
structures::paging::{PageTable, PageTableFlags},
};
pub fn switch_ptable() {
let allocated_region = crate::memory::FREELIST
.lock()
.allocate(PageLayout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap())
.expect("Could not allocate pages for new page table!");
log_info!("Got region for new PML4: 0x{:x}", allocated_region.start());
let pml4_start_vaddr = allocated_region.start() + HHDM_RESPONSE.offset() as usize;
let pml4_ptr = pml4_start_vaddr as *mut PageTable;
let mut pml4 = unsafe { crate::memory::alloc::boxed::Box::from_raw(pml4_ptr) };
*pml4 = PageTable::new();
log_info!("Initialized page table at 0x{:p}", pml4);
}
pub fn get_mappings() {
log_info!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING));
log_info!(

View File

@ -161,7 +161,7 @@ impl SerialPort {
}
/// Create a new port-mapped serial port with the base address `port_addr`.
pub fn new(port_addr: u16) -> Self {
pub unsafe fn from_port_unchecked(port_addr: u16) -> Self {
let mut port = SerialPort {
base_port: Port::new(port_addr),
interrupt_enable: Port::new(port_addr + 1),
@ -180,6 +180,33 @@ impl SerialPort {
port
}
pub fn try_from_port(port_addr: u16) -> Option<Self> {
let mut port = unsafe { SerialPort::from_port_unchecked(port_addr) };
// Assert that port scratch register is writable
unsafe { port.scratch.write(192) };
if unsafe { port.scratch.read() } != 192 {
return None;
}
// Enable loopback mode
let mut port_modem = port.get_modem_control();
port_modem.insert(ModemControl::Loop);
port.set_modem_control(port_modem);
port.write_char(0xae as char);
// Assert that loopback mode worked
if port.read_char() != (0xae as u8) {
return None;
}
// Disable loopback mode
port_modem.remove(ModemControl::Loop);
port.set_modem_control(port_modem);
Some(port)
}
fn get_line_control(&mut self) -> u8 {
unsafe { self.line_control.read() }
}

View File

@ -37,18 +37,20 @@ use spin::mutex::Mutex;
use crate::arch::x86_64::cpuid::{CPUID, virt_supported};
lazy_static! {
pub static ref SERIAL_3F8: Mutex<SerialPort> =
Mutex::new(arch::x86_64::serial::SerialPort::new(0x3f8));
pub static ref SERIAL_3F8: Mutex<SerialPort> = Mutex::new(
arch::x86_64::serial::SerialPort::try_from_port(0x3f8).expect("Could not create port")
);
}
#[unsafe(no_mangle)]
unsafe extern "C" fn main() -> ! {
// CRITICAL AREA
// Nothing non-essential should be done until we can initialize logging
// Otherwise it will fail silently
// Assert supported bootloader version
assert!(BASE_REVISION.is_supported());
// Ensure IDT exists
IDT.load();
// Set up logging level from params
// Nothing we can do here if this fails since no log subscribers are initialized yet
if let Some(level) = PARAMS.get("-loglevel")
@ -69,6 +71,13 @@ unsafe extern "C" fn main() -> ! {
}
log_trace!("Configured kernel logging devices");
}
// END OF CRITICAL AREA
// Fallible code can be placed below this comment
// Ensure IDT exists
IDT.load();
log_info!(
"Kernel cmdline: {}",
String::from_utf8_lossy(
@ -150,5 +159,7 @@ unsafe extern "C" fn main() -> ! {
}
log_info!("Virtualization provider: {:?}", virt_supported());
arch::x86_64::paging::switch_ptable();
panic!("Finished boot, but cannot start init because processes not implemented!");
}

View File

@ -19,8 +19,8 @@ use talc::*;
pub extern crate alloc;
static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
static HW_FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
pub static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
pub static HW_FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
lazy_static! {
pub static ref MEMMAP_RESPONSE: &'static MemoryMapResponse = MEMMAP_REQUEST

View File

@ -1,33 +1,45 @@
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use crate::arch;
#[repr(u32)]
#[derive(FromPrimitive, Debug)]
pub enum Syscall {
Exit,
Pid,
Message,
MemMap,
MemUnmap,
Resolve,
Spawn,
Version,
Yield,
/// Kill the calling process, and deallocate all
/// resources associated, including shared memory channels,
/// IPC sessions, handles, etc.
/// Arguments:
/// 0 - Exit code
Exit = 0,
/// Get the current PID of the calling process.
Pid = 1,
/// Send a message to another process.
Message = 2,
MemMap = 3,
MemUnmap = 4,
Resolve = 5,
Spawn = 6,
Version = 7,
Yield = 8,
}
#[repr(u32)]
#[derive(FromPrimitive, Debug)]
pub enum SyscallStatus {
/// Syscall completed without any issues.
Success,
/// Issued a system call with the wrong call ID.
NoSuchCall,
NoSuchProcess,
NoSuchService,
NoPermission,
SecurityFailure,
OutOfMemory,
Aborted,
Unspecified,
Unknown,
Unimplemented,
InvalidPage,
}
impl From<u64> for SyscallStatus {
@ -35,3 +47,8 @@ impl From<u64> for SyscallStatus {
SyscallStatus::from_u64(value).unwrap_or(Self::Unknown)
}
}
pub fn exit(code: u32) -> ! {
arch::syscall_impl::caller_syscall_1(Syscall::Exit as u64, code as u64);
unreachable!();
}