i686: add PCI functionality for i686
This commit is contained in:
parent
4b25a4db89
commit
b9e2998248
@ -12,7 +12,7 @@ use yggdrasil_abi::{arch::SavedFrame, error::Error};
|
||||
#[repr(C)]
|
||||
pub struct ExceptionFrame {
|
||||
/// General-purpose registers
|
||||
pub r: [u64; 32],
|
||||
pub r: [usize; 32],
|
||||
/// SPSR_EL1, userspace flags register
|
||||
pub spsr_el1: u64,
|
||||
/// ELR_EL1, userspace program counter
|
||||
@ -65,7 +65,7 @@ impl TaskFrame for ExceptionFrame {
|
||||
}
|
||||
|
||||
fn argument(&self) -> u64 {
|
||||
self.r[0]
|
||||
self.r[0] as _
|
||||
}
|
||||
|
||||
fn user_ip(&self) -> usize {
|
||||
@ -77,11 +77,11 @@ impl TaskFrame for ExceptionFrame {
|
||||
}
|
||||
|
||||
fn set_argument(&mut self, value: u64) {
|
||||
self.r[0] = value;
|
||||
self.r[0] = value as _;
|
||||
}
|
||||
|
||||
fn set_return_value(&mut self, value: u64) {
|
||||
self.r[0] = value;
|
||||
self.r[0] = value as _;
|
||||
}
|
||||
|
||||
fn set_user_ip(&mut self, value: usize) {
|
||||
|
@ -10,6 +10,7 @@ use yggdrasil_abi::{arch::SavedFrame, error::Error};
|
||||
|
||||
use crate::{gdt::TSS, mem::KERNEL_TABLES, registers::CR3};
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(C)]
|
||||
pub struct ExceptionFrame {
|
||||
pub eax: u32,
|
||||
@ -30,6 +31,7 @@ pub struct ExceptionFrame {
|
||||
ss: u32,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct SyscallFrame {
|
||||
@ -44,6 +46,7 @@ pub struct SyscallFrame {
|
||||
pub ss: u32,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(C)]
|
||||
pub struct InterruptFrame {
|
||||
pub eax: u32,
|
||||
@ -91,7 +94,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
const USER_STACK_EXTRA_ALIGN: usize = 0;
|
||||
|
||||
fn user(context: UserContextInfo) -> Result<Self, Error> {
|
||||
const USER_TASK_PAGES: usize = 8;
|
||||
const USER_TASK_PAGES: usize = 16;
|
||||
|
||||
let stack_base_phys = PA::allocate_contiguous_pages(USER_TASK_PAGES)?;
|
||||
let stack_base = stack_base_phys.raw_virtualize::<K>();
|
||||
@ -218,7 +221,17 @@ impl TaskFrame for SyscallFrame {
|
||||
}
|
||||
|
||||
fn restore(&mut self, saved: &SavedFrame) {
|
||||
todo!()
|
||||
self.eax = saved.eax as _;
|
||||
self.args[0] = saved.ebx as _;
|
||||
self.args[1] = saved.ecx as _;
|
||||
self.args[2] = saved.edx as _;
|
||||
self.args[3] = saved.esi as _;
|
||||
self.args[4] = saved.edi as _;
|
||||
self.args[5] = saved.ebp as _;
|
||||
|
||||
self.eip = saved.user_ip;
|
||||
self.esp = saved.user_sp;
|
||||
self.eflags = saved.eflags;
|
||||
}
|
||||
|
||||
fn user_sp(&self) -> usize {
|
||||
@ -230,7 +243,7 @@ impl TaskFrame for SyscallFrame {
|
||||
}
|
||||
|
||||
fn argument(&self) -> u64 {
|
||||
todo!()
|
||||
self.args[0] as _
|
||||
}
|
||||
|
||||
fn set_user_sp(&mut self, value: usize) {
|
||||
@ -250,7 +263,7 @@ impl TaskFrame for SyscallFrame {
|
||||
self.eax = value as usize;
|
||||
}
|
||||
|
||||
fn set_single_step(&mut self, step: bool) {
|
||||
fn set_single_step(&mut self, _step: bool) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@ -281,7 +294,7 @@ impl TaskFrame for InterruptFrame {
|
||||
}
|
||||
}
|
||||
|
||||
fn restore(&mut self, saved: &SavedFrame) {
|
||||
fn restore(&mut self, _saved: &SavedFrame) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@ -314,7 +327,7 @@ impl TaskFrame for InterruptFrame {
|
||||
self.eax = value as u32;
|
||||
}
|
||||
|
||||
fn set_single_step(&mut self, step: bool) {
|
||||
fn set_single_step(&mut self, _step: bool) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@ -345,7 +358,7 @@ impl TaskFrame for ExceptionFrame {
|
||||
}
|
||||
}
|
||||
|
||||
fn restore(&mut self, saved: &SavedFrame) {
|
||||
fn restore(&mut self, _saved: &SavedFrame) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@ -378,7 +391,7 @@ impl TaskFrame for ExceptionFrame {
|
||||
self.eax = value as u32;
|
||||
}
|
||||
|
||||
fn set_single_step(&mut self, step: bool) {
|
||||
fn set_single_step(&mut self, _step: bool) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use core::ptr::{addr_of_mut, null_mut};
|
||||
use core::ptr::null_mut;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use device_api::interrupt::{LocalInterruptController, MessageInterruptController};
|
||||
@ -100,11 +100,11 @@ impl Architecture for ArchitectureImpl {
|
||||
}
|
||||
|
||||
fn message_interrupt_controller() -> &'static dyn MessageInterruptController {
|
||||
loop {}
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn local_interrupt_controller() -> &'static dyn LocalInterruptController {
|
||||
loop {}
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn idle_task() -> extern "C" fn(usize) -> ! {
|
||||
|
@ -1,19 +1,25 @@
|
||||
use kernel_arch_interface::KERNEL_VIRT_OFFSET;
|
||||
use libk_mm_interface::address::PhysicalAddress;
|
||||
use kernel_arch_interface::{sync::IrqSafeSpinlock, KERNEL_VIRT_OFFSET};
|
||||
use libk_mm_interface::{address::PhysicalAddress, table::EntryLevel, KernelImageObject};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::mem::KERNEL_TABLES;
|
||||
use crate::{
|
||||
mem::{flush_tlb_entry, table::PageAttributes, KERNEL_TABLES},
|
||||
ArchitectureImpl,
|
||||
};
|
||||
|
||||
use super::table::{PageEntry, PageTable, L0, L3};
|
||||
|
||||
pub const KERNEL_SPLIT_L0: usize = KERNEL_VIRT_OFFSET >> 22;
|
||||
pub const DYNAMIC_MAP_COUNT: usize = 64;
|
||||
pub const FIXED_MAP_COUNT: usize = 1024 - (KERNEL_SPLIT_L0 + DYNAMIC_MAP_COUNT);
|
||||
pub const DYNAMIC_MAP_OFFSET: usize = (KERNEL_SPLIT_L0 + FIXED_MAP_COUNT) << L0::SHIFT;
|
||||
pub const MAX_FIXED_PHYSICAL: PhysicalAddress =
|
||||
PhysicalAddress::from_u64((FIXED_MAP_COUNT as u64) << 22);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FixedTables {
|
||||
pub l0: KernelL0,
|
||||
pub dynamic: KernelDynamic,
|
||||
pub dynamic: IrqSafeSpinlock<ArchitectureImpl, KernelDynamic>,
|
||||
}
|
||||
|
||||
#[repr(C, align(0x1000))]
|
||||
@ -23,16 +29,17 @@ pub struct KernelL0 {
|
||||
pub dynamic: [PageEntry<L0>; DYNAMIC_MAP_COUNT],
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub struct KernelDynamic {
|
||||
l3s: [PageTable<L3>; DYNAMIC_MAP_COUNT],
|
||||
refcounts: [u32; DYNAMIC_MAP_COUNT],
|
||||
pub l3s: [KernelImageObject<PageTable<L3>>; DYNAMIC_MAP_COUNT],
|
||||
free: usize,
|
||||
}
|
||||
|
||||
impl FixedTables {
|
||||
pub const fn zeroed() -> Self {
|
||||
Self {
|
||||
l0: KernelL0::zeroed(),
|
||||
dynamic: KernelDynamic::zeroed(),
|
||||
dynamic: IrqSafeSpinlock::new(KernelDynamic::zeroed()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +48,7 @@ impl FixedTables {
|
||||
// It's a fixed address
|
||||
address.into_u64() as usize + KERNEL_VIRT_OFFSET
|
||||
} else {
|
||||
loop {}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +61,13 @@ impl FixedTables {
|
||||
// It's a fixed address
|
||||
Some(PhysicalAddress::from_usize(address - KERNEL_VIRT_OFFSET))
|
||||
} else {
|
||||
loop {}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_dynamic_memory(&mut self, base: u64, page_count: usize) -> Result<usize, Error> {
|
||||
self.dynamic.lock().map(base, page_count)
|
||||
}
|
||||
}
|
||||
|
||||
impl KernelL0 {
|
||||
@ -72,10 +83,47 @@ impl KernelL0 {
|
||||
impl KernelDynamic {
|
||||
pub const fn zeroed() -> Self {
|
||||
Self {
|
||||
l3s: [PageTable::zeroed(); DYNAMIC_MAP_COUNT],
|
||||
refcounts: [0; DYNAMIC_MAP_COUNT],
|
||||
l3s: [const { unsafe { KernelImageObject::new(PageTable::zeroed()) } };
|
||||
DYNAMIC_MAP_COUNT],
|
||||
free: DYNAMIC_MAP_COUNT * 1024,
|
||||
}
|
||||
}
|
||||
|
||||
fn map(&mut self, base: u64, page_count: usize) -> Result<usize, Error> {
|
||||
if page_count > self.free {
|
||||
return Err(Error::OutOfMemory);
|
||||
}
|
||||
|
||||
'l0: for i in 0..DYNAMIC_MAP_COUNT * 1024 - page_count {
|
||||
for j in 0..page_count {
|
||||
let entry = self.entry(i + j);
|
||||
if entry.is_present() {
|
||||
continue 'l0;
|
||||
}
|
||||
}
|
||||
|
||||
self.free -= page_count;
|
||||
for j in 0..page_count {
|
||||
let address = PhysicalAddress::from_u64(base + ((j as u64) << L3::SHIFT));
|
||||
*self.entry_mut(i + j) = PageEntry::page(address, PageAttributes::WRITABLE);
|
||||
unsafe {
|
||||
flush_tlb_entry(DYNAMIC_MAP_OFFSET + ((i + j) << L3::SHIFT));
|
||||
}
|
||||
}
|
||||
let addr = DYNAMIC_MAP_OFFSET + (i << L3::SHIFT);
|
||||
return Ok(addr);
|
||||
}
|
||||
|
||||
Err(Error::OutOfMemory)
|
||||
}
|
||||
|
||||
fn entry(&self, index: usize) -> &PageEntry<L3> {
|
||||
&self.l3s[index / 1024][index % 1024]
|
||||
}
|
||||
|
||||
fn entry_mut(&mut self, index: usize) -> &mut PageEntry<L3> {
|
||||
&mut self.l3s[index / 1024][index % 1024]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
||||
@ -83,5 +131,7 @@ pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
||||
dst[i + KERNEL_SPLIT_L0] = *entry;
|
||||
}
|
||||
|
||||
// TODO dynamic entries
|
||||
for (i, entry) in unsafe { KERNEL_TABLES.l0.dynamic.iter().enumerate() } {
|
||||
dst[i + KERNEL_SPLIT_L0 + FIXED_MAP_COUNT] = *entry;
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,12 @@ use kernel_arch_interface::{
|
||||
mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping},
|
||||
KERNEL_VIRT_OFFSET,
|
||||
};
|
||||
use libk_mm_interface::{address::PhysicalAddress, KernelImageObject};
|
||||
use table::{PageAttributes, PageEntry};
|
||||
use libk_mm_interface::{
|
||||
address::{AsPhysicalAddress, PhysicalAddress},
|
||||
table::page_count,
|
||||
KernelImageObject,
|
||||
};
|
||||
use table::{PageAttributes, PageEntry, L3};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
pub mod fixed;
|
||||
@ -28,6 +32,7 @@ impl KernelTableManager for KernelTableManagerImpl {
|
||||
) -> Result<RawDeviceMemoryMapping<Self>, Error> {
|
||||
// TODO page align up
|
||||
let end = base + count as u64;
|
||||
assert_eq!(base & 0xFFF, 0);
|
||||
if end < fixed::MAX_FIXED_PHYSICAL.into_u64() {
|
||||
// 1:1
|
||||
let address = Self::virtualize(base);
|
||||
@ -35,12 +40,19 @@ impl KernelTableManager for KernelTableManagerImpl {
|
||||
address, address, 0, 0,
|
||||
))
|
||||
} else {
|
||||
loop {}
|
||||
assert_eq!(base & 0xFFF, 0);
|
||||
log::info!("map_device_pages({:#x}, {})", base, count);
|
||||
let page_count = page_count::<L3>(count);
|
||||
let virt = KERNEL_TABLES.map_dynamic_memory(base, page_count)?;
|
||||
|
||||
Ok(RawDeviceMemoryMapping::from_raw_parts(
|
||||
virt, virt, page_count, 0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn unmap_device_pages(mapping: &RawDeviceMemoryMapping<Self>) {
|
||||
loop {}
|
||||
unsafe fn unmap_device_pages(_mapping: &RawDeviceMemoryMapping<Self>) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn virtualize(phys: u64) -> usize {
|
||||
@ -68,6 +80,14 @@ pub unsafe fn init_fixed_tables() {
|
||||
*entry = PageEntry::block(PhysicalAddress::from_u32(phys), PageAttributes::WRITABLE);
|
||||
flush_tlb_entry(virt);
|
||||
}
|
||||
|
||||
for (l0_entry, entry) in Iterator::zip(
|
||||
KERNEL_TABLES.l0.dynamic.iter_mut(),
|
||||
KERNEL_TABLES.dynamic.lock().l3s.iter(),
|
||||
) {
|
||||
let phys = entry.as_physical_address();
|
||||
*l0_entry = PageEntry::table(phys, PageAttributes::WRITABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
|
@ -6,3 +6,6 @@ edition = "2021"
|
||||
[dependencies]
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
device-api = { path = "../../lib/device-api", features = ["derive"] }
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||
|
@ -124,13 +124,19 @@ pub trait TaskContext<K: KernelTableManager, PA: PhysicalMemoryAllocator>: Sized
|
||||
// XXX
|
||||
/// Constructs a safe wrapper process to execute a kernel-space closure
|
||||
fn kernel_closure<F: FnOnce() -> ! + Send + 'static>(f: F) -> Result<Self, Error> {
|
||||
extern "C" fn closure_wrapper<F: FnOnce() -> ! + Send + 'static>(closure_addr: usize) -> ! {
|
||||
extern "C" fn closure_wrapper<F: FnOnce() -> ! + Send + 'static>(
|
||||
mut closure_addr: usize,
|
||||
) -> ! {
|
||||
if closure_addr == 0 {
|
||||
closure_addr = align_of::<F>();
|
||||
}
|
||||
let closure = unsafe { Box::from_raw(closure_addr as *mut F) };
|
||||
closure()
|
||||
}
|
||||
|
||||
let closure = Box::new(f);
|
||||
Self::kernel(closure_wrapper::<F>, Box::into_raw(closure) as usize)
|
||||
let ptr = Box::into_raw(closure) as usize;
|
||||
Self::kernel(closure_wrapper::<F>, ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,8 +70,8 @@ pub struct ExceptionFrame {
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct SyscallFrame {
|
||||
pub rax: u64,
|
||||
pub args: [u64; 6],
|
||||
pub rax: usize,
|
||||
pub args: [usize; 6],
|
||||
|
||||
pub rcx: u64,
|
||||
pub r11: u64,
|
||||
@ -254,23 +254,23 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
}
|
||||
|
||||
fn set_return_value(&mut self, value: u64) {
|
||||
self.rax = value;
|
||||
self.rax = value as _;
|
||||
}
|
||||
}
|
||||
|
||||
impl TaskFrame for SyscallFrame {
|
||||
fn store(&self) -> SavedFrame {
|
||||
SavedFrame {
|
||||
rax: self.rax,
|
||||
rax: self.rax as _,
|
||||
rcx: self.rcx,
|
||||
rdx: self.args[2],
|
||||
rdx: self.args[2] as _,
|
||||
rbx: self.rbx,
|
||||
rsi: self.args[1],
|
||||
rdi: self.args[0],
|
||||
rsi: self.args[1] as _,
|
||||
rdi: self.args[0] as _,
|
||||
rbp: self.rbp,
|
||||
r8: self.args[4],
|
||||
r9: self.args[5],
|
||||
r10: self.args[3],
|
||||
r8: self.args[4] as _,
|
||||
r9: self.args[5] as _,
|
||||
r10: self.args[3] as _,
|
||||
r11: self.r11,
|
||||
r12: self.r12,
|
||||
r13: self.r13,
|
||||
@ -283,13 +283,13 @@ impl TaskFrame for SyscallFrame {
|
||||
}
|
||||
|
||||
fn restore(&mut self, saved: &SavedFrame) {
|
||||
self.rax = saved.rax;
|
||||
self.args[0] = saved.rdi;
|
||||
self.args[1] = saved.rsi;
|
||||
self.args[2] = saved.rdx;
|
||||
self.args[3] = saved.r10;
|
||||
self.args[4] = saved.r8;
|
||||
self.args[5] = saved.r9;
|
||||
self.rax = saved.rax as _;
|
||||
self.args[0] = saved.rdi as _;
|
||||
self.args[1] = saved.rsi as _;
|
||||
self.args[2] = saved.rdx as _;
|
||||
self.args[3] = saved.r10 as _;
|
||||
self.args[4] = saved.r8 as _;
|
||||
self.args[5] = saved.r9 as _;
|
||||
|
||||
self.rcx = saved.rcx;
|
||||
self.r11 = saved.r11;
|
||||
@ -307,7 +307,7 @@ impl TaskFrame for SyscallFrame {
|
||||
}
|
||||
|
||||
fn argument(&self) -> u64 {
|
||||
self.args[0]
|
||||
self.args[0] as _
|
||||
}
|
||||
|
||||
fn user_sp(&self) -> usize {
|
||||
@ -327,11 +327,11 @@ impl TaskFrame for SyscallFrame {
|
||||
}
|
||||
|
||||
fn set_return_value(&mut self, value: u64) {
|
||||
self.rax = value;
|
||||
self.rax = value as _;
|
||||
}
|
||||
|
||||
fn set_argument(&mut self, value: u64) {
|
||||
self.args[0] = value;
|
||||
self.args[0] = value as _;
|
||||
}
|
||||
|
||||
fn set_single_step(&mut self, step: bool) {
|
||||
|
@ -17,3 +17,6 @@ tock-registers = "0.8.1"
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
acpi = { git = "https://github.com/alnyan/acpi.git", package = "acpi", branch = "acpi-system" }
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||
|
@ -50,7 +50,9 @@ pub enum PreferredInterruptMode {
|
||||
enum ConfiguredInterruptMode {
|
||||
MsiX(MsiXVectorTable<'static>),
|
||||
Msi,
|
||||
Legacy(PciInterruptPin),
|
||||
LegacyPin(PciInterruptPin),
|
||||
#[cfg_attr(not(target_arch = "x86"), allow(unused))]
|
||||
LegacyLine(u8),
|
||||
None,
|
||||
}
|
||||
|
||||
@ -102,11 +104,11 @@ impl PciDeviceInfo {
|
||||
} else if self.config_space.capability::<MsiCapability>().is_some() {
|
||||
ConfiguredInterruptMode::Msi
|
||||
} else {
|
||||
self.interrupt_mode_from_pin()
|
||||
self.legacy_interrupt_mode()
|
||||
}
|
||||
} else {
|
||||
// Ignore preferred_mode, the only supported is Legacy
|
||||
self.interrupt_mode_from_pin()
|
||||
self.legacy_interrupt_mode()
|
||||
};
|
||||
|
||||
IrqSafeRwLock::new(InterruptConfig {
|
||||
@ -119,9 +121,16 @@ impl PciDeviceInfo {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn interrupt_mode_from_pin(&self) -> ConfiguredInterruptMode {
|
||||
fn legacy_interrupt_mode(&self) -> ConfiguredInterruptMode {
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
{
|
||||
if let Some(irq) = self.config_space.interrupt_line() {
|
||||
return ConfiguredInterruptMode::LegacyLine(irq);
|
||||
}
|
||||
}
|
||||
|
||||
match self.config_space.interrupt_pin() {
|
||||
Some(pin) => ConfiguredInterruptMode::Legacy(pin),
|
||||
Some(pin) => ConfiguredInterruptMode::LegacyPin(pin),
|
||||
None => ConfiguredInterruptMode::None,
|
||||
}
|
||||
}
|
||||
@ -149,10 +158,14 @@ impl PciDeviceInfo {
|
||||
|
||||
Ok(Some(info))
|
||||
}
|
||||
ConfiguredInterruptMode::Legacy(pin) => {
|
||||
ConfiguredInterruptMode::LegacyPin(pin) => {
|
||||
self.try_map_legacy(*pin, handler)?;
|
||||
Ok(None)
|
||||
}
|
||||
ConfiguredInterruptMode::LegacyLine(irq) => {
|
||||
self.try_map_legacy_line(*irq, handler)?;
|
||||
Ok(None)
|
||||
}
|
||||
ConfiguredInterruptMode::None => Err(Error::InvalidOperation),
|
||||
}
|
||||
}
|
||||
@ -203,6 +216,16 @@ impl PciDeviceInfo {
|
||||
|
||||
register_global_interrupt(route.number, route.options, handler)
|
||||
}
|
||||
|
||||
fn try_map_legacy_line(
|
||||
&self,
|
||||
line: u8,
|
||||
handler: &'static dyn InterruptHandler,
|
||||
) -> Result<(), Error> {
|
||||
log::debug!("PCI {} -> IRQ#{}", self.address, line);
|
||||
|
||||
register_global_interrupt(line as _, Default::default(), handler)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for PciInterruptPin {
|
||||
|
@ -122,7 +122,7 @@ struct BusAddressAllocator {
|
||||
offset_32: u32,
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "x86_64", allow(dead_code))]
|
||||
#[cfg_attr(any(target_arch = "x86_64", target_arch = "x86"), allow(dead_code))]
|
||||
impl BusAddressAllocator {
|
||||
pub fn from_ranges(ranges: &[PciAddressRange]) -> Self {
|
||||
let mut range_32 = None;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
use libk_util::OneTimeInit;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::{PciAddress, PciConfigurationSpace};
|
||||
|
@ -220,6 +220,15 @@ pub trait PciConfigurationSpace {
|
||||
PciInterruptPin::try_from(self.read_u8(0x3D) as u32).ok()
|
||||
}
|
||||
|
||||
fn interrupt_line(&self) -> Option<u8> {
|
||||
let value = self.read_u8(0x3C);
|
||||
if value < 16 {
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is only meant to be called before the device has seen any use by the OS,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::any::Any;
|
||||
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use libk::{
|
||||
block,
|
||||
error::Error,
|
||||
@ -63,7 +63,7 @@ impl SymlinkNode {
|
||||
}
|
||||
|
||||
impl CommonImpl for SymlinkNode {
|
||||
fn size(&self, node: &NodeRef) -> Result<u64, Error> {
|
||||
fn size(&self, _node: &NodeRef) -> Result<u64, Error> {
|
||||
Ok(self.inode.size_lower as _)
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ impl CommonImpl for SymlinkNode {
|
||||
self
|
||||
}
|
||||
|
||||
fn metadata(&self, node: &NodeRef) -> Result<Metadata, Error> {
|
||||
fn metadata(&self, _node: &NodeRef) -> Result<Metadata, Error> {
|
||||
Ok(self.inode.metadata())
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ use core::task::{Context, Poll};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use async_trait::async_trait;
|
||||
use libk::vfs::{CharDevice, FileReadiness, TerminalInput};
|
||||
use libk_util::{ring::LossyRingQueue, sync::spin_rwlock::IrqSafeRwLock, StaticVector};
|
||||
use libk::vfs::{CharDevice, FileReadiness};
|
||||
use libk_util::ring::LossyRingQueue;
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{DeviceRequest, KeyboardKeyEvent},
|
||||
|
@ -92,6 +92,7 @@ impl NetworkInterface {
|
||||
ArpTable::flush_address(self.id, address);
|
||||
}
|
||||
|
||||
log::info!("Assigned address: {:?} -> {:?}", self.name, address);
|
||||
addr.replace(address);
|
||||
|
||||
ArpTable::insert_address(self.id, self.mac, address, true);
|
||||
|
@ -100,12 +100,11 @@ pub fn probe(info: &PciDeviceInfo) -> Result<&'static dyn Device, Error> {
|
||||
cmd |= PciCommandRegister::ENABLE_MEMORY | PciCommandRegister::BUS_MASTER;
|
||||
info.config_space.set_command(cmd.bits());
|
||||
|
||||
todo!()
|
||||
// let regs = unsafe { xhci_lib::Registers::new(bar0.into(), Mapper::new()) };
|
||||
// let xhci = Box::leak(Box::new(Xhci::new(regs)?));
|
||||
let regs = unsafe { xhci_lib::Registers::new(bar0.try_into_usize().unwrap(), Mapper::new()) };
|
||||
let xhci = Box::leak(Box::new(Xhci::new(regs)?));
|
||||
|
||||
// info.init_interrupts(PreferredInterruptMode::Msi)?;
|
||||
// info.map_interrupt(InterruptAffinity::Any, xhci)?;
|
||||
info.init_interrupts(PreferredInterruptMode::Msi)?;
|
||||
info.map_interrupt(InterruptAffinity::Any, xhci)?;
|
||||
|
||||
// Ok(xhci)
|
||||
Ok(xhci)
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ pub struct VirtQueue {
|
||||
|
||||
impl AvailableRing {
|
||||
pub fn with_capacity(no_irq: bool, capacity: usize) -> Result<Self, Error> {
|
||||
let mut data = PageBox::new_uninit_slice(capacity + 3)?;
|
||||
let mut data = PageBox::new_zeroed_slice(capacity + 3)?;
|
||||
|
||||
if no_irq {
|
||||
data[0].write(1);
|
||||
@ -86,7 +86,7 @@ impl AvailableRing {
|
||||
|
||||
impl UsedRing {
|
||||
pub fn with_capacity(capacity: usize) -> Result<Self, Error> {
|
||||
let mut data = PageBox::new_uninit_slice(capacity * 2 + 2)?;
|
||||
let mut data = PageBox::new_zeroed_slice(capacity * 2 + 2)?;
|
||||
|
||||
data[0].write(0);
|
||||
|
||||
@ -127,7 +127,7 @@ impl VirtQueue {
|
||||
return Err(Error::QueueTooLarge);
|
||||
}
|
||||
|
||||
let descriptor_table = PageBox::new_uninit_slice(capacity)?;
|
||||
let descriptor_table = PageBox::new_zeroed_slice(capacity)?;
|
||||
let available = AvailableRing::with_capacity(no_avail_irq, capacity)?;
|
||||
let used = UsedRing::with_capacity(capacity)?;
|
||||
|
||||
|
@ -14,3 +14,6 @@ discrete_range_map = { git = "https://git.alnyan.me/yggdrasil/discrete_range_map
|
||||
[dev-dependencies]
|
||||
itertools = "0.11.0"
|
||||
proptest = "1.2.0"
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||
|
@ -12,3 +12,6 @@ kernel-arch-interface = { path = "../../../arch/interface" }
|
||||
|
||||
bitflags = "2.6.0"
|
||||
bytemuck = { version = "1.16.1", features = ["derive"] }
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Kernel's global heap allocator
|
||||
use core::{
|
||||
alloc::{GlobalAlloc, Layout},
|
||||
ptr::{null_mut, NonNull},
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
use kernel_arch::KernelTableManagerImpl;
|
||||
@ -52,8 +52,7 @@ unsafe impl GlobalAlloc for KernelAllocator {
|
||||
match self.inner.lock().allocate(layout) {
|
||||
Some(p) => p.as_ptr(),
|
||||
None => {
|
||||
log::error!("Failed to allocate {:?}", layout);
|
||||
null_mut()
|
||||
panic!("Failed to allocate {:?}", layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,17 +79,20 @@ impl PhysicalMemoryAllocator for GlobalPhysicalAllocator {
|
||||
|
||||
/// Allocates a single physical page from the global manager
|
||||
pub fn alloc_page() -> Result<PhysicalAddress, Error> {
|
||||
PHYSICAL_MEMORY.get().lock().alloc_page()
|
||||
let p = PHYSICAL_MEMORY.get().lock().alloc_page();
|
||||
p
|
||||
}
|
||||
|
||||
/// Allocates a contiguous range of physical pages from the global manager
|
||||
pub fn alloc_pages_contiguous(count: usize) -> Result<PhysicalAddress, Error> {
|
||||
PHYSICAL_MEMORY.get().lock().alloc_contiguous_pages(count)
|
||||
let p = PHYSICAL_MEMORY.get().lock().alloc_contiguous_pages(count);
|
||||
p
|
||||
}
|
||||
|
||||
/// Allocates a single 2MiB page of physical memory from the global manager
|
||||
pub fn alloc_2m_page() -> Result<PhysicalAddress, Error> {
|
||||
PHYSICAL_MEMORY.get().lock().alloc_2m_page()
|
||||
let p = PHYSICAL_MEMORY.get().lock().alloc_2m_page();
|
||||
p
|
||||
}
|
||||
|
||||
/// Returns physical memory stats
|
||||
|
@ -54,6 +54,15 @@ impl<T: Copy> RingBuffer<T> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reserve(&mut self) -> Result<(), Error> {
|
||||
if self.data.is_none() {
|
||||
let buffer =
|
||||
Box::try_new_uninit_slice(self.capacity).map_err(|_| Error::OutOfMemory)?;
|
||||
self.data = Some(buffer);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const fn readable_count_at(&self, at: usize) -> usize {
|
||||
if at <= self.wr {
|
||||
self.wr - at
|
||||
|
@ -57,7 +57,11 @@ pub fn load_kernel_symbol_table<P: AsRef<Path>>(
|
||||
ioctx: &mut IoContext,
|
||||
path: P,
|
||||
) -> Result<(), Error> {
|
||||
let symbol_file = ioctx.open(None, path, OpenOptions::READ, FileMode::empty())?;
|
||||
let symbol_file = match ioctx.open(None, path, OpenOptions::READ, FileMode::empty()) {
|
||||
Ok(file) => file,
|
||||
Err(Error::DoesNotExist) => return Ok(()),
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
let mut string_buffer = PageBox::new_slice(0, 4096)?;
|
||||
let mut map = DefaultHashTable::new();
|
||||
|
||||
|
@ -472,9 +472,8 @@ fn write_rela(rela: &Rela, space: &ProcessAddressSpace, b: usize) -> Result<(),
|
||||
|
||||
match width {
|
||||
8 => {
|
||||
todo!();
|
||||
// unsafe { (dst.as_mut_ptr() as *mut u64).write_volatile(value as u64) };
|
||||
// Ok(())
|
||||
unsafe { (dst.as_mut_ptr() as *mut u64).write_volatile(value as u64) };
|
||||
Ok(())
|
||||
}
|
||||
_ => todo!("Unhandled relocation width: {}", width),
|
||||
}
|
||||
|
@ -147,6 +147,7 @@ fn setup_context(
|
||||
virt_stack_base + USER_STACK_PAGES * 0x1000 - TaskContextImpl::USER_STACK_EXTRA_ALIGN;
|
||||
|
||||
// Fill with some sentinel value to detect stack underflows
|
||||
#[allow(unused_mut)]
|
||||
let mut ptr = user_sp as *mut usize;
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
|
@ -1,6 +1,5 @@
|
||||
use core::{
|
||||
fmt,
|
||||
mem::size_of,
|
||||
sync::atomic::{AtomicU32, AtomicU64, Ordering},
|
||||
};
|
||||
|
||||
@ -157,6 +156,8 @@ impl AllocateProcessId for ProcessId {
|
||||
impl ProcessTlsLayout {
|
||||
/// Constructs a new thread-local storage layout info struct
|
||||
pub fn new(align: usize, data_size: usize, mem_size: usize) -> Self {
|
||||
use core::mem::size_of;
|
||||
|
||||
debug_assert!(align.is_power_of_two());
|
||||
let tls_block0_offset = (size_of::<usize>() * 2 + align - 1) & !(align - 1);
|
||||
|
||||
@ -178,6 +179,8 @@ impl ProcessTlsLayout {
|
||||
impl ProcessTlsLayout {
|
||||
/// Constructs a new thread-local storage layout info struct
|
||||
pub fn new(align: usize, data_size: usize, mem_size: usize) -> Self {
|
||||
use core::mem::size_of;
|
||||
|
||||
// The static TLS blocks are placed below TP
|
||||
// TP points to the TCB
|
||||
debug_assert!(align.is_power_of_two());
|
||||
@ -201,7 +204,7 @@ impl ProcessTlsLayout {
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
impl ProcessTlsLayout {
|
||||
pub fn new(align: usize, data_size: usize, mem_size: usize) -> Self {
|
||||
pub fn new(_align: usize, _data_size: usize, _mem_size: usize) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
2
kernel/modules/test_mod/Cargo.lock
generated
2
kernel/modules/test_mod/Cargo.lock
generated
@ -263,7 +263,7 @@ dependencies = [
|
||||
"device-api",
|
||||
"kernel-arch-interface",
|
||||
"libk-mm-interface",
|
||||
"memtables",
|
||||
"log",
|
||||
"static_assertions",
|
||||
"tock-registers",
|
||||
"yggdrasil-abi",
|
||||
|
@ -175,7 +175,7 @@ fn el0_sync_inner(frame: &mut ExceptionFrame) {
|
||||
// SVC in AArch64
|
||||
0b010101 => {
|
||||
let func = frame.r[8];
|
||||
if func == usize::from(SyscallFunction::ExitSignal) as u64 {
|
||||
if func == usize::from(SyscallFunction::ExitSignal) {
|
||||
unsafe {
|
||||
syscall::handle_signal_exit(frame);
|
||||
}
|
||||
@ -183,7 +183,7 @@ fn el0_sync_inner(frame: &mut ExceptionFrame) {
|
||||
}
|
||||
|
||||
let args = &frame.r[0..6];
|
||||
let result = raw_syscall_handler(func, args);
|
||||
let result = raw_syscall_handler(func, args) as _;
|
||||
frame.r[0] = result;
|
||||
}
|
||||
// Software Step from lower Exception Level
|
||||
|
@ -1,121 +1,16 @@
|
||||
use core::arch::global_asm;
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use kernel_arch_i686::{
|
||||
mem::KERNEL_TABLES,
|
||||
registers::{CR0, CR4},
|
||||
};
|
||||
use kernel_fs::devfs;
|
||||
use libk::task::runtime;
|
||||
use libk_mm::{
|
||||
address::{PhysicalAddress, Virtualize},
|
||||
phys::PhysicalMemoryRegion,
|
||||
pointer::PhysicalRef,
|
||||
};
|
||||
use tock_registers::interfaces::ReadWriteable;
|
||||
use kernel_arch_i686::mem::KERNEL_TABLES;
|
||||
use libk_mm::{address::PhysicalAddress, pointer::PhysicalRef};
|
||||
use multiboot::MultibootInfo;
|
||||
|
||||
use crate::{arch::x86::gdt, kernel_main, mem::KERNEL_VIRT_OFFSET};
|
||||
use crate::{kernel_main, mem::KERNEL_VIRT_OFFSET};
|
||||
|
||||
use super::{exception, I686, PLATFORM};
|
||||
use super::PLATFORM;
|
||||
|
||||
const BOOT_STACK_SIZE: usize = 64 * 1024;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct MultibootInfo {
|
||||
pub flags: u32,
|
||||
pub mem_lower: u32,
|
||||
pub mem_upper: u32,
|
||||
pub boot_device: u32,
|
||||
pub cmdline: u32,
|
||||
pub mods_count: u32,
|
||||
pub mods_addr: u32,
|
||||
pub syms: [u32; 4],
|
||||
pub mmap_length: u32,
|
||||
pub mmap_addr: u32,
|
||||
// ...
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MultibootMemoryMapIter<'a> {
|
||||
multiboot_info: &'a MultibootInfo,
|
||||
base: usize,
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MultibootModuleIter<'a> {
|
||||
multiboot_info: &'a MultibootInfo,
|
||||
base: usize,
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C, packed)]
|
||||
pub struct MultibootMemoryMapEntry {
|
||||
pub size: u32,
|
||||
pub addr: u64,
|
||||
pub len: u64,
|
||||
pub ty: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct MultibootModuleEntry {
|
||||
pub mod_start: u32,
|
||||
pub mod_end: u32,
|
||||
pub cmdline: u32,
|
||||
_pad: u32,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for MultibootMemoryMapIter<'a> {
|
||||
type Item = PhysicalMemoryRegion;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if self.pos + size_of::<MultibootMemoryMapEntry>()
|
||||
>= self.multiboot_info.mmap_length as usize
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let entry: &MultibootMemoryMapEntry =
|
||||
unsafe { core::mem::transmute(self.base + self.pos) };
|
||||
|
||||
self.pos += entry.size as usize + size_of::<u32>();
|
||||
|
||||
if !entry.is_available() {
|
||||
continue;
|
||||
}
|
||||
|
||||
return Some(PhysicalMemoryRegion {
|
||||
base: PhysicalAddress::from_u64(entry.addr),
|
||||
size: entry.len.try_into().unwrap(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MultibootInfo {
|
||||
pub fn memory_map_iter(&self) -> MultibootMemoryMapIter {
|
||||
MultibootMemoryMapIter {
|
||||
multiboot_info: self,
|
||||
base: PhysicalAddress::from_u32(self.mmap_addr).virtualize(),
|
||||
pos: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modules(&self) -> &[MultibootModuleEntry] {
|
||||
let base = PhysicalAddress::from_u32(self.mods_addr).virtualize();
|
||||
unsafe { core::slice::from_raw_parts(base as *const _, self.mods_count as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
impl MultibootMemoryMapEntry {
|
||||
pub fn is_available(&self) -> bool {
|
||||
self.ty == 1
|
||||
}
|
||||
}
|
||||
pub mod multiboot;
|
||||
|
||||
#[repr(C, align(0x20))]
|
||||
struct BootStack {
|
||||
|
94
kernel/src/arch/i686/boot/multiboot.rs
Normal file
94
kernel/src/arch/i686/boot/multiboot.rs
Normal file
@ -0,0 +1,94 @@
|
||||
use libk_mm::{
|
||||
address::{PhysicalAddress, Virtualize},
|
||||
phys::PhysicalMemoryRegion,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct MultibootInfo {
|
||||
pub flags: u32,
|
||||
pub mem_lower: u32,
|
||||
pub mem_upper: u32,
|
||||
pub boot_device: u32,
|
||||
pub cmdline: u32,
|
||||
pub mods_count: u32,
|
||||
pub mods_addr: u32,
|
||||
pub syms: [u32; 4],
|
||||
pub mmap_length: u32,
|
||||
pub mmap_addr: u32,
|
||||
// ...
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MultibootMemoryMapIter<'a> {
|
||||
multiboot_info: &'a MultibootInfo,
|
||||
base: usize,
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C, packed)]
|
||||
pub struct MultibootMemoryMapEntry {
|
||||
pub size: u32,
|
||||
pub addr: u64,
|
||||
pub len: u64,
|
||||
pub ty: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct MultibootModuleEntry {
|
||||
pub mod_start: u32,
|
||||
pub mod_end: u32,
|
||||
pub cmdline: u32,
|
||||
_pad: u32,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for MultibootMemoryMapIter<'a> {
|
||||
type Item = PhysicalMemoryRegion;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if self.pos + size_of::<MultibootMemoryMapEntry>()
|
||||
>= self.multiboot_info.mmap_length as usize
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let entry: &MultibootMemoryMapEntry =
|
||||
unsafe { core::mem::transmute(self.base + self.pos) };
|
||||
|
||||
self.pos += entry.size as usize + size_of::<u32>();
|
||||
|
||||
if !entry.is_available() {
|
||||
continue;
|
||||
}
|
||||
|
||||
return Some(PhysicalMemoryRegion {
|
||||
base: PhysicalAddress::from_u64(entry.addr),
|
||||
size: entry.len.try_into().unwrap(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MultibootInfo {
|
||||
pub fn memory_map_iter(&self) -> MultibootMemoryMapIter {
|
||||
MultibootMemoryMapIter {
|
||||
multiboot_info: self,
|
||||
base: PhysicalAddress::from_u32(self.mmap_addr).virtualize(),
|
||||
pos: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modules(&self) -> &[MultibootModuleEntry] {
|
||||
let base = PhysicalAddress::from_u32(self.mods_addr).virtualize();
|
||||
unsafe { core::slice::from_raw_parts(base as *const _, self.mods_count as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
impl MultibootMemoryMapEntry {
|
||||
pub fn is_available(&self) -> bool {
|
||||
self.ty == 1
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
use core::{arch::global_asm, ptr::addr_of};
|
||||
|
||||
use abi::{primitive_enum, process::Signal};
|
||||
use abi::{primitive_enum, process::Signal, SyscallFunction};
|
||||
use kernel_arch_i686::context::{ExceptionFrame, SyscallFrame};
|
||||
use libk::task::thread::Thread;
|
||||
use static_assertions::const_assert_eq;
|
||||
|
||||
use crate::{arch::x86::peripherals::i8259, syscall};
|
||||
|
||||
@ -165,7 +164,7 @@ fn kernel_exception_inner(kind: ExceptionKind, frame: &ExceptionFrame) -> ! {
|
||||
panic!("Irrecoverable exception")
|
||||
}
|
||||
|
||||
fn user_exception_inner(kind: ExceptionKind, frame: &ExceptionFrame) {
|
||||
fn user_exception_inner(kind: ExceptionKind, _frame: &ExceptionFrame) {
|
||||
let thread = Thread::current();
|
||||
let cr3: usize;
|
||||
unsafe {
|
||||
@ -214,6 +213,21 @@ extern "C" fn __i686_exception_handler(frame: *mut ExceptionFrame) {
|
||||
|
||||
extern "C" fn __i686_syscall_handler(frame: *mut SyscallFrame) {
|
||||
let frame = unsafe { &mut *frame };
|
||||
|
||||
if frame.eax == usize::from(SyscallFunction::ExitSignal) {
|
||||
unsafe {
|
||||
syscall::handle_signal_exit(frame);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if frame.eax == usize::from(SyscallFunction::Fork) {
|
||||
todo!()
|
||||
// unsafe {
|
||||
// Process::raw_fork(frame);
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO check that cs == 0x1B, kernel to kernel syscalls disallowed
|
||||
let result = syscall::raw_syscall_handler(frame.eax, &frame.args);
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
#![allow(missing_docs)]
|
||||
use abi::{
|
||||
error::Error,
|
||||
io::{KeyboardKey, KeyboardKeyEvent},
|
||||
};
|
||||
use boot::{MultibootInfo, MultibootMemoryMapEntry};
|
||||
use abi::error::Error;
|
||||
use boot::multiboot::MultibootInfo;
|
||||
use device_api::{
|
||||
interrupt::{IpiDeliveryTarget, IpiMessage, Irq},
|
||||
Device, ResetDevice,
|
||||
@ -14,7 +11,7 @@ use kernel_fs::devfs::{self, CharDeviceType};
|
||||
use libk::{
|
||||
arch::Cpu,
|
||||
task::runtime,
|
||||
vfs::{CharDevice, Terminal, TerminalInput},
|
||||
vfs::{Terminal, TerminalInput},
|
||||
};
|
||||
use libk_device::{register_external_interrupt_controller, register_monotonic_timestamp_provider};
|
||||
use libk_mm::{
|
||||
@ -40,7 +37,7 @@ use crate::{
|
||||
debug::{self, LogLevel},
|
||||
device::{
|
||||
self,
|
||||
display::console::{add_console_autoflush, ConsoleWrapper, DisplayConsole},
|
||||
display::console::{add_console_autoflush, ConsoleWrapper},
|
||||
},
|
||||
fs::{Initrd, INITRD_DATA},
|
||||
};
|
||||
@ -89,7 +86,7 @@ impl Platform for I686 {
|
||||
loop {}
|
||||
}
|
||||
|
||||
unsafe fn send_ipi(&self, target: IpiDeliveryTarget, msg: IpiMessage) -> Result<(), Error> {
|
||||
unsafe fn send_ipi(&self, _target: IpiDeliveryTarget, _msg: IpiMessage) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -97,8 +94,8 @@ impl Platform for I686 {
|
||||
// No APs in i686, go get a better CPU
|
||||
}
|
||||
|
||||
fn register_reset_device(&self, reset: &'static dyn ResetDevice) -> Result<(), Error> {
|
||||
loop {}
|
||||
fn register_reset_device(&self, _reset: &'static dyn ResetDevice) -> Result<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,8 +132,6 @@ impl I686 {
|
||||
.init(ComPort::new(0x3F8, 0x3E8, Irq::External(4)));
|
||||
debug::add_sink(com1_3.port_a(), LogLevel::Debug);
|
||||
|
||||
debug::init();
|
||||
|
||||
reserve_region(
|
||||
"lowmem",
|
||||
PhysicalMemoryRegion {
|
||||
@ -169,6 +164,8 @@ impl I686 {
|
||||
// Initialize physical memory
|
||||
phys::init_from_iter(multiboot_info.memory_map_iter(), |_, _, _| Ok(()))?;
|
||||
|
||||
debug::init();
|
||||
|
||||
unsafe {
|
||||
gdt::init();
|
||||
exception::init_exceptions();
|
||||
@ -180,6 +177,29 @@ impl I686 {
|
||||
runtime::init_task_queue();
|
||||
devfs::init();
|
||||
|
||||
// Register the PCI drivers
|
||||
// TODO make this implicit init
|
||||
ygg_driver_pci::register_class_driver(
|
||||
"AHCI SATA Controller",
|
||||
0x01,
|
||||
Some(0x06),
|
||||
Some(0x01),
|
||||
ygg_driver_ahci::probe,
|
||||
);
|
||||
ygg_driver_pci::register_class_driver(
|
||||
"USB xHCI",
|
||||
0x0C,
|
||||
Some(0x03),
|
||||
Some(0x30),
|
||||
ygg_driver_usb_xhci::probe,
|
||||
);
|
||||
ygg_driver_pci::register_vendor_driver(
|
||||
"Virtio PCI Network Device",
|
||||
0x1AF4,
|
||||
0x1000,
|
||||
ygg_driver_virtio_net::probe,
|
||||
);
|
||||
|
||||
I8259.init().expect("Could not initialize i8259 PIC");
|
||||
register_external_interrupt_controller(&I8259);
|
||||
I8253.init().expect("Could not initialize i8253 Timer");
|
||||
|
@ -135,7 +135,7 @@ fn convert_attrs(ch: &ConsoleChar) -> u8 {
|
||||
if attr.contains(Attributes::BOLD) {
|
||||
fg += 8;
|
||||
}
|
||||
(fg | (bg << 4))
|
||||
fg | (bg << 4)
|
||||
}
|
||||
|
||||
fn convert_color(c: ColorAttribute) -> u8 {
|
||||
|
@ -1,7 +1,3 @@
|
||||
use core::mem::size_of;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
struct Entry {
|
||||
@ -31,9 +27,6 @@ impl Entry {
|
||||
#[allow(unused)]
|
||||
const ACC_ACCESS: u8 = 1 << 0;
|
||||
|
||||
const FLAG_4K: u8 = 1 << 7;
|
||||
const FLAG_32: u8 = 1 << 6;
|
||||
|
||||
const NULL: Self = Self {
|
||||
base_lo: 0,
|
||||
base_mi: 0,
|
||||
@ -57,6 +50,8 @@ impl Entry {
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
mod imp {
|
||||
use core::ptr::addr_of_mut;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use super::{Entry, Pointer};
|
||||
@ -64,6 +59,9 @@ mod imp {
|
||||
pub use kernel_arch_i686::gdt::{Tss, TSS};
|
||||
|
||||
impl Entry {
|
||||
const FLAG_4K: u8 = 1 << 7;
|
||||
const FLAG_32: u8 = 1 << 6;
|
||||
|
||||
const RING0_CS32: Entry = Entry::new(
|
||||
0,
|
||||
0xFFFFF,
|
||||
@ -99,12 +97,12 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_gdt() -> (&'static [Entry], &'static Tss) {
|
||||
pub(super) fn create_gdt() -> (&'static [Entry], &'static Tss) {
|
||||
// Won't be deallocated, so leaks are not a concern
|
||||
let tss = unsafe { &mut TSS };
|
||||
let tss = unsafe { &mut *addr_of_mut!(TSS) };
|
||||
tss.ss0 = 0x10;
|
||||
let tss_addr = (tss as *mut Tss).addr();
|
||||
let mut gdt = Box::new([
|
||||
let gdt = Box::new([
|
||||
Entry::NULL,
|
||||
Entry::RING0_CS32,
|
||||
Entry::RING0_DS32,
|
||||
@ -116,7 +114,7 @@ mod imp {
|
||||
(Box::leak(gdt), tss)
|
||||
}
|
||||
|
||||
pub unsafe fn load_gdt(gdt: &'static [Entry]) {
|
||||
pub(super) unsafe fn load_gdt(gdt: &'static [Entry]) {
|
||||
let gdt_addr = gdt.as_ptr().addr();
|
||||
let gdtr = Pointer {
|
||||
limit: (gdt.len() * size_of::<Entry>()) as u16 - 1,
|
||||
@ -150,11 +148,13 @@ mod imp {
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
mod imp {
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use super::{Entry, Pointer};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
struct Tss {
|
||||
pub struct Tss {
|
||||
_0: u32,
|
||||
rsp0: u64,
|
||||
rsp1: u64,
|
||||
@ -230,10 +230,10 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_gdt() -> (&'static [Entry], &'static Tss) {
|
||||
pub(super) fn create_gdt() -> (&'static [Entry], &'static Tss) {
|
||||
// Won't be deallocated, so leaks are not a concern
|
||||
let tss = Box::leak(Box::new(Tss::NULL));
|
||||
let tss_addr = (tss as *mut _).addr();
|
||||
let tss_addr = (tss as *mut Tss).addr();
|
||||
let mut gdt = Box::new([
|
||||
Entry::NULL,
|
||||
Entry::RING0_CS64,
|
||||
@ -247,16 +247,13 @@ mod imp {
|
||||
let tss_high = &mut gdt[6] as *mut _ as *mut u64;
|
||||
unsafe { tss_high.write_unaligned((tss_addr >> 32) as u64) };
|
||||
|
||||
Box::leak(gdt)
|
||||
|
||||
// let gdt_addr = Box::into_raw(gdt) as usize;
|
||||
|
||||
// todo!()
|
||||
(Box::leak(gdt), tss)
|
||||
}
|
||||
|
||||
pub unsafe fn load_gdt(gdt: &'static [Entry]) {
|
||||
pub(super) unsafe fn load_gdt(gdt: &'static [Entry]) {
|
||||
let gdt_addr = gdt.as_ptr().addr();
|
||||
let gdtr = Pointer {
|
||||
limit: (GDT_SIZE * size_of::<Entry>()) as u16 - 1,
|
||||
limit: (gdt.len() * size_of::<Entry>()) as u16 - 1,
|
||||
offset: gdt_addr,
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
pub const ISA_IRQ_OFFSET: u32 = ISA_IRQ_OFFSET;
|
||||
pub const ISA_IRQ_OFFSET: u32 = crate::arch::x86_64::ISA_IRQ_OFFSET;
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
pub const ISA_IRQ_OFFSET: u32 = 0;
|
||||
|
@ -1,7 +1,5 @@
|
||||
//! Intel 8259 interrupt controller
|
||||
|
||||
use core::arch::global_asm;
|
||||
|
||||
use abi::error::Error;
|
||||
use device_api::{
|
||||
interrupt::{
|
||||
@ -10,18 +8,14 @@ use device_api::{
|
||||
},
|
||||
Device,
|
||||
};
|
||||
use kernel_arch::task::Scheduler;
|
||||
use kernel_arch_i686::context::InterruptFrame;
|
||||
use libk::{
|
||||
arch::Cpu,
|
||||
task::{sched, thread::Thread},
|
||||
};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
|
||||
use crate::arch::{
|
||||
i686::exception,
|
||||
x86::intrinsics::{IoPort, IoPortAccess},
|
||||
};
|
||||
use crate::arch::x86::intrinsics::{IoPort, IoPortAccess};
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
use crate::arch::i686::exception;
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
use kernel_arch_i686::context::InterruptFrame;
|
||||
|
||||
use super::i8253::I8253;
|
||||
|
||||
@ -56,6 +50,7 @@ impl Device for I8259 {
|
||||
impl ExternalInterruptController for I8259 {
|
||||
fn enable_irq(&self, irq: Irq) -> Result<(), Error> {
|
||||
let Irq::External(irq) = irq else { panic!() };
|
||||
log::debug!("Enable IRQ#{}", irq);
|
||||
let inner = self.inner.lock();
|
||||
let port = if irq < 8 {
|
||||
&inner.master_data
|
||||
@ -63,7 +58,6 @@ impl ExternalInterruptController for I8259 {
|
||||
&inner.slave_data
|
||||
};
|
||||
let mask = port.read();
|
||||
log::debug!("Enable IRQ#{}", irq);
|
||||
port.write(mask & !(1 << (irq % 8)));
|
||||
Ok(())
|
||||
}
|
||||
@ -71,7 +65,7 @@ impl ExternalInterruptController for I8259 {
|
||||
fn register_irq(
|
||||
&self,
|
||||
irq: Irq,
|
||||
options: IrqOptions,
|
||||
_options: IrqOptions,
|
||||
handler: &'static dyn InterruptHandler,
|
||||
) -> Result<(), Error> {
|
||||
let Irq::External(irq) = irq else {
|
||||
@ -96,15 +90,13 @@ impl ExternalInterruptController for I8259 {
|
||||
I8253.irq_handler_fastpath();
|
||||
} else if index < 16 {
|
||||
// Rest of IRQs
|
||||
self.eoi(index);
|
||||
|
||||
let table = self.table.lock();
|
||||
|
||||
if let Some(handler) = table.handler(index - 1) {
|
||||
handler.handle_irq(None);
|
||||
} else {
|
||||
warnln!("No handler set for IRQ#{}", index);
|
||||
}
|
||||
|
||||
self.eoi(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,16 +153,19 @@ impl I8259 {
|
||||
inner.master_data.write(ICW4_8086);
|
||||
inner.slave_data.write(ICW4_8086);
|
||||
|
||||
// Mask everything
|
||||
inner.master_data.write(0xFF);
|
||||
// Mask everything (except IRQ#2 on master, used for cascading)
|
||||
inner.master_data.write(0xFF & !(1 << 2));
|
||||
inner.slave_data.write(0xFF);
|
||||
|
||||
inner.master_cmd.write(0x20);
|
||||
inner.slave_cmd.write(0x20);
|
||||
}
|
||||
|
||||
pub fn eoi(&self, index: usize) {
|
||||
let inner = self.inner.lock();
|
||||
|
||||
inner.master_cmd.write(0x20);
|
||||
if index >= 12 {
|
||||
if index >= 8 {
|
||||
inner.slave_cmd.write(0x20);
|
||||
}
|
||||
}
|
||||
@ -178,6 +173,7 @@ impl I8259 {
|
||||
|
||||
pub static I8259: I8259 = I8259::new();
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
pub fn setup_vectors(idt: &mut [exception::Entry]) {
|
||||
extern "C" {
|
||||
// IRQ vectors
|
||||
@ -193,7 +189,10 @@ pub fn setup_vectors(idt: &mut [exception::Entry]) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
extern "C" fn irq_handler(frame: *mut InterruptFrame) {
|
||||
use libk::task::thread::Thread;
|
||||
|
||||
let frame = unsafe { &mut *frame };
|
||||
|
||||
I8259.handle_specific_irq(frame.irq_number as _);
|
||||
@ -203,4 +202,5 @@ extern "C" fn irq_handler(frame: *mut InterruptFrame) {
|
||||
}
|
||||
}
|
||||
|
||||
global_asm!(include_str!("i8259_vectors.S"), irq_handler = sym irq_handler, options(att_syntax));
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
core::arch::global_asm!(include_str!("i8259_vectors.S"), irq_handler = sym irq_handler, options(att_syntax));
|
||||
|
@ -31,19 +31,11 @@ mod apic;
|
||||
mod boot;
|
||||
mod cpuid;
|
||||
mod exception;
|
||||
#[path = "../i686/intrinsics.rs"]
|
||||
mod intrinsics;
|
||||
mod smp;
|
||||
mod syscall;
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
x86::peripherals::{i8253::I8253, i8259::I8259, ps2::PS2},
|
||||
x86_64::{
|
||||
apic::ioapic::ISA_IRQ_OFFSET,
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
},
|
||||
},
|
||||
arch::x86::peripherals::{i8253::I8253, i8259::I8259, ps2::PS2, serial::ComPort},
|
||||
debug::{self, LogLevel},
|
||||
device::{
|
||||
self,
|
||||
@ -57,10 +49,15 @@ use self::{
|
||||
apic::{ioapic::IoApic, local::LocalApic},
|
||||
boot::BootData,
|
||||
cpuid::{ProcessorFeatures, PROCESSOR_FEATURES},
|
||||
peripherals::{i8253::I8253, ps2::PS2Controller, serial::ComPort},
|
||||
};
|
||||
|
||||
use super::{IpiMessage, Platform};
|
||||
use super::{
|
||||
x86::{gdt, intrinsics},
|
||||
IpiMessage, Platform,
|
||||
};
|
||||
|
||||
/// Offset where legacy ISA IRQs are remapped
|
||||
pub const ISA_IRQ_OFFSET: u32 = apic::ioapic::ISA_IRQ_OFFSET;
|
||||
|
||||
/// x86-64 architecture implementation
|
||||
pub struct X86_64 {
|
||||
@ -342,7 +339,7 @@ impl X86_64 {
|
||||
|
||||
I8253.init_irq()?;
|
||||
// ps2.connect(self.tty.get());
|
||||
ps2.init_irq()?;
|
||||
PS2.init_irq()?;
|
||||
|
||||
device::register_device(&PS2);
|
||||
|
||||
|
@ -13,13 +13,13 @@ use tock_registers::interfaces::{ReadWriteable, Writeable};
|
||||
use crate::syscall::{self, raw_syscall_handler};
|
||||
|
||||
fn syscall_inner(frame: &mut SyscallFrame) {
|
||||
if frame.rax == usize::from(SyscallFunction::ExitSignal) as u64 {
|
||||
if frame.rax == usize::from(SyscallFunction::ExitSignal) {
|
||||
unsafe {
|
||||
syscall::handle_signal_exit(frame);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if frame.rax == usize::from(SyscallFunction::Fork) as u64 {
|
||||
if frame.rax == usize::from(SyscallFunction::Fork) {
|
||||
unsafe {
|
||||
Process::raw_fork(frame);
|
||||
return;
|
||||
@ -28,7 +28,7 @@ fn syscall_inner(frame: &mut SyscallFrame) {
|
||||
|
||||
let result = raw_syscall_handler(frame.rax, &frame.args);
|
||||
|
||||
frame.rax = result;
|
||||
frame.rax = result as _;
|
||||
}
|
||||
|
||||
extern "C" fn __x86_64_syscall_handler(frame: *mut SyscallFrame) {
|
||||
|
@ -1,5 +1,8 @@
|
||||
//! Utilities for debug information logging
|
||||
use core::fmt::{self, Arguments};
|
||||
use core::{
|
||||
fmt::{self, Arguments},
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use abi::error::Error;
|
||||
use libk::task::process::Process;
|
||||
@ -8,6 +11,8 @@ use libk_util::{ring::RingBuffer, sync::IrqSafeSpinlock, StaticVector};
|
||||
const MAX_DEBUG_SINKS: usize = 4;
|
||||
const RING_LOGGER_CAPACITY: usize = 65536;
|
||||
|
||||
static RING_AVAILABLE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
struct SimpleLogger;
|
||||
|
||||
struct RingLoggerInner {
|
||||
@ -178,6 +183,10 @@ impl RingLoggerSink {
|
||||
use fmt::Write;
|
||||
self.inner.lock().write_fmt(args)
|
||||
}
|
||||
|
||||
fn init_buffer(&self) -> Result<(), Error> {
|
||||
self.inner.lock().data.reserve()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for RingLoggerInner {
|
||||
@ -252,6 +261,10 @@ pub fn program_trace(process: &Process, message: &str) {
|
||||
|
||||
/// Resets the debugging terminal by clearing it
|
||||
pub fn init() {
|
||||
if RING_LOGGER_SINK.init_buffer().is_ok() {
|
||||
RING_AVAILABLE.store(true, Ordering::Release);
|
||||
}
|
||||
|
||||
log::set_logger(&LOGGER)
|
||||
.map(|_| log::set_max_level(log::LevelFilter::Trace))
|
||||
.ok();
|
||||
@ -263,7 +276,9 @@ pub fn init() {
|
||||
pub fn debug_internal(args: Arguments, level: LogLevel) {
|
||||
use fmt::Write;
|
||||
|
||||
// RING_LOGGER_SINK.write_fmt(args).ok();
|
||||
if RING_AVAILABLE.load(Ordering::Acquire) {
|
||||
RING_LOGGER_SINK.write_fmt(args).ok();
|
||||
}
|
||||
|
||||
for sink in DEBUG_SINKS.lock().iter_mut() {
|
||||
if level < sink.level {
|
||||
|
@ -71,7 +71,7 @@ pub fn kinit() -> Result<(), Error> {
|
||||
|
||||
// TODO move this to userspace so it doesn't block the init process, maybe lazy-load on first
|
||||
// attempt to load a module?
|
||||
// load_kernel_symbol_table(&mut ioctx, "/kernel.sym")?;
|
||||
load_kernel_symbol_table(&mut ioctx, "/kernel.sym")?;
|
||||
|
||||
{
|
||||
let group_id = Process::create_group();
|
||||
|
@ -37,7 +37,6 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use arch::Platform;
|
||||
use kernel_arch::{Architecture, ArchitectureImpl};
|
||||
use libk::arch::Cpu;
|
||||
|
@ -209,12 +209,16 @@ pub(crate) fn mutex(mutex: &AtomicU32, op: &MutexOperation) -> Result<(), Error>
|
||||
let mutex = process.get_or_insert_mutex((mutex as *const AtomicU32).addr());
|
||||
|
||||
match op {
|
||||
&MutexOperation::Wait(value, _timeout) => block! { mutex.wait(value).await }.unwrap(),
|
||||
MutexOperation::Wake => mutex.wake(),
|
||||
MutexOperation::WakeAll => mutex.wake_all(),
|
||||
}
|
||||
|
||||
&MutexOperation::Wait(value, _timeout) => block! { mutex.wait(value).await },
|
||||
MutexOperation::Wake => {
|
||||
mutex.wake();
|
||||
Ok(())
|
||||
}
|
||||
MutexOperation::WakeAll => {
|
||||
mutex.wake_all();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn start_session() -> Result<(), Error> {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct SavedFrame {
|
||||
pub gp_regs: [u64; 32],
|
||||
pub gp_regs: [usize; 32],
|
||||
pub spsr_el1: u64,
|
||||
pub elr_el1: u64,
|
||||
pub sp_el0: u64,
|
||||
|
@ -14,7 +14,7 @@ use super::{
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
|
||||
#[repr(C)]
|
||||
#[repr(C, packed)]
|
||||
pub struct EthernetFrame {
|
||||
pub destination_mac: MacAddress,
|
||||
pub source_mac: MacAddress,
|
||||
|
@ -6,7 +6,6 @@ use std::{
|
||||
fd::AsRawFd,
|
||||
yggdrasil::{
|
||||
io::{poll::PollChannel, raw_socket::RawSocket, timer::TimerFd},
|
||||
signal::{set_signal_handler, Signal, SignalHandler},
|
||||
},
|
||||
},
|
||||
process::ExitCode,
|
||||
@ -319,14 +318,10 @@ fn ping(
|
||||
Ok(stats)
|
||||
}
|
||||
|
||||
fn interrupt(_: Signal) {
|
||||
INTERRUPTED.store(true, Ordering::Release);
|
||||
}
|
||||
|
||||
static INTERRUPTED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
fn main() -> ExitCode {
|
||||
set_signal_handler(Signal::Interrupted, SignalHandler::Function(interrupt));
|
||||
// set_signal_handler(Signal::Interrupted, SignalHandler::Function(interrupt));
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::fs::{self, File};
|
||||
use std::fs;
|
||||
|
||||
use crate::{env::BuildEnv, error::Error, util::run_external_command};
|
||||
|
||||
|
@ -87,12 +87,15 @@ pub fn build_all(env: BuildEnv) -> Result<AllBuilt, Error> {
|
||||
Arch::i686 => KernelProcessed(kernel),
|
||||
_ => generate_kernel_tables(&env.kernel_symbol_file, kernel, tools)?,
|
||||
};
|
||||
// let modules = build_modules(&env, env.workspace_root.join("kernel/modules"))?;
|
||||
let modules = match env.arch {
|
||||
Arch::i686 => Vec::new(),
|
||||
_ => build_modules(&env, env.workspace_root.join("kernel/modules"))?,
|
||||
};
|
||||
|
||||
let mut install_extra = vec![];
|
||||
// for module in modules {
|
||||
// install_extra.push((module.clone(), module.file_name().unwrap().into()));
|
||||
// }
|
||||
for module in modules {
|
||||
install_extra.push((module.clone(), module.file_name().unwrap().into()));
|
||||
}
|
||||
|
||||
// Userspace stuff
|
||||
let initrd = userspace::build_initrd(&env, install_extra, check)?;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// #![deny(warnings)]
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::{fs, path::PathBuf, process::ExitCode};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user