Squashed some bugs; implemented first iteration of kernel items
This commit is contained in:
parent
a2311366f2
commit
04ee0a1cb2
13 changed files with 245 additions and 111 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -4,6 +4,7 @@
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"kernel/Cargo.toml",
|
"kernel/Cargo.toml",
|
||||||
"kernel/aphrodite_proc_macros/Cargo.toml",
|
"kernel/aphrodite_proc_macros/Cargo.toml",
|
||||||
"kernel/aphrodite_common/Cargo.toml"
|
"kernel/aphrodite_common/Cargo.toml",
|
||||||
|
"user/Cargo.toml"
|
||||||
],
|
],
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
display_library: x, options="gui_debug"
|
display_library: x, options="gui_debug"
|
||||||
port_e9_hack: enabled=1
|
port_e9_hack: enabled=1
|
||||||
cpu: reset_on_triple_fault=0, model=tigerlake
|
cpu: reset_on_triple_fault=0, model=corei7_icelake_u
|
||||||
magic_break: enabled=1
|
magic_break: enabled=1
|
||||||
|
|
||||||
ata0-master: type=cdrom, path=../kernel/aphrodite.iso, status=inserted
|
ata0-master: type=cdrom, path=../kernel/aphrodite.iso, status=inserted
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# config.aphro for aphrodite devel-6a2a677-out-of-tree
|
# config.aphro for aphrodite devel-6a2a677-out-of-tree
|
||||||
CFG_VERSION=devel-6a2a677-out-of-tree
|
CFG_VERSION=devel-6a2a677-out-of-tree
|
||||||
CONT_WITH_DIFFERENT_VERSION=false
|
CONT_WITH_DIFFERENT_VERSION=true
|
||||||
|
|
||||||
# Begin metadata
|
# Begin metadata
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
RUSTFLAGS='-Clink-arg=--script=link.x' cargo expand --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint
|
RUSTFLAGS='-Clink-arg=--script=link.x' cargo expand --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint_x86
|
|
@ -220,18 +220,18 @@ extern "C" fn _start() -> ! {
|
||||||
ptr = (ptr + current_tag.tag_len as usize + 7) & !7;
|
ptr = (ptr + current_tag.tag_len as usize + 7) & !7;
|
||||||
if ptr>end_addr {
|
if ptr>end_addr {
|
||||||
cfg_match! {
|
cfg_match! {
|
||||||
cfg(all(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH = "true", CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false")) => {
|
all(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH = "true", CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false") => {
|
||||||
serrorsln("Current tag length would put pointer out-of-bounds; CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH is set, continuing");
|
serrorsln("Current tag length would put pointer out-of-bounds; CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH is set, continuing");
|
||||||
}
|
}
|
||||||
cfg(all(CONFIG_PREUSER_WARN_ON_INVALID_LENGTH = "true", CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false")) => {
|
all(CONFIG_PREUSER_WARN_ON_INVALID_LENGTH = "true", CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false") => {
|
||||||
swarningsln("Current tag length would put pointer out-of-bounds; CONFIG_PREUSER_WARN_ON_INVALID_LENGTH is set, continuing");
|
swarningsln("Current tag length would put pointer out-of-bounds; CONFIG_PREUSER_WARN_ON_INVALID_LENGTH is set, continuing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg_match! {
|
cfg_match! {
|
||||||
cfg(not(CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false")) => {
|
not(CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false") => {
|
||||||
panic!("current tag length would put pointer out-of-bounds")
|
panic!("current tag length would put pointer out-of-bounds")
|
||||||
}
|
}
|
||||||
cfg(CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH = "true") => {
|
CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH = "true" => {
|
||||||
sinfos("Exiting loop as current tag length would put pointer out-of-bounds ");
|
sinfos("Exiting loop as current tag length would put pointer out-of-bounds ");
|
||||||
sinfosnpln("and CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH is set");
|
sinfosnpln("and CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH is set");
|
||||||
break;
|
break;
|
||||||
|
@ -263,7 +263,7 @@ extern "C" fn _start() -> ! {
|
||||||
sdebugs("Framebuffer bpp: ");
|
sdebugs("Framebuffer bpp: ");
|
||||||
sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp));
|
sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp));
|
||||||
|
|
||||||
sdebugsln("Beginning output to screen...");
|
sdebugsln("Beginning test output to screen...");
|
||||||
|
|
||||||
let ega: &dyn aphrodite::display::TextDisplay = &framebuffer_info;
|
let ega: &dyn aphrodite::display::TextDisplay = &framebuffer_info;
|
||||||
framebuffer_info.disable_cursor();
|
framebuffer_info.disable_cursor();
|
||||||
|
@ -272,11 +272,11 @@ extern "C" fn _start() -> ! {
|
||||||
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||||
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||||
|
|
||||||
aphrodite::indep_boot_entry::indep_boot_entry(Some(ega), &BI);
|
aphrodite::indep_boot_entry::IndepBootEntry(Some(ega), &BI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aphrodite::indep_boot_entry::indep_boot_entry(None, &BI);
|
aphrodite::indep_boot_entry::IndepBootEntry(None, &BI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(link_section = ".panic")]
|
#[unsafe(link_section = ".panic")]
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
use syn::{parse::Parse, Ident};
|
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
use strum_macros::EnumIter;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, EnumIter)]
|
|
||||||
pub enum KernelItem {
|
|
||||||
IndepBootEntry,
|
|
||||||
ArchBootEntry,
|
|
||||||
SyscallSetup,
|
|
||||||
MemMapGen,
|
|
||||||
MemMapAlloc,
|
|
||||||
PreuserModLoad,
|
|
||||||
InitEnv,
|
|
||||||
KernelFSMount,
|
|
||||||
StorageFSMount,
|
|
||||||
PreuserMod,
|
|
||||||
RamLoader,
|
|
||||||
UserInit,
|
|
||||||
UserModLoad,
|
|
||||||
ProcessFSMount
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for KernelItem {
|
|
||||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
||||||
let ident: Ident = input.parse()?;
|
|
||||||
|
|
||||||
for variant in Self::iter() {
|
|
||||||
let name = format!("{:?}", variant);
|
|
||||||
|
|
||||||
if ident.to_string().as_str() == name {
|
|
||||||
return Ok(variant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(syn::Error::new(ident.span(), "Expected one of aphrodite_common::KernelItem's variants"))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,11 @@ const MEM_TEST_SIZES: [usize; 8] = [1, 2, 4, 8, 16, 32, 64, 128];
|
||||||
|
|
||||||
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files eventually call this.
|
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files eventually call this.
|
||||||
#[kernel_item(IndepBootEntry)]
|
#[kernel_item(IndepBootEntry)]
|
||||||
pub fn indep_boot_entry(display: Option<&dyn crate::display::TextDisplay>, BI: &crate::boot::BootInfo) -> ! {
|
fn indep_boot_entry(
|
||||||
|
display: Option<&dyn crate::display::TextDisplay>,
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
BI: &crate::boot::BootInfo,
|
||||||
|
) -> ! {
|
||||||
crate::arch::output::sdebugsln("Entrypoint called");
|
crate::arch::output::sdebugsln("Entrypoint called");
|
||||||
|
|
||||||
let display = display.unwrap();
|
let display = display.unwrap();
|
||||||
|
@ -21,18 +25,19 @@ pub fn indep_boot_entry(display: Option<&dyn crate::display::TextDisplay>, BI: &
|
||||||
display.clear_screen(COLOR_DEFAULT);
|
display.clear_screen(COLOR_DEFAULT);
|
||||||
sreset();
|
sreset();
|
||||||
|
|
||||||
let mut mem_map = BI.memory_map.unwrap();
|
let mem_map = BI.memory_map.unwrap();
|
||||||
let allocator_res = crate::mem::MemoryMapAlloc::new(&mut mem_map);
|
crate::mem::MemMapAllocInit(mem_map).unwrap();
|
||||||
if allocator_res.is_err() {
|
let allocator = crate::mem::MemMapAlloc().unwrap();
|
||||||
panic!("{}", allocator_res.unwrap_err());
|
|
||||||
}
|
|
||||||
let allocator = allocator_res.unwrap();
|
|
||||||
|
|
||||||
tdebugsln("Testing allocator...", display).unwrap();
|
tdebugsln("Testing allocator...", display).unwrap();
|
||||||
|
|
||||||
for size in MEM_TEST_SIZES {
|
for size in MEM_TEST_SIZES {
|
||||||
tdebugs("Number of allocations: ", display).unwrap();
|
tdebugs("Number of allocations: ", display).unwrap();
|
||||||
tdebugbnpln(&crate::u64_as_u8_slice(allocator.number_of_allocations()), display).unwrap();
|
tdebugbnpln(
|
||||||
|
&crate::u64_as_u8_slice(allocator.number_of_allocations()),
|
||||||
|
display,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
tdebugs("Allocating ", display).unwrap();
|
tdebugs("Allocating ", display).unwrap();
|
||||||
tdebugbnp(&crate::usize_as_u8_slice(size), display).unwrap();
|
tdebugbnp(&crate::usize_as_u8_slice(size), display).unwrap();
|
||||||
|
@ -49,7 +54,12 @@ pub fn indep_boot_entry(display: Option<&dyn crate::display::TextDisplay>, BI: &
|
||||||
tdebugsnpln(".", display).unwrap();
|
tdebugsnpln(".", display).unwrap();
|
||||||
tdebugsln("", display).unwrap();
|
tdebugsln("", display).unwrap();
|
||||||
tdebugsln("Deallocating memory...", display).unwrap();
|
tdebugsln("Deallocating memory...", display).unwrap();
|
||||||
unsafe { allocator.deallocate(ptr.as_non_null_ptr(), Layout::from_size_align(size, 1).unwrap()) }
|
unsafe {
|
||||||
|
allocator.deallocate(
|
||||||
|
ptr.as_non_null_ptr(),
|
||||||
|
Layout::from_size_align(size, 1).unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
if let Err(err) = unsafe { crate::mem::LAST_MEMMAP_ERR } {
|
if let Err(err) = unsafe { crate::mem::LAST_MEMMAP_ERR } {
|
||||||
terrors("Failed to deallocate: ", display).unwrap();
|
terrors("Failed to deallocate: ", display).unwrap();
|
||||||
err.display_np(display);
|
err.display_np(display);
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
//! Memory allocation.
|
//! Memory allocation.
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
alloc::{Allocator, GlobalAlloc}, fmt::Debug, num::NonZero, ops::Range, ptr::{null_mut, NonNull}
|
alloc::{Allocator, GlobalAlloc},
|
||||||
|
fmt::Debug,
|
||||||
|
mem::MaybeUninit,
|
||||||
|
num::NonZero,
|
||||||
|
ops::Range,
|
||||||
|
ptr::{NonNull, null_mut},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::boot::MemoryType;
|
use crate::boot::{MemoryMap, MemoryType};
|
||||||
|
|
||||||
|
use aphrodite_proc_macros::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Allocation {
|
struct Allocation {
|
||||||
|
@ -56,6 +63,42 @@ impl Iterator for AllocationIter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mut ALLOCATOR: MaybeUninit<MemoryMapAlloc<'static>> = MaybeUninit::uninit();
|
||||||
|
static mut ALLOCATOR_MEMMAP: MaybeUninit<MemoryMap> = MaybeUninit::uninit();
|
||||||
|
static mut ALLOCATOR_INITALIZED: bool = false;
|
||||||
|
|
||||||
|
#[kernel_item(MemMapAlloc)]
|
||||||
|
fn get_allocator() -> Option<&'static MemoryMapAlloc<'static>> {
|
||||||
|
if unsafe { ALLOCATOR_INITALIZED } {
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
return Some(unsafe { ALLOCATOR.assume_init_ref() });
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[kernel_item(MemMapAllocInit)]
|
||||||
|
fn memory_map_alloc_init(
|
||||||
|
memmap: crate::boot::MemoryMap,
|
||||||
|
) -> Result<(), crate::Error<'static>> {
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
unsafe {
|
||||||
|
ALLOCATOR_MEMMAP.write(memmap);
|
||||||
|
}
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
let alloc = MemoryMapAlloc::new(unsafe { ALLOCATOR_MEMMAP.assume_init_mut() })?;
|
||||||
|
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
unsafe {
|
||||||
|
ALLOCATOR.write(alloc);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
ALLOCATOR_INITALIZED = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// A implementation of a physical memory allocator that uses a [crate::boot::MemoryMap].
|
/// A implementation of a physical memory allocator that uses a [crate::boot::MemoryMap].
|
||||||
pub struct MemoryMapAlloc<'a> {
|
pub struct MemoryMapAlloc<'a> {
|
||||||
/// The memory map to use to allocate memory.
|
/// The memory map to use to allocate memory.
|
||||||
|
@ -84,7 +127,12 @@ const EXTEND_ALLOCATION_OTHER_ALLOCATION: i16 = -6;
|
||||||
impl<'a> Debug for MemoryMapAlloc<'a> {
|
impl<'a> Debug for MemoryMapAlloc<'a> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.write_str("MemoryMapAlloc with ")?;
|
f.write_str("MemoryMapAlloc with ")?;
|
||||||
f.write_str(core::str::from_utf8(&crate::u64_as_u8_slice(unsafe { *self.allocationheader }.num_allocations)).unwrap())?;
|
f.write_str(
|
||||||
|
core::str::from_utf8(&crate::u64_as_u8_slice(
|
||||||
|
unsafe { *self.allocationheader }.num_allocations,
|
||||||
|
))
|
||||||
|
.unwrap(),
|
||||||
|
)?;
|
||||||
f.write_str(" allocations")?;
|
f.write_str(" allocations")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -115,7 +163,9 @@ impl<'a> MemoryMapAlloc<'a> {
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
out.allocations = core::ptr::from_raw_parts_mut(
|
out.allocations = core::ptr::from_raw_parts_mut(
|
||||||
core::ptr::without_provenance_mut::<()>(mapping.start as usize+size_of::<AllocationHeader>()),
|
core::ptr::without_provenance_mut::<()>(
|
||||||
|
mapping.start as usize + size_of::<AllocationHeader>(),
|
||||||
|
),
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
out.max_allocations_size = mapping.len;
|
out.max_allocations_size = mapping.len;
|
||||||
|
@ -126,7 +176,9 @@ impl<'a> MemoryMapAlloc<'a> {
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
out.allocations = core::ptr::from_raw_parts_mut(
|
out.allocations = core::ptr::from_raw_parts_mut(
|
||||||
core::ptr::without_provenance_mut::<()>(mapping.start as usize+size_of::<AllocationHeader>()),
|
core::ptr::without_provenance_mut::<()>(
|
||||||
|
mapping.start as usize + size_of::<AllocationHeader>(),
|
||||||
|
),
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
out.max_allocations_size = mapping.len;
|
out.max_allocations_size = mapping.len;
|
||||||
|
@ -149,7 +201,7 @@ impl<'a> MemoryMapAlloc<'a> {
|
||||||
used: true,
|
used: true,
|
||||||
addr: out.allocations as usize as u64,
|
addr: out.allocations as usize as u64,
|
||||||
len: (size_of::<Allocation>() * 32) as u64,
|
len: (size_of::<Allocation>() * 32) as u64,
|
||||||
num_allocations: 1
|
num_allocations: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(out)
|
Ok(out)
|
||||||
|
@ -182,10 +234,10 @@ impl<'a> MemoryMapAlloc<'a> {
|
||||||
|
|
||||||
let num_allocations = unsafe { *self.allocationheader }.num_allocations;
|
let num_allocations = unsafe { *self.allocationheader }.num_allocations;
|
||||||
|
|
||||||
if unsafe { *self.allocations }.len
|
if unsafe { *self.allocations }.len < (size_of::<Allocation>() as u64 * (num_allocations)) {
|
||||||
< (size_of::<Allocation>() as u64 * (num_allocations))
|
if unsafe { *self.allocationheader }.len + size_of::<Allocation>() as u64
|
||||||
|
>= self.max_allocations_size
|
||||||
{
|
{
|
||||||
if unsafe { *self.allocationheader }.len + size_of::<Allocation>() as u64 >= self.max_allocations_size {
|
|
||||||
return Err(crate::Error::new(
|
return Err(crate::Error::new(
|
||||||
"not enough space for another allocation",
|
"not enough space for another allocation",
|
||||||
TOO_MANY_ALLOCATIONS,
|
TOO_MANY_ALLOCATIONS,
|
||||||
|
@ -266,7 +318,9 @@ impl<'a> MemoryMapAlloc<'a> {
|
||||||
|
|
||||||
/// Check to see if any allocations contain the given address. Returns true if so.
|
/// Check to see if any allocations contain the given address. Returns true if so.
|
||||||
fn check_addr(&self, addr: u64) -> bool {
|
fn check_addr(&self, addr: u64) -> bool {
|
||||||
if addr >= (self.allocationheader as u64) && addr < (self.allocationheader as u64+unsafe { *self.allocationheader }.len) {
|
if addr >= (self.allocationheader as u64)
|
||||||
|
&& addr < (self.allocationheader as u64 + unsafe { *self.allocationheader }.len)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for ele in self.allocations_iter() {
|
for ele in self.allocations_iter() {
|
||||||
|
@ -346,10 +400,16 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
|
||||||
}
|
}
|
||||||
if allocatable {
|
if allocatable {
|
||||||
addr = mapping.start + mapping.len - layout.size() as u64;
|
addr = mapping.start + mapping.len - layout.size() as u64;
|
||||||
while self.check_range(addr..addr+layout.size() as u64) && (addr as usize % layout.align() != 0) && addr >= mapping.start {
|
while self.check_range(addr..addr + layout.size() as u64)
|
||||||
|
&& (addr as usize % layout.align() != 0)
|
||||||
|
&& addr >= mapping.start
|
||||||
|
{
|
||||||
addr -= layout.size() as u64 / crate::cfg_int!("CONFIG_ALLOC_PRECISION", u64);
|
addr -= layout.size() as u64 / crate::cfg_int!("CONFIG_ALLOC_PRECISION", u64);
|
||||||
}
|
}
|
||||||
if (!self.check_range(addr..addr+layout.size() as u64)) && (addr as usize % layout.align() == 0) && addr >= mapping.start {
|
if (!self.check_range(addr..addr + layout.size() as u64))
|
||||||
|
&& (addr as usize % layout.align() == 0)
|
||||||
|
&& addr >= mapping.start
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -364,7 +424,11 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
|
||||||
}
|
}
|
||||||
return Err(core::alloc::AllocError {});
|
return Err(core::alloc::AllocError {});
|
||||||
}
|
}
|
||||||
if let Err(err) = self.add_allocation(Allocation { used: true, addr, len: layout.size() as u64 }) {
|
if let Err(err) = self.add_allocation(Allocation {
|
||||||
|
used: true,
|
||||||
|
addr,
|
||||||
|
len: layout.size() as u64,
|
||||||
|
}) {
|
||||||
unsafe { LAST_MEMMAP_ERR = Err(err) }
|
unsafe { LAST_MEMMAP_ERR = Err(err) }
|
||||||
return Err(core::alloc::AllocError {});
|
return Err(core::alloc::AllocError {});
|
||||||
}
|
}
|
||||||
|
@ -387,7 +451,9 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(unsafe { *self.allocationheader }.num_allocations));
|
crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(
|
||||||
|
unsafe { *self.allocationheader }.num_allocations,
|
||||||
|
));
|
||||||
for allocation in self.allocations_iter() {
|
for allocation in self.allocations_iter() {
|
||||||
crate::arch::output::sdebugsln("Allocation");
|
crate::arch::output::sdebugsln("Allocation");
|
||||||
let alloc = unsafe { *allocation }.clone();
|
let alloc = unsafe { *allocation }.clone();
|
||||||
|
@ -401,7 +467,12 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Memory not allocated, something is up, this is put after the loop to prevent a costly call to check_addr
|
// Memory not allocated, something is up, this is put after the loop to prevent a costly call to check_addr
|
||||||
unsafe { LAST_MEMMAP_ERR = Err(crate::Error::new("memory not allocated", MEMORY_NOT_ALLOCATED)) }
|
unsafe {
|
||||||
|
LAST_MEMMAP_ERR = Err(crate::Error::new(
|
||||||
|
"memory not allocated",
|
||||||
|
MEMORY_NOT_ALLOCATED,
|
||||||
|
))
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,32 @@
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::{quote_spanned, ToTokens};
|
use quote::{ToTokens, quote};
|
||||||
use syn::{parse::{Parse, ParseStream}, spanned::Spanned, ItemFn, Signature, Token};
|
use syn::{
|
||||||
|
ItemFn, Signature, Token,
|
||||||
|
parse::{Parse, ParseStream}
|
||||||
|
};
|
||||||
|
|
||||||
struct KernelItemNameInput {
|
struct KernelItemNameInput {
|
||||||
item: aphrodite_common::KernelItem
|
item: syn::Ident,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for KernelItemNameInput {
|
impl Parse for KernelItemNameInput {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
let item: aphrodite_common::KernelItem = input.parse()?;
|
let item: syn::Ident = input.parse()?;
|
||||||
Ok(KernelItemNameInput { item })
|
Ok(KernelItemNameInput { item })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_tokens(signature: Signature, tokens: &mut TokenStream) {
|
fn to_tokens(signature: Signature, tokens: &mut proc_macro2::TokenStream) {
|
||||||
signature.constness.to_tokens(&mut (*tokens).clone().into());
|
let ts = tokens;
|
||||||
signature.asyncness.to_tokens(&mut (*tokens).clone().into());
|
signature.constness.to_tokens(ts.into());
|
||||||
signature.unsafety.to_tokens(&mut (*tokens).clone().into());
|
signature.asyncness.to_tokens(ts.into());
|
||||||
signature.abi.to_tokens(&mut (*tokens).clone().into());
|
signature.unsafety.to_tokens(ts.into());
|
||||||
signature.fn_token.to_tokens(&mut (*tokens).clone().into());
|
signature.abi.to_tokens(ts.into());
|
||||||
signature.generics.to_tokens(&mut (*tokens).clone().into());
|
signature.fn_token.to_tokens(ts.into());
|
||||||
signature.paren_token.surround(&mut (*tokens).clone().into(), |tokens| {
|
signature.generics.to_tokens(ts.into());
|
||||||
|
signature
|
||||||
|
.paren_token
|
||||||
|
.surround(ts.into(), |tokens| {
|
||||||
signature.inputs.to_tokens(tokens);
|
signature.inputs.to_tokens(tokens);
|
||||||
if let Some(variadic) = &signature.variadic {
|
if let Some(variadic) = &signature.variadic {
|
||||||
if !signature.inputs.empty_or_trailing() {
|
if !signature.inputs.empty_or_trailing() {
|
||||||
|
@ -29,12 +35,15 @@ fn to_tokens(signature: Signature, tokens: &mut TokenStream) {
|
||||||
variadic.to_tokens(tokens);
|
variadic.to_tokens(tokens);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
signature.output.to_tokens(&mut (*tokens).clone().into());
|
signature.output.to_tokens(ts.into());
|
||||||
signature.generics.where_clause.to_tokens(&mut (*tokens).clone().into());
|
signature
|
||||||
|
.generics
|
||||||
|
.where_clause
|
||||||
|
.to_tokens(ts.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_token_stream(signature: Signature) -> TokenStream {
|
fn to_token_stream(signature: Signature) -> proc_macro2::TokenStream {
|
||||||
let mut tokens = proc_macro::TokenStream::new();
|
let mut tokens = proc_macro2::TokenStream::new();
|
||||||
to_tokens(signature, &mut tokens);
|
to_tokens(signature, &mut tokens);
|
||||||
tokens.into()
|
tokens.into()
|
||||||
}
|
}
|
||||||
|
@ -42,18 +51,19 @@ fn to_token_stream(signature: Signature) -> TokenStream {
|
||||||
/// Implement a kernel item.
|
/// Implement a kernel item.
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn kernel_item(attr: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn kernel_item(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let item_name_input: KernelItemNameInput = syn::parse_macro_input!(attr);
|
let name: KernelItemNameInput = syn::parse_macro_input!(attr);
|
||||||
let item_name = format!("{:?}", item_name_input.item);
|
let item_name = name.item;
|
||||||
|
|
||||||
let input_fn: ItemFn = syn::parse_macro_input!(item as ItemFn);
|
let input_fn = syn::parse_macro_input!(item as ItemFn);
|
||||||
let fn_name = input_fn.clone().sig.ident;
|
let fn_name = input_fn.clone().sig.ident;
|
||||||
let fn_sig = to_token_stream(input_fn.clone().sig);
|
let fn_sig = to_token_stream(input_fn.clone().sig);
|
||||||
|
|
||||||
quote_spanned!(input_fn.span()=>{
|
quote!{
|
||||||
// The #item_name kernel item.
|
/// The #item_name kernel item.
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const #item_name: #fn_sig = #fn_name;
|
pub const #item_name: #fn_sig = #fn_name;
|
||||||
|
|
||||||
#input_fn
|
#input_fn
|
||||||
}).into()
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
6
user/Cargo.toml
Normal file
6
user/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "user"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
6
user/src/arch/mod.rs
Normal file
6
user/src/arch/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//! Architecture-specific stuff, mainly syscall methods.
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod x86;
|
||||||
|
|
||||||
|
pub use x86::*;
|
62
user/src/arch/x86/mod.rs
Normal file
62
user/src/arch/x86/mod.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
//! x86 syscall method.
|
||||||
|
|
||||||
|
/// Syscall method.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! syscall {
|
||||||
|
($id: expr) => {
|
||||||
|
unsafe {
|
||||||
|
let out = 0u32;
|
||||||
|
asm!(
|
||||||
|
"int 0xA0",
|
||||||
|
id = in("eax") const $id,
|
||||||
|
out("eax") out
|
||||||
|
)
|
||||||
|
out
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($id: expr, $d0: expr) => {
|
||||||
|
unsafe {
|
||||||
|
let out = 0u32;
|
||||||
|
let d0 = $d0;
|
||||||
|
asm!(
|
||||||
|
"int 0xA0",
|
||||||
|
id = in("eax") const $id,
|
||||||
|
d0 = in("ebx") $d0,
|
||||||
|
out("eax") out
|
||||||
|
)
|
||||||
|
out
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($id: expr, $d0: expr, $d1: expr) => {
|
||||||
|
unsafe {
|
||||||
|
let out = 0u32;
|
||||||
|
let d0 = $d0;
|
||||||
|
let d1 = $d1;
|
||||||
|
asm!(
|
||||||
|
"int 0xA0",
|
||||||
|
id = in("eax") const $id,
|
||||||
|
d0 = in("ebx") $d0,
|
||||||
|
d1 = in("ecx") $d1,
|
||||||
|
out("eax") out
|
||||||
|
)
|
||||||
|
out
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($id: expr, $d0: expr, $d1: expr, $d2: expr) => {
|
||||||
|
unsafe {
|
||||||
|
let out = 0u32;
|
||||||
|
let d0 = $d0;
|
||||||
|
let d1 = $d1;
|
||||||
|
let d2 = $d2;
|
||||||
|
asm!(
|
||||||
|
"int 0xA0",
|
||||||
|
id = in("eax") const $id,
|
||||||
|
d0 = in("ebx") $d0,
|
||||||
|
d1 = in("ecx") $d1,
|
||||||
|
d2 = in("edx") $d2,
|
||||||
|
out("eax") out
|
||||||
|
)
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
user/src/lib.rs
Normal file
5
user/src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#[warn(missing_docs)]
|
||||||
|
|
||||||
|
mod arch;
|
||||||
|
|
||||||
|
use arch::*;
|
Loading…
Add table
Reference in a new issue