Compare commits
2 Commits
4dc05da38d
...
5a41a9c6a9
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a41a9c6a9 | |||
| 2b34fe6912 |
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -61,12 +61,6 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core2"
|
name = "core2"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@ -139,7 +133,6 @@ version = "0.3.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"acid_alloc",
|
"acid_alloc",
|
||||||
"acpi",
|
"acpi",
|
||||||
"cfg-if",
|
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"fdt",
|
"fdt",
|
||||||
"flagset",
|
"flagset",
|
||||||
|
|||||||
@ -6,22 +6,22 @@ license = "MIT"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
acid_alloc = { version = "0.1.0", features = ["alloc"] }
|
acid_alloc = { version = "0.1.0", features = ["alloc"] }
|
||||||
acpi = { version = "6.0.1", optional = true }
|
|
||||||
cfg-if = "1.0.4"
|
|
||||||
enumflags2 = "0.7.12"
|
enumflags2 = "0.7.12"
|
||||||
fdt = { git = "https://github.com/repnop/fdt", version = "0.2.0-alpha1", optional = true }
|
|
||||||
flagset = "0.4.7"
|
flagset = "0.4.7"
|
||||||
free-list = { version = "0.3.1", features = ["x86_64"] }
|
free-list = { version = "0.3.1", features = ["x86_64"] }
|
||||||
intbits = "0.2.0"
|
intbits = "0.2.0"
|
||||||
lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] }
|
lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] }
|
||||||
limine = "0.5.0"
|
limine = "0.5.0"
|
||||||
lzma-rs = { git = "https://github.com/glaeqen/lzma-no-std-rs/", version = "0.2.0", default-features = false, optional = true }
|
|
||||||
num-derive = "0.4.2"
|
num-derive = "0.4.2"
|
||||||
num-traits = { version = "0.2.19", default-features = false }
|
num-traits = { version = "0.2.19", default-features = false }
|
||||||
once_cell = { version = "1.21.3", default-features = false, features = ["alloc", "critical-section"] }
|
once_cell = { version = "1.21.3", default-features = false, features = ["alloc", "critical-section"] }
|
||||||
spin = "0.10.0"
|
spin = "0.10.0"
|
||||||
talc = "4.4.3"
|
talc = "4.4.3"
|
||||||
|
# Optional Dependencies for Features
|
||||||
tar-no-std = "0.4.2"
|
tar-no-std = "0.4.2"
|
||||||
|
fdt = { git = "https://github.com/repnop/fdt", version = "0.2.0-alpha1", optional = true }
|
||||||
|
acpi = { version = "6.0.1", optional = true }
|
||||||
|
lzma-rs = { git = "https://github.com/glaeqen/lzma-no-std-rs/", version = "0.2.0", default-features = false, optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
x86_64 = "0.15.2"
|
x86_64 = "0.15.2"
|
||||||
|
|||||||
@ -4,13 +4,27 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::constants::KERNEL_BUILD_PROFILE;
|
use crate::constants::KERNEL_BUILD_PROFILE;
|
||||||
use crate::{LOGGER, LogLevel, format, log_info, memory::HHDM_RESPONSE};
|
use crate::{LOGGER, LogLevel, format, log_info, log_trace, memory::HHDM_RESPONSE};
|
||||||
|
use free_list::{PAGE_SIZE, PageLayout};
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
PhysAddr, VirtAddr,
|
PhysAddr, VirtAddr,
|
||||||
registers::control::*,
|
registers::control::*,
|
||||||
structures::paging::{PageTable, PageTableFlags},
|
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() {
|
pub fn get_mappings() {
|
||||||
log_info!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING));
|
log_info!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING));
|
||||||
log_info!(
|
log_info!(
|
||||||
@ -60,7 +74,7 @@ fn iter_table(table: &'static mut PageTable, level: usize) {
|
|||||||
if level == 1 {
|
if level == 1 {
|
||||||
for page_entry in table.iter() {
|
for page_entry in table.iter() {
|
||||||
if page_entry.flags().contains(PageTableFlags::PRESENT) {
|
if page_entry.flags().contains(PageTableFlags::PRESENT) {
|
||||||
log_info!(
|
log_trace!(
|
||||||
"Page entry: 0x{:x}, flags: {:?}",
|
"Page entry: 0x{:x}, flags: {:?}",
|
||||||
page_entry.addr(),
|
page_entry.addr(),
|
||||||
page_entry.flags()
|
page_entry.flags()
|
||||||
|
|||||||
@ -161,7 +161,7 @@ impl SerialPort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new port-mapped serial port with the base address `port_addr`.
|
/// 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 {
|
let mut port = SerialPort {
|
||||||
base_port: Port::new(port_addr),
|
base_port: Port::new(port_addr),
|
||||||
interrupt_enable: Port::new(port_addr + 1),
|
interrupt_enable: Port::new(port_addr + 1),
|
||||||
@ -180,6 +180,33 @@ impl SerialPort {
|
|||||||
port
|
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 {
|
fn get_line_control(&mut self) -> u8 {
|
||||||
unsafe { self.line_control.read() }
|
unsafe { self.line_control.read() }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,18 +37,20 @@ use spin::mutex::Mutex;
|
|||||||
use crate::arch::x86_64::cpuid::{CPUID, virt_supported};
|
use crate::arch::x86_64::cpuid::{CPUID, virt_supported};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref SERIAL_3F8: Mutex<SerialPort> =
|
pub static ref SERIAL_3F8: Mutex<SerialPort> = Mutex::new(
|
||||||
Mutex::new(arch::x86_64::serial::SerialPort::new(0x3f8));
|
arch::x86_64::serial::SerialPort::try_from_port(0x3f8).expect("Could not create port")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn main() -> ! {
|
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 supported bootloader version
|
||||||
assert!(BASE_REVISION.is_supported());
|
assert!(BASE_REVISION.is_supported());
|
||||||
|
|
||||||
// Ensure IDT exists
|
|
||||||
IDT.load();
|
|
||||||
|
|
||||||
// Set up logging level from params
|
// Set up logging level from params
|
||||||
// Nothing we can do here if this fails since no log subscribers are initialized yet
|
// Nothing we can do here if this fails since no log subscribers are initialized yet
|
||||||
if let Some(level) = PARAMS.get("-loglevel")
|
if let Some(level) = PARAMS.get("-loglevel")
|
||||||
@ -69,6 +71,13 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
}
|
}
|
||||||
log_trace!("Configured kernel logging devices");
|
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!(
|
log_info!(
|
||||||
"Kernel cmdline: {}",
|
"Kernel cmdline: {}",
|
||||||
String::from_utf8_lossy(
|
String::from_utf8_lossy(
|
||||||
@ -150,5 +159,7 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
}
|
}
|
||||||
log_info!("Virtualization provider: {:?}", virt_supported());
|
log_info!("Virtualization provider: {:?}", virt_supported());
|
||||||
|
|
||||||
|
arch::x86_64::paging::switch_ptable();
|
||||||
|
|
||||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
panic!("Finished boot, but cannot start init because processes not implemented!");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,8 @@ use talc::*;
|
|||||||
|
|
||||||
pub extern crate alloc;
|
pub extern crate alloc;
|
||||||
|
|
||||||
static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
|
pub static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
|
||||||
static HW_FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
|
pub static HW_FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref MEMMAP_RESPONSE: &'static MemoryMapResponse = MEMMAP_REQUEST
|
pub static ref MEMMAP_RESPONSE: &'static MemoryMapResponse = MEMMAP_REQUEST
|
||||||
|
|||||||
@ -1,33 +1,45 @@
|
|||||||
|
|
||||||
use num_derive::FromPrimitive;
|
use num_derive::FromPrimitive;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
use crate::arch;
|
use crate::arch;
|
||||||
|
#[repr(u32)]
|
||||||
#[derive(FromPrimitive, Debug)]
|
#[derive(FromPrimitive, Debug)]
|
||||||
pub enum Syscall {
|
pub enum Syscall {
|
||||||
Exit,
|
/// Kill the calling process, and deallocate all
|
||||||
Pid,
|
/// resources associated, including shared memory channels,
|
||||||
Message,
|
/// IPC sessions, handles, etc.
|
||||||
MemMap,
|
/// Arguments:
|
||||||
MemUnmap,
|
/// 0 - Exit code
|
||||||
Resolve,
|
Exit = 0,
|
||||||
Spawn,
|
/// Get the current PID of the calling process.
|
||||||
Version,
|
Pid = 1,
|
||||||
Yield,
|
/// 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)]
|
#[derive(FromPrimitive, Debug)]
|
||||||
pub enum SyscallStatus {
|
pub enum SyscallStatus {
|
||||||
|
/// Syscall completed without any issues.
|
||||||
Success,
|
Success,
|
||||||
|
/// Issued a system call with the wrong call ID.
|
||||||
NoSuchCall,
|
NoSuchCall,
|
||||||
NoSuchProcess,
|
NoSuchProcess,
|
||||||
NoSuchService,
|
NoSuchService,
|
||||||
NoPermission,
|
SecurityFailure,
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
Aborted,
|
Aborted,
|
||||||
Unspecified,
|
Unspecified,
|
||||||
Unknown,
|
Unknown,
|
||||||
Unimplemented,
|
Unimplemented,
|
||||||
|
InvalidPage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u64> for SyscallStatus {
|
impl From<u64> for SyscallStatus {
|
||||||
@ -35,3 +47,8 @@ impl From<u64> for SyscallStatus {
|
|||||||
SyscallStatus::from_u64(value).unwrap_or(Self::Unknown)
|
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!();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user