Worked on build script a bunch, added format script and formatted everything

This commit is contained in:
Arthur Beck 2025-02-16 20:32:36 -06:00
parent 7ae1677a87
commit 884e9aa3cf
Signed by: ArthurB
GPG key ID: ACE3D14F5CEF14BF
33 changed files with 393 additions and 272 deletions

View file

@ -21,7 +21,3 @@ path = "src/arch_boot_entry/x86.rs"
[lib]
name = "aphrodite"
path = "src/kernel/mod.rs"
[[test]]
name = "test_aphrodite"
path = "src/include/test.rs"

View file

@ -1,29 +1,33 @@
#!/bin/bash
(
set -o errexit -o pipefail -o noclobber
flags=$-
set -o pipefail -o noclobber
HAVE_GETOPT=true
HAVE_GETOPT="${HAVE_GETOPT:-true}"
getopt --test > /dev/null && true
if [[ $? -ne 4 ]]; then
if [[ $? -ne 4 && $HAVE_GETOPT ]]; then
if [[ -n "EXIT_WITHOUT_GETOPT" ]]; then
echo '`getopt --test` failed. Exiting.'
echo '[ERROR] `getopt --test` failed. Exiting.'
exit 1
else
echo '`getopt --test` failed. Continuing and ignoring command line flags. (note that $1 will still be used for the target)'
echo '(to exit instead of ignoring, set the environment variable `EXIT_WITHOUT_GETOPT` to a non-null value)'
echo '[WARN] `getopt --test` failed. Continuing and ignoring command line flags. (note that $1 will still be used for the target)'
echo '[WARN] (to exit instead of ignoring, set the environment variable `EXIT_WITHOUT_GETOPT` to a non-null value)'
HAVE_GETOPT=false
fi
fi
set -o errexit # put down here as getopt returns error code four if it's working, and it probably would work otherwise, but I'm not taking chances
check=false
format=false
if [[ "$HAVE_GETOPT" = "true" ]]; then
LONGOPTS=check
OPTIONS=c
LONGOPTS=check,format
OPTIONS=cf
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") || (
echo '`getopt` failed to parse command line arguments. Check the arguments passed.'
echo '[ERROR] Failed to parse command line arguments. If your getopt is broken, set HAVE_GETOPT=true.'
exit 1
)
eval set -- "$PARSED"
@ -34,6 +38,10 @@
check=true
shift
;;
-f|--format)
format=true
shift
;;
--)
shift
break
@ -44,6 +52,12 @@
;;
esac
done
if [[ $check == "true" && $format == "true" ]]; then
echo "[WARN] Both --check and --format were passed."
echo "[WARN] Interpretting as only --format, as format will also check that Aphrokern can compile."
check=false
fi
fi
export KERNEL_DIR=$(readlink -e .)
@ -79,11 +93,11 @@
function compile_one {
target=$1
real_target=${!target}
real_target=$(basename $real_target)
echo "Compiling target $target(with rust target of $real_target)"
if [[ $check = "true" ]]; then
echo "[INFO] Checking target $target(with rust target of $real_target)"
cargo check --target "$real_target" --release -Zbuild-std=core,alloc --bin entrypoint_$target
else
echo "[INFO] Compiling target $target(with rust target of $real_target)"
cargo build --target "$real_target" --release -Zbuild-std=core,alloc --bin entrypoint_$target
cp "target/$(echo $real_target | sed 's/\.json//')/release/entrypoint_$target" kernel-$target
@ -103,6 +117,12 @@
fi
}
if [[ $format = "true" ]]; then
echo "[INFO] Formatting"
cargo fmt --all
exit 0
fi
if [[ $# -ge 1 ]]; then
echo "[INFO] Compiling only target $1"
compile_one $1
@ -114,4 +134,5 @@
done
reset_version_vars
set +$flags
)

View file

@ -1,22 +1,42 @@
fn main() {
let env = std::env::vars();
// Begin checks
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_DISABLE_MULTIBOOT2_SUPPORT, values("true", "false", none()))"#);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_DISABLE_MULTIBOOT2_SUPPORT, values("true", "false", none()))"#
);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_HALT_ON_PANIC, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_SPIN_ON_PANIC, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_WARN_ON_INVALID_LENGTH, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH, values("true", "false", none()))"#);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_WARN_ON_INVALID_LENGTH, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH, values("true", "false", none()))"#
);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_DEBUG, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_INFO, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_WARN, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_ERROR, values("true", "false", none()))"#);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_FATAL, values("true", "false", none()))"#);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_DEBUG, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_INFO, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_WARN, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_ERROR, values("true", "false", none()))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_FATAL, values("true", "false", none()))"#
);
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_BUILD_GRUB, values("true", "false", none()))"#);
// End checks
@ -26,9 +46,9 @@ fn main() {
for (var, val) in env {
if !var.starts_with("CONFIG_") {
continue
continue;
}
println!("cargo:rerun-if-env-changed={}", var);
println!("cargo:rustc-cfg={}=\"{}\"", var, val);
}
}
}

View file

@ -1,3 +0,0 @@
#!/bin/bash
RUSTFLAGS='-Clink-arg=--script=link.x' cargo expand --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint_x86

7
kernel/format Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
(
set -o errexit -o pipefail -o noclobber
./build --format $!
)

View file

@ -1,3 +1,5 @@
#!/bin/bash
function get_version() {
local TEMP_SUFFIX
if git add . && git diff --quiet && git diff --cached --quiet

View file

@ -9,26 +9,27 @@
#![feature(cfg_match)]
#![feature(formatting_options)]
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
use core::fmt::Debug;
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
use aphrodite::boot::{BootInfo, MemoryMapping};
use aphrodite::multiboot2::{FramebufferInfo, MemoryMap, MemorySection, RawMemoryMap, RootTag, Tag};
use aphrodite::arch::egatext;
use aphrodite::arch::output::*;
use aphrodite::arch::egatext as egatext;
use aphrodite::output::*;
use aphrodite::boot::{BootInfo, MemoryMapping};
use aphrodite::display::COLOR_DEFAULT;
use aphrodite::multiboot2::{
FramebufferInfo, MemoryMap, MemorySection, RawMemoryMap, RootTag, Tag,
};
use aphrodite::output::*;
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
#[unsafe(link_section = ".bootheader")]
#[unsafe(no_mangle)]
static MULTIBOOT2_HEADER: [u8; 24] = [
0xd6, 0x50, 0x52, 0xe8, // Magic number
0xd6, 0x50, 0x52, 0xe8, // Magic number
0x00, 0x00, 0x00, 0x00, // Architecture
0x18, 0x00, 0x00, 0x00, // Size
0x18, 0x00, 0x00, 0x00, // Size
0x12, 0xaf, 0xad, 0x17, // Checksum
0x00, 0x00, // End tag
0x00, 0x00, // End tag
0x00, 0x00, // Flags
0x08, 0x00, 0x00, 0x00, // Size
];
@ -45,14 +46,15 @@ static mut MM: MemoryMap = MemoryMap {
sections: &[],
};
static mut FBI: aphrodite::arch::egatext::FramebufferInfo = aphrodite::arch::egatext::FramebufferInfo {
address: 0,
pitch: 0,
width: 0,
height: 0,
bpp: 0,
change_cursor: false,
};
static mut FBI: aphrodite::arch::egatext::FramebufferInfo =
aphrodite::arch::egatext::FramebufferInfo {
address: 0,
pitch: 0,
width: 0,
height: 0,
bpp: 0,
change_cursor: false,
};
// The magic number in eax. 0x36D76289 for multiboot2.
static mut MAGIC: u32 = 0xFFFFFFFF;
@ -61,7 +63,8 @@ static mut MAGIC: u32 = 0xFFFFFFFF;
#[unsafe(no_mangle)]
#[aphrodite_proc_macros::kernel_item(ArchBootEntry)]
extern "C" fn _start() -> ! {
unsafe { // Copy values provided by the bootloader out
unsafe {
// Copy values provided by the bootloader out
// Aphrodite bootloaders pass values in eax and ebx, however rust doesn't know that it can't overwrite those.
// (if necessary, we'll store all of the registers for other bootloaders and identify which one it is later)
// we force using ebx and eax as the output of an empty assembly block to let it know.
@ -81,7 +84,8 @@ extern "C" fn _start() -> ! {
unsafe {
match MAGIC {
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
0x36D76289 => { // Multiboot2
0x36D76289 => {
// Multiboot2
RT = O as *const RootTag; // This is unsafe rust! We can do whatever we want! *manical laughter*
sdebugs("Total boot info length is ");
@ -92,11 +96,12 @@ extern "C" fn _start() -> ! {
sdebugbnp(&aphrodite::usize_as_u8_slice(O as usize));
sdebugunp(b'\n');
if (*RT).total_len<16 { // Size of root tag+size of terminating tag. Something's up.
if (*RT).total_len < 16 {
// Size of root tag+size of terminating tag. Something's up.
panic!("total length < 16")
}
let end_addr = O as usize+(*RT).total_len as usize;
let end_addr = O as usize + (*RT).total_len as usize;
sdebugunp(b'\n');
@ -104,7 +109,7 @@ extern "C" fn _start() -> ! {
ptr += size_of::<RootTag>();
let mut current_tag = core::ptr::read_volatile(ptr as *const Tag);
loop {
sdebugs("Tag address is ");
sdebugbnpln(&aphrodite::usize_as_u8_slice(ptr));
@ -114,26 +119,34 @@ extern "C" fn _start() -> ! {
sdebugs("Tag length is ");
sdebugbnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_len));
match current_tag.tag_type {
0 => { // Ending tag
if current_tag.tag_len != 8 { // Unexpected size, something is probably up
0 => {
// Ending tag
if current_tag.tag_len != 8 {
// Unexpected size, something is probably up
panic!("size of ending tag != 8");
}
break
},
4 => { // Basic memory information
if current_tag.tag_len != 16 { // Unexpected size, something is probably up
break;
}
4 => {
// Basic memory information
if current_tag.tag_len != 16 {
// Unexpected size, something is probably up
panic!("size of basic memory information tag != 16");
}
},
5 => { // BIOS boot device, ignore
if current_tag.tag_len != 20 { // Unexpected size, something is probably up
}
5 => {
// BIOS boot device, ignore
if current_tag.tag_len != 20 {
// Unexpected size, something is probably up
panic!("size of bios boot device tag != 20");
}
},
1 => { // Command line
if current_tag.tag_len < 8 { // Unexpected size, something is probably up
}
1 => {
// Command line
if current_tag.tag_len < 8 {
// Unexpected size, something is probably up
panic!("size of command line tag < 8");
}
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
@ -141,13 +154,16 @@ extern "C" fn _start() -> ! {
BI.cmdline = Some(cstring.to_str().unwrap());
// ...before the BootInfo's commandline is set.
},
6 => { // Memory map tag
if current_tag.tag_len < 16 { // Unexpected size, something is probably up
}
6 => {
// Memory map tag
if current_tag.tag_len < 16 {
// Unexpected size, something is probably up
panic!("size of memory map tag < 16");
}
let rawmemorymap: *mut RawMemoryMap = core::ptr::from_raw_parts_mut(
ptr as *mut u8, (current_tag.tag_len / *((ptr + 8usize) as *const u32)) as usize
ptr as *mut u8,
(current_tag.tag_len / *((ptr + 8usize) as *const u32)) as usize,
);
// The end result of the above is creating a *const RawMemoryMap that has the same address as current_tag
// and has all of the [aphrodite::multiboot2::MemorySection]s for the memory map
@ -169,12 +185,14 @@ extern "C" fn _start() -> ! {
size_pages: 1,
page_size: MM.mem_size(),
sections: MM.sections,
idx: 0
idx: 0,
};
BI.memory_map = Some(mm2);
},
2 => { // Bootloader name
if current_tag.tag_len < 8 { // Unexpected size, something is probably up
}
2 => {
// Bootloader name
if current_tag.tag_len < 8 {
// Unexpected size, something is probably up
panic!("size of command line tag < 8");
}
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
@ -182,21 +200,26 @@ extern "C" fn _start() -> ! {
BI.bootloader_name = Some(cstring.to_str().unwrap());
// ...before the BootInfo's bootloader_name is set.
},
8 => { // Framebuffer info
if current_tag.tag_len < 32 { // Unexpected size, something is probably up
}
8 => {
// Framebuffer info
if current_tag.tag_len < 32 {
// Unexpected size, something is probably up
panic!("size of framebuffer info tag < 32");
}
let framebufferinfo: *const FramebufferInfo = (ptr as usize + size_of::<Tag>()) as *const FramebufferInfo;
let framebufferinfo: *const FramebufferInfo =
(ptr as usize + size_of::<Tag>()) as *const FramebufferInfo;
match (*framebufferinfo).fb_type {
0 => { // Indexed
0 => {
// Indexed
panic!("Indexed color is unimplemented");
},
1 => { // RGB
}
1 => {
// RGB
panic!("RGB color is unimplemented");
},
}
2 => { // EGA Text
},
}
_ => {
panic!("unknown color info type")
}
@ -212,15 +235,16 @@ extern "C" fn _start() -> ! {
change_cursor: false,
};
BI.output = Some(&FBI)
},
_ => { // Unknown/unimplemented tag type, ignore
}
_ => {
// Unknown/unimplemented tag type, ignore
swarnings("Unknown tag type ");
swarningbnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_type));
}
}
sinfounp(b'\n');
ptr = (ptr + current_tag.tag_len as usize + 7) & !7;
if ptr>end_addr {
if ptr > end_addr {
cfg_match! {
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");
@ -242,8 +266,9 @@ extern "C" fn _start() -> ! {
}
current_tag = core::ptr::read_volatile(ptr as *const Tag);
}
},
_ => { // Unknown bootloader, panic
}
_ => {
// Unknown bootloader, panic
panic!("unknown bootloader");
}
}
@ -261,10 +286,12 @@ extern "C" fn _start() -> ! {
sdebugs("Framebuffer pitch: ");
sdebugbnpln(&aphrodite::u32_as_u8_slice(framebuffer_info.pitch));
sdebugs("Framebuffer address: ");
sdebugbnpln(&aphrodite::usize_as_u8_slice(framebuffer_info.address as usize));
sdebugbnpln(&aphrodite::usize_as_u8_slice(
framebuffer_info.address as usize,
));
sdebugs("Framebuffer bpp: ");
sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp));
sdebugsln("Beginning test output to screen...");
let ega: &dyn aphrodite::display::TextDisplay = &framebuffer_info;
@ -293,12 +320,13 @@ fn halt_on_panic(info: &PanicInfo) -> ! {
sfatalsnp(":");
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line()));
sfatalsnp(":");
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column()));
sfatalsnp(": ");
sfatalbnpln(&aphrodite::u32_as_u8_slice(
info.location().unwrap().column(),
));
} else {
sfatals("Panic: ");
}
let mut formatter = FormattingOptions::new().create_formatter(unsafe { &mut FBI });
let mut formatter = FormattingOptions::new().create_formatter(unsafe { &mut FBI });
let _ = info.message().fmt(&mut formatter);
aphrodite::arch::interrupts::disable_interrupts();
unsafe {
@ -308,7 +336,7 @@ fn halt_on_panic(info: &PanicInfo) -> ! {
#[unsafe(link_section = ".panic")]
#[panic_handler]
#[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_PREUSER_HALT_ON_PANIC = "false"))]
#[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_HALT_ON_PANIC = "false"))]
fn spin_on_panic(info: &PanicInfo) -> ! {
if info.location().is_some() {
sfatals("Panic at ");
@ -316,7 +344,9 @@ fn spin_on_panic(info: &PanicInfo) -> ! {
sfatalsnp(":");
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line()));
sfatalsnp(":");
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column()));
sfatalbnp(&aphrodite::u32_as_u8_slice(
info.location().unwrap().column(),
));
sfatalsnp(": ");
} else {
sfatals("Panic: ");
@ -329,4 +359,4 @@ fn spin_on_panic(info: &PanicInfo) -> ! {
}
aphrodite::arch::interrupts::disable_interrupts();
loop {}
}
}

View file

@ -0,0 +1 @@

View file

@ -1,12 +1,13 @@
//! An example implementation of an architecture. DO NOT use this module!
//! Everything must be implemented via either kernel items, or for constants
//! making them public.
//!
//!
//! This is commented out for obvious reasons, but make sure to have this at
//! the top of the all files in your arch(with "arch" replaced with the
//! actual architecture, of course):
//! #![cfg(any(target_arch = "arch"))]
/// Returns the most specific architecture available.
pub const fn get_arch() -> super::Architecture {
super::Architecture::ExampleDummy
}
@ -15,11 +16,11 @@ pub mod interrupts {
//! Interrupt-related functions.
use core::mem::MaybeUninit;
/// Must be a u16 or castable to a u16.
/// Value used in x86 shown here as an example.
pub const USER_SYSCALL_VECTOR: u16 = 0xA0;
/// Returns whether interrupts are enabled or not.
#[aphrodite_proc_macros::kernel_item(InterruptsCheck)]
fn interrupts_enabled() -> bool {
@ -28,15 +29,11 @@ pub mod interrupts {
/// Enables interrupts.
#[aphrodite_proc_macros::kernel_item(InterruptsEnable)]
fn enable_interrupts() {
}
fn enable_interrupts() {}
/// Disables interrupts.
#[aphrodite_proc_macros::kernel_item(InterruptsDisable)]
fn disable_interrupts() {
}
fn disable_interrupts() {}
/// Disables interrupts and a value that can be used to restore them
/// with [restore_irq].
@ -47,21 +44,17 @@ pub mod interrupts {
/// Restores interrupts after a [pop_irq] call.
#[aphrodite_proc_macros::kernel_item(InterruptsRestore)]
fn restore_irq(irq: u64) {
irq;
}
fn restore_irq(_irq: u64) {}
/// Activates an IDT.
#[aphrodite_proc_macros::kernel_item(ActivateIDT)]
fn activate_idt(idt: Idt) {
idt;
}
fn activate_idt(_idt: Idt) {}
/// An IDT.
#[derive(Clone, Copy)]
pub struct Idt {
vectors: [u16; 256],
funcs: [MaybeUninit<fn ()>; 256],
funcs: [MaybeUninit<fn()>; 256],
len: usize,
}
@ -70,14 +63,14 @@ pub mod interrupts {
#[derive(Clone, Copy)]
pub struct IdtBuilder {
vectors: [u16; 256],
funcs: [MaybeUninit<fn ()>; 256],
funcs: [MaybeUninit<fn()>; 256],
idx: usize,
}
impl IdtBuilder {
/// Start creating a new IDT.
pub fn new() -> Self {
IdtBuilder {
IdtBuilder {
vectors: [0; 256],
funcs: [MaybeUninit::uninit(); 256],
idx: 0,
@ -95,7 +88,7 @@ pub mod interrupts {
Idt {
vectors: self.vectors,
funcs: self.funcs,
len: self.idx
len: self.idx,
}
}
}
@ -106,9 +99,3 @@ pub mod output {
//! LOT of output functions must be implemented. Using macros to
//! implement these is HIGHLY recommended.
}
/// Returns whether paging is available for this architecture.
#[aphrodite_proc_macros::kernel_item(PagingAvailabe)]
pub fn paging_available() -> bool {
true
}

View file

@ -1,9 +1,9 @@
//! Arch-specific code. This module re-exports all code from the architecture being used.
//!
//!
//! See [example_impl] for everything that has to be implemented by an architecture module.
mod x86;
pub mod example_impl;
mod x86;
pub use x86::*;
@ -16,4 +16,4 @@ pub enum Architecture {
ExampleDummy,
/// 32-bit x86.
X86,
}
}

View file

@ -2,4 +2,4 @@
#![cfg(any(target_arch = "x86"))]
/// The assembly port number to output debug messages to.
pub(super) const DEBUG_PORT: u16 = 0xE9;
pub(super) const DEBUG_PORT: u16 = 0xE9;

View file

@ -34,7 +34,12 @@ impl core::fmt::Write for FramebufferInfo {
impl crate::display::TextDisplay for FramebufferInfo {
/// Writes a character to the screen.
fn write_char(&self, mut pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>> {
fn write_char(
&self,
mut pos: (u32, u32),
char: u8,
color: Color,
) -> Result<(), crate::Error<'static>> {
let mut clr = color.0;
if color.1 {
match clr {
@ -44,18 +49,18 @@ impl crate::display::TextDisplay for FramebufferInfo {
}
}
let color = clr;
if pos.0>self.width {
if pos.0 > self.width {
return Err(crate::Error::new("Invalid X position", ERR_INVALID_X));
}
if pos.1>self.height {
if pos.1 > self.height {
return Err(crate::Error::new("Invalid Y position", ERR_INVALID_Y));
}
unsafe {
let mut addr = self.address as usize;
addr += (pos.1*self.pitch) as usize;
addr += (pos.0*(self.bpp as u32/8)) as usize;
addr += (pos.1 * self.pitch) as usize;
addr += (pos.0 * (self.bpp as u32 / 8)) as usize;
let base_ptr = addr as *mut u16;
(*base_ptr) = ((color as u16)<<8) | (char as u16);
(*base_ptr) = ((color as u16) << 8) | (char as u16);
}
pos.1 += 1;
if self.change_cursor {
@ -69,7 +74,6 @@ impl crate::display::TextDisplay for FramebufferInfo {
}
impl FramebufferInfo {
/// Disables the cursor.
pub fn disable_cursor(self) {
super::ports::outb(0x3D4, 0x0A);

View file

@ -5,15 +5,18 @@ use core::alloc::Layout;
use alloc::vec::Vec;
/// Writes a series of GDT entries to an allocated section of memory and returns a pointer.
pub unsafe fn write_gdt_entries(entries: Vec<GDTEntry>) -> Result<*const [u8], crate::Error<'static>> {
let mut mem = unsafe { alloc::alloc::alloc(Layout::from_size_align(8*entries.len(), 1).unwrap()) };
pub unsafe fn write_gdt_entries(
entries: Vec<GDTEntry>,
) -> Result<*const [u8], crate::Error<'static>> {
let mut mem =
unsafe { alloc::alloc::alloc(Layout::from_size_align(8 * entries.len(), 1).unwrap()) };
for ele in &entries {
let ele: &GDTEntry = ele;
unsafe { ele.write_to_addr(mem as *mut ())? }
mem = (mem as usize + 8) as *mut u8;
}
Ok(core::ptr::from_raw_parts(mem, 8*entries.len()))
Ok(core::ptr::from_raw_parts(mem, 8 * entries.len()))
}
/// A GDT entry.
@ -35,7 +38,10 @@ const GDT_WRITE_ADDR_INVALID_LIMIT: i16 = -1;
impl GDTEntry {
const unsafe fn write_to_addr(self, ptr: *mut ()) -> Result<(), crate::Error<'static>> {
if self.limit > 0xFFFFF {
return Err(crate::Error::new("Invalid GDT entry limit(more than 0xFFFFF)", GDT_WRITE_ADDR_INVALID_LIMIT));
return Err(crate::Error::new(
"Invalid GDT entry limit(more than 0xFFFFF)",
GDT_WRITE_ADDR_INVALID_LIMIT,
));
}
let mut serialized = (0u64).to_ne_bytes();
@ -55,7 +61,7 @@ impl GDTEntry {
unsafe {
core::ptr::write(ptr as *mut [u8; 8], serialized);
}
Ok(())
}
}
}

View file

@ -2,7 +2,11 @@
#![cfg(any(target_arch = "x86"))]
#![allow(static_mut_refs)]
use core::{alloc::{Allocator, Layout}, arch::asm, mem::MaybeUninit};
use core::{
alloc::{Allocator, Layout},
arch::asm,
mem::MaybeUninit,
};
/// The syscall vector.
pub const USER_SYSCALL_VECTOR: u16 = 0xA0;
@ -23,9 +27,7 @@ pub fn interrupts_enabled() -> bool {
/// Disables interrupts.
#[aphrodite_proc_macros::kernel_item(InterruptsDisable)]
pub fn disable_interrupts() {
unsafe {
asm!("cli")
}
unsafe { asm!("cli") }
}
/// PoppedInterrupts implements drop and restores the interrupts upon being dropped.
@ -62,9 +64,7 @@ pub fn restore_irq(flags: PoppedInterrupts) {
asm!(
"push {0:e}", in(reg) flags
);
asm!(
"popf"
);
asm!("popf");
}
}
@ -73,7 +73,7 @@ pub fn restore_irq(flags: PoppedInterrupts) {
#[repr(C)]
struct IDTR {
base: *const u8,
size: usize
size: usize,
}
unsafe impl Send for IDTR {}
@ -83,53 +83,54 @@ unsafe impl Sync for IDTR {}
fn load_idt(base: *const u8, size: usize) {
static mut IDTR: MaybeUninit<IDTR> = MaybeUninit::uninit();
unsafe {
IDTR.write(IDTR {
base,
size
});
}
unsafe {
asm!("lidt {}", in(reg) IDTR.as_ptr() as usize)
IDTR.write(IDTR { base, size });
}
unsafe { asm!("lidt {}", in(reg) IDTR.as_ptr() as usize) }
}
/// Activate an IDT.
#[aphrodite_proc_macros::kernel_item(ActivateIDT)]
fn activate_idt(idt: Idt, alloc: crate::mem::MemoryMapAlloc) {
let mem = alloc.allocate(unsafe { Layout::from_size_align_unchecked(8*idt.len, 1) }).unwrap().as_mut_ptr();
let _mem = alloc
.allocate(unsafe { Layout::from_size_align_unchecked(8 * idt.len, 1) })
.unwrap()
.as_mut_ptr();
for i in 0..idt.len {
let vector = idt.vectors[i];
let func = unsafe { idt.funcs[i].assume_init() } as usize as u64;
let user_callable = idt.user_callable[i];
let _vector = idt.vectors[i];
let _func = unsafe { idt.funcs[i].assume_init() } as usize as u64;
let _user_callable = idt.user_callable[i];
}
}
/// An Interrupt Descriptor Table.
#[derive(Clone, Copy)]
pub struct Idt {
vectors: [u16; 256],
funcs: [MaybeUninit<fn ()>; 256],
funcs: [MaybeUninit<fn()>; 256],
user_callable: [bool; 256],
len: usize,
}
/// A builder of an [Idt].
#[derive(Clone, Copy)]
pub struct IdtBuilder {
vectors: [u16; 256],
funcs: [MaybeUninit<fn ()>; 256],
funcs: [MaybeUninit<fn()>; 256],
user_callable: [bool; 256],
idx: usize,
}
impl IdtBuilder {
/// Create a new IdtBuilder.
pub fn new() -> Self {
IdtBuilder {
IdtBuilder {
vectors: [0; 256],
funcs: [MaybeUninit::uninit(); 256],
user_callable: [false; 256],
idx: 0,
}
}
/// Add a function to this IdtBuilder.
pub fn add_fn(&mut self, vector: u16, func: fn(), user_callable: bool) -> &mut Self {
self.vectors[self.idx] = vector;
self.funcs[self.idx].write(func);
@ -137,12 +138,13 @@ impl IdtBuilder {
self.idx += 1;
self
}
/// Finish creating this IdtBuilder and return an [Idt].
pub fn finish(&self) -> Idt {
Idt {
vectors: self.vectors,
funcs: self.funcs,
user_callable: self.user_callable,
len: self.idx
len: self.idx,
}
}
}
}

View file

@ -6,8 +6,9 @@ use alloc::{vec, vec::Vec};
use crate::memsections::*;
use super::gdt::{write_gdt_entries, GDTEntry};
use super::gdt::{GDTEntry, write_gdt_entries};
/// A list of memory sections. Create one with [MemorySectionBuilder].
pub struct MemorySections {
sections: Vec<MemorySection>,
}
@ -100,11 +101,11 @@ unsafe impl crate::memsections::MemorySections for MemorySections {
let gdtr = GDTR {
address: ptr as *const u8 as usize as u32,
size: (ptr.len()-1) as u16
size: (ptr.len() - 1) as u16,
};
let addr = &gdtr as *const GDTR as *const () as usize as u32;
asm!(
"lgdt eax",
in("eax") addr
@ -124,10 +125,10 @@ unsafe impl crate::memsections::MemorySections for MemorySections {
}
if entry.access & 0b11000 == 0b11000 && !code_set {
code_segment = i-1;
code_segment = i - 1;
code_set = true;
} else if entry.access & 0b10000 == 0b10000 && !data_set {
data_segment = i-1;
data_segment = i - 1;
data_set = true;
}
}
@ -156,16 +157,19 @@ pub struct MemorySectionBuilder {
}
impl MemorySectionBuilder {
/// Create a new MemorySectionBuilder.
pub fn new() -> Self {
MemorySectionBuilder { sections: vec![] }
}
/// Adds a section to this MemorySectionBuilder.
pub fn add_section(&mut self, section: MemorySection) -> &mut Self {
self.sections.push(section);
self
}
/// Finishes this MemorySectionBuilder and returns a MemorySections.
pub fn finish(self) -> MemorySections {
MemorySections {
sections: self.sections,

View file

@ -3,13 +3,13 @@
use core::arch::asm;
pub mod interrupts;
pub mod ports;
pub mod output;
pub mod egatext;
pub mod paging;
mod gdt;
pub mod interrupts;
pub mod memory;
pub mod output;
pub mod paging;
pub mod ports;
mod constants;
@ -17,15 +17,11 @@ pub(self) use constants::*;
use interrupts::{pop_irq, restore_irq};
use ports::{inb, outb};
/// Returns the most specific architecture available.
pub const fn get_arch() -> super::Architecture {
super::Architecture::X86
}
#[aphrodite_proc_macros::kernel_item(PagingAvailabe)]
pub fn paging_available() -> bool {
true
}
/// Returns information from the CPUID command in the form
/// (ebx, edx, ecx).
pub fn cpuid(id: u32) -> (u32, u32, u32) {
@ -70,12 +66,12 @@ pub fn test_a20() -> bool {
/// Waits for a keyboard command to complete.
pub fn wait_for_keyboard_cmd() {
while inb(0x64)&0b10 > 1 {}
while inb(0x64) & 0b10 > 1 {}
}
/// Waits for there to be data to read from the keyboard.
pub fn wait_for_keyboard_data() {
while inb(0x64)&0b1 == 0 {}
while inb(0x64) & 0b1 == 0 {}
}
/// Sends a keyboard command.
@ -111,7 +107,7 @@ pub fn enable_a20_keyboard() {
send_keyboard_cmd(0xD1); // write to output
wait_for_keyboard_cmd();
send_keyboard_data(a|2);
send_keyboard_data(a | 2);
wait_for_keyboard_cmd();
send_keyboard_cmd(0xAE); // enable keyboard
@ -123,8 +119,8 @@ pub fn enable_a20_keyboard() {
/// Note that this may not work or do something unexpected.
pub fn enable_a20_fasta20() {
let mut a = inb(0x92);
if a&0b10 > 0 {
return
if a & 0b10 > 0 {
return;
}
a |= 0b10;
a &= 0xFE;
@ -145,7 +141,7 @@ pub fn enable_a20() -> bool {
enable_a20_keyboard();
let mut i = 0u32;
while (!test_a20()) && i<10000 {
while (!test_a20()) && i < 10000 {
i += 1;
}
@ -155,7 +151,7 @@ pub fn enable_a20() -> bool {
enable_a20_ee_port();
let mut i = 0u32;
while (!test_a20()) && i<10000 {
while (!test_a20()) && i < 10000 {
i += 1;
}
@ -165,7 +161,7 @@ pub fn enable_a20() -> bool {
enable_a20_fasta20();
let mut i = 0u32;
while (!test_a20()) && i<10000 {
while (!test_a20()) && i < 10000 {
i += 1;
}

View file

@ -94,7 +94,7 @@ macro_rules! message_funcs {
ports::outb(super::DEBUG_PORT, s);
}
}
}
};
}
message_funcs!(debug, "[DEBUG] ", CONFIG_PREUSER_OUTPUT_DEBUG);
@ -103,4 +103,3 @@ message_funcs!(warning, "[WARN] ", CONFIG_PREUSER_OUTPUT_WARN);
message_funcs!(error, "[ERROR] ", CONFIG_PREUSER_OUTPUT_ERROR);
message_funcs!(fatal, "[FATAL] ", CONFIG_PREUSER_OUTPUT_FATAL);
message_funcs!(output, "", NONE);

View file

@ -4,8 +4,11 @@ use core::arch::asm;
use aphrodite_proc_macros::kernel_item;
/// One page directory entry. Use [PageDirectoryEntry::create_fourmb] or [PageDirectoryEntry::create_other] to make these.
pub enum PageDirectoryEntry {
/// A four megabyte page.
FourMb(u32),
/// A smaller page.
Other(u32),
}
@ -114,11 +117,9 @@ impl PageDirectoryEntry {
static mut PAGE_DIRECTORY: PageDirectoryEntry =
PageDirectoryEntry::create_other(0, false, 0, false, false, false, false, false, false, false);
/// Initalize paging.
#[kernel_item(PagingInit)]
pub fn initalize_paging() {
}
pub fn initalize_paging() {}
/// Disables paging by clearing bit 31 in the cr0 register.
#[kernel_item(PagingDeinit)]

View file

@ -36,4 +36,4 @@ pub fn inb(port: u16) -> u8 {
#[inline(always)]
pub fn io_wait() {
outb(0x80, 0);
}
}

View file

@ -34,15 +34,14 @@ impl MemoryType {
MemoryType::Faulty => crate::arch::output::sdebugsnp("Faulty RAM"),
MemoryType::HardwareReserved => crate::arch::output::sdebugsnp("Hardware Reserved"),
MemoryType::HardwareSpecific(val, allocatable) => {
crate::arch::output::sdebugsnp("Hardware specific ");
crate::arch::output::sdebugbnp(&crate::u32_as_u8_slice(*val));
if *allocatable {
crate::arch::output::sdebugsnp(", allocatable");
} else {
crate::arch::output::sdebugsnp(", unallocatable");
}
},
crate::arch::output::sdebugsnp("Hardware specific ");
crate::arch::output::sdebugbnp(&crate::u32_as_u8_slice(*val));
if *allocatable {
crate::arch::output::sdebugsnp(", allocatable");
} else {
crate::arch::output::sdebugsnp(", unallocatable");
}
}
MemoryType::Kernel => crate::arch::output::sdebugsnp("Kernel loaded"),
MemoryType::Permanent => crate::arch::output::sdebugsnp("Flash"),
MemoryType::Reserved => crate::arch::output::sdebugsnp("Reserved"),

View file

@ -11,4 +11,4 @@ macro_rules! cfg_int {
}
}
};
}
}

View file

@ -19,14 +19,14 @@ pub struct Argument {
/// The name of an argument.
pub name: &'static str,
/// The value of an argument.
pub value: ArgumentValue
pub value: ArgumentValue,
}
/// A single flag in a [Cmdline].
#[derive(Clone, Copy)]
pub struct Flag {
/// The name of a flag.
pub name: &'static str
pub name: &'static str,
}
/// A kernel command line.
@ -83,7 +83,10 @@ impl Validator for CmdlineValidator {
}
}
if !correct {
return Err(crate::Error::new("invalid argument in command line", ERR_INVALID_ARGUMENT));
return Err(crate::Error::new(
"invalid argument in command line",
ERR_INVALID_ARGUMENT,
));
}
}
@ -96,9 +99,12 @@ impl Validator for CmdlineValidator {
}
}
if !correct {
return Err(crate::Error::new("invalid flag in command line", ERR_INVALID_FLAG));
return Err(crate::Error::new(
"invalid flag in command line",
ERR_INVALID_FLAG,
));
}
}
Ok(())
}
}
}

View file

@ -1 +1 @@
//! Constants used throughout kernel code.
//! Constants used throughout kernel code.

View file

@ -3,7 +3,7 @@
use core::fmt::Write;
/// A type used for color in the functions of [TextDisplay].
///
///
/// Type alias for (u8, bool). Boolean argument is whether to
/// change the value(i.e. for [COLOR_BLACK] and [COLOR_DEFAULT]).
pub type Color = (u8, bool);
@ -18,7 +18,12 @@ pub const COLOR_DEFAULT: Color = (1, true);
/// Some form of display that can be written to with text.
pub trait TextDisplay: core::fmt::Write {
/// Writes a single character to the specified position.
fn write_char(&self, pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>>;
fn write_char(
&self,
pos: (u32, u32),
char: u8,
color: Color,
) -> Result<(), crate::Error<'static>>;
/// Gets the size of the screen.
fn get_size(&self) -> (u32, u32);
}
@ -35,16 +40,21 @@ impl dyn TextDisplay + '_ {
}
/// Writes a &str to the screen.
pub fn write_str(&self, pos: (u32, u32), str: &str, color: Color) -> Result<(u32, u32), crate::Error<'static>> {
pub fn write_str(
&self,
pos: (u32, u32),
str: &str,
color: Color,
) -> Result<(u32, u32), crate::Error<'static>> {
let (width, _) = self.get_size();
let (mut x, mut y) = pos;
for char in str.as_bytes() {
self.write_char((x, y), *char, color)?;
if *char == 0 {
continue
continue;
}
x += 1;
while x>width {
while x > width {
x -= width;
y += 1;
}
@ -53,16 +63,21 @@ impl dyn TextDisplay + '_ {
}
/// Writes a &\[u8] to the screen.
pub fn write_bytes(&self, pos: (u32, u32), str: &[u8], color: Color) -> Result<(u32, u32), crate::Error<'static>> {
pub fn write_bytes(
&self,
pos: (u32, u32),
str: &[u8],
color: Color,
) -> Result<(u32, u32), crate::Error<'static>> {
let (width, _) = self.get_size();
let (mut x, mut y) = pos;
for char in str {
self.write_char((x, y), *char, color)?;
if *char == 0 {
continue
continue;
}
x += 1;
while x>width {
while x > width {
x -= width;
y += 1;
}
@ -76,7 +91,7 @@ pub struct NoneTextDisplay {}
impl TextDisplay for NoneTextDisplay {
fn get_size(&self) -> (u32, u32) {
(1,1)
(1, 1)
}
fn write_char(&self, _: (u32, u32), _: u8, _: Color) -> Result<(), crate::Error<'static>> {
Ok(())
@ -90,4 +105,4 @@ impl Write for NoneTextDisplay {
fn write_str(&mut self, _: &str) -> core::fmt::Result {
Ok(())
}
}
}

View file

@ -6,7 +6,7 @@ use crate::display::TextDisplay;
#[derive(Clone, Copy)]
pub struct Error<'a> {
message: &'a str,
code: i16
code: i16,
}
impl<'a> Error<'a> {
@ -17,7 +17,7 @@ impl<'a> Error<'a> {
}
impl Error<'_> {
/// Display the contents of the error on a [TextDisplay].
/// Display the contents of the error on a [TextDisplay] with no prefix.
pub fn display_np(&self, display: &dyn TextDisplay) {
crate::output::terrorbnp(&crate::i16_as_u8_slice(self.code), display).unwrap();
crate::output::terrorsnp(": ", display).unwrap();
@ -41,4 +41,4 @@ impl core::fmt::Display for Error<'_> {
}
}
impl core::error::Error for Error<'_> {}
impl core::error::Error for Error<'_> {}

View file

@ -5,7 +5,10 @@
use core::alloc::{Allocator, Layout};
use crate::{display::{NoneTextDisplay, COLOR_DEFAULT}, output::*};
use crate::{
display::{COLOR_DEFAULT, NoneTextDisplay},
output::*,
};
use aphrodite_proc_macros::*;
@ -17,7 +20,10 @@ fn indep_boot_entry(
display: Option<&dyn crate::display::TextDisplay>,
#[allow(non_snake_case)] BI: &crate::boot::BootInfo,
) -> ! {
assert_ne!(crate::arch::get_arch(), crate::arch::Architecture::ExampleDummy);
assert_ne!(
crate::arch::get_arch(),
crate::arch::Architecture::ExampleDummy
);
crate::arch::output::sdebugsln("IndepBootEntry called");
let display = display.unwrap_or(&NoneTextDisplay {});
@ -64,6 +70,8 @@ fn indep_boot_entry(
terrors("Failed to deallocate: ", display).unwrap();
err.display_np(display);
panic!("Deallocation failure");
} else {
tdebugsln("Successfully deallocated!", display).unwrap();
}
}
tdebugsln("", display).unwrap();

View file

@ -48,8 +48,6 @@ struct AllocationIter {
impl Iterator for AllocationIter {
type Item = *mut Allocation;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(self.num_allocations));
crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(self.idx));
self.idx += 1;
if self.idx > self.num_allocations {
return None;
@ -139,7 +137,11 @@ impl<'a> Debug for MemoryMapAlloc<'a> {
impl<'a> MemoryMapAlloc<'a> {
/// Creates a new [MemoryMapAlloc]. Please call this method instead of creating it manually!
/// This method uses the memory mapping to
///
/// This method internally stores the memory map in the outputted MemoryMapAlloc.
///
/// Note that this function will return an error only if there isn't enough allocatable space
/// for at least 32 allocations.
pub fn new(
memory_map: &'a mut crate::boot::MemoryMap,
) -> Result<MemoryMapAlloc<'a>, crate::Error<'a>> {
@ -222,6 +224,9 @@ impl<'a> MemoryMapAlloc<'a> {
/// Add an allocation to [MemoryMapAlloc::allocations]. It will overwrite allocations with `used` set to false.
fn add_allocation(&self, allocation: Allocation) -> Result<(), crate::Error<'static>> {
if !allocation.used {
crate::arch::output::swarningsln("Adding unused allocation");
}
for alloc in self.allocations_iter() {
if !unsafe { *alloc }.used {
unsafe { (*alloc) = allocation }
@ -355,7 +360,7 @@ pub const MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED: i16 = -8;
struct MaybeMemoryMapAlloc<'a> {
alloc: MaybeUninit<MemoryMapAlloc<'a>>,
initalized: bool
initalized: bool,
}
impl<'a> MaybeMemoryMapAlloc<'a> {
const fn new(alloc: Option<MemoryMapAlloc<'a>>) -> Self {
@ -363,7 +368,7 @@ impl<'a> MaybeMemoryMapAlloc<'a> {
return MaybeMemoryMapAlloc {
alloc: MaybeUninit::uninit(),
initalized: false,
}
};
}
MaybeMemoryMapAlloc {
alloc: MaybeUninit::new(alloc.unwrap()),
@ -385,7 +390,9 @@ impl<'a> MaybeMemoryMapAlloc<'a> {
if !self.initalized {
return;
}
unsafe { self.alloc.assume_init_drop(); }
unsafe {
self.alloc.assume_init_drop();
}
self.initalized = false;
}
}
@ -418,7 +425,10 @@ unsafe impl<'a> GlobalAlloc for MaybeMemoryMapAlloc<'a> {
}
unsafe impl<'a> Allocator for MaybeMemoryMapAlloc<'a> {
fn allocate(&self, layout: core::alloc::Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
fn allocate(
&self,
layout: core::alloc::Layout,
) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
if !self.initalized {
unsafe {
LAST_MEMMAP_ERR = Err(crate::Error::new(
@ -545,6 +555,7 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
}
return;
}
crate::arch::output::sdebugsln("Searching for allocation");
crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(
unsafe { *self.allocationheader }.num_allocations,
));
@ -552,6 +563,17 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
crate::arch::output::sdebugsln("Allocation");
let alloc = unsafe { *allocation }.clone();
if !alloc.used {
crate::arch::output::sdebugs("Unused, addr is ");
if alloc.addr == addr {
crate::arch::output::sdebugsnp("correct and ");
} else {
crate::arch::output::sdebugsnp("incorrect and ");
}
if alloc.addr == 0 {
crate::arch::output::sdebugsnpln("null");
} else {
crate::arch::output::sdebugsnpln("non-null");
}
continue;
}
crate::arch::output::sdebugsln("Used");
@ -560,6 +582,7 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> {
return;
}
}
crate::arch::output::sdebugsln("Memory unallocated");
// 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(

View file

@ -1,5 +1,5 @@
//! Architecture-independt memory section stuff.
//!
//!
//! arch::*::memory is the architecture-dependent counterpart.
/// Section types for [MemorySection].
@ -12,7 +12,7 @@ pub enum SectionType {
CodeSection {
/// Whether more powerful owners can jump to this if the owner
/// is less powerful.
can_powerful_sections_jump: bool
can_powerful_sections_jump: bool,
},
/// A data section. Generally at least one of these for the kernel.
DataSection,
@ -21,7 +21,7 @@ pub enum SectionType {
/// if they aren't directly supported by the hardware.
TaskSection {
/// Whether the section is busy.
busy: bool
busy: bool,
},
}
@ -62,8 +62,8 @@ pub struct MemorySection {
/// is called, which is not supposed to happen.
pub unsafe trait MemorySections {
/// Write the sections to an allocated region and then activate them.
///
///
/// This intentionally takes ownership of the MemorySections as it
/// shouldn't be used after this is called.
unsafe fn write(self) -> Result<(), crate::Error<'static>>;
}
}

View file

@ -29,12 +29,12 @@ pub mod display;
mod errors;
pub mod indep_boot_entry;
pub mod mem;
pub mod memsections;
pub mod multiboot2;
pub mod output;
pub mod psfont;
mod traits;
mod util;
pub mod memsections;
#[macro_use]
pub(crate) mod cfg;
@ -47,3 +47,11 @@ pub use util::*;
#[allow(unused_imports)] // if there are no traits, then it gives a warning
pub use traits::*;
pub const fn version() -> &'static str {
env!("VERSION")
}
pub const fn cfg_version() -> &'static str {
env!("CFG_VERSION")
}

View file

@ -9,7 +9,7 @@ pub struct Tag {
/// The type of the tag.
pub tag_type: u32,
/// The length of the tag.
pub tag_len: u32
pub tag_len: u32,
}
/// The root tag. The official Multiboot2 name is literally the "fixed part" of the tags, so I made a better name.
@ -32,7 +32,7 @@ pub struct Module {
pub mod_end: *const u8,
/// A string that should be in the format `module_name (command line arguments)`.
/// See <https://aphrodite-os.github.io/book/bootloader-modules.html>.
pub mod_str: &'static core::ffi::CStr
pub mod_str: &'static core::ffi::CStr,
}
/// One memory section provided by a Multiboot2 bootloader.
@ -58,10 +58,10 @@ impl Into<crate::boot::MemoryMapping> for MemorySection {
2 => crate::boot::MemoryType::HardwareReserved,
3 => crate::boot::MemoryType::HardwareSpecific(3, false),
5 => crate::boot::MemoryType::Faulty,
_ => crate::boot::MemoryType::Reserved
_ => crate::boot::MemoryType::Reserved,
},
start: self.base_addr,
len: self.length
len: self.length,
}
}
}
@ -79,7 +79,7 @@ pub struct RawMemoryMap {
/// The version of the memory map. Should be disregarded as it's 0.
pub entry_version: u32, // currently is 0, future Multiboot2 versions may increment
/// The sections. This is the reason that [Clone] can't be implemented for [RawMemoryMap].
pub sections: [MemorySection]
pub sections: [MemorySection],
}
/// A full memory map provided by a Multiboot2 bootloader.
@ -119,7 +119,7 @@ pub struct PaletteColorDescriptor {
/// The green value
pub green: u8,
/// The blue value
pub blue: u8
pub blue: u8,
}
/// Information about color, for use in [FramebufferInfo].
@ -131,7 +131,7 @@ pub enum ColorInfo {
/// The number of colors in the palette.
num_colors: u32,
/// The first color in the palette.
palette: *const PaletteColorDescriptor
palette: *const PaletteColorDescriptor,
},
/// RGB information for use on the framebuffer.
RGBColor {
@ -151,7 +151,7 @@ pub enum ColorInfo {
blue_mask_size: u8,
},
/// Text information, no metadata
EGAText
EGAText,
}
/// Information about the framebuffer.
@ -172,7 +172,6 @@ pub struct FramebufferInfo {
pub fb_type: u8,
/// Reserved space. Ignore.
reserved: u8,
// Color info after this; we need separate structs for each colorinfo as
// we have to understand the format the bootloader gives us.
}
@ -190,7 +189,6 @@ pub struct Multiboot2BootInfo {
// Multiboot2 bootloaders may provide us with the BIOS device and partition, but we're not interested.
// To ensure future developers don't get any ideas, I'm leaving it out here.
// If you need it, good luck.
/// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by
/// the bootloader.
/// See <https://aphrodite-os.github.io/book/command-line.html> for the format.
@ -201,7 +199,6 @@ pub struct Multiboot2BootInfo {
// Multiboot2 bootloaders may provide us with ELF symbols, but I'm feeling lazy and right now it's mostly
// unnecessary, so I don't care. Sorry if you are affected by this.
/// The memory map provided by the bootloader.
pub memory_map: Option<MemoryMap>,
@ -212,12 +209,10 @@ pub struct Multiboot2BootInfo {
// APM table is ignored as APM has been superseded by ACPI. If your system doesn't support ACPI, good luck.
// VBE table is ignored for a similar reason to above: it's deprecated. Good luck if you need it.
/// Provides information on the framebuffer.
pub framebuffer_info: Option<FramebufferInfo>,
/// Color info, stored separately from [FramebufferInfo] because rust
pub color_info: Option<ColorInfo>,
// Even though SMBIOS is documented for Multiboot2, we're not using it and will instead search for it ourselves.
// This is because right now I cannot figure out what format it provides the SMBIOS table in.

View file

@ -1,7 +1,7 @@
//! Architecture-independent output functions.
use paste::paste;
use crate::display::COLOR_DEFAULT;
use paste::paste;
/// The position to output stuff to.
static mut OUTPUT_TERM_POSITION: (u32, u32) = (0, 0);
@ -157,4 +157,4 @@ pub fn sreset() {
unsafe {
OUTPUT_TERM_POSITION = (0, 0);
}
}
}

View file

@ -82,17 +82,13 @@ pub fn parse_raw_pc_screen_font(data: Vec<u8>) -> Result<RawPCScreenFont, crate:
}
/// Parses a PC Screen Font into a [PCScreenFont].
pub fn parse_pc_screen_font(
data: RawPCScreenFont,
) -> Result<PCScreenFont, crate::Error<'static>> {
pub fn parse_pc_screen_font(data: RawPCScreenFont) -> Result<PCScreenFont, crate::Error<'static>> {
unsafe {
if data.flags == 0 {
let mut unitable: Vec<Vec<u8>> = Vec::with_capacity(data.num_glyphs as usize * core::mem::size_of::<Vec<u8>>());
let mut unitable: Vec<Vec<u8>> =
Vec::with_capacity(data.num_glyphs as usize * core::mem::size_of::<Vec<u8>>());
let unistr = (data
.glyphs
.as_slice()
as *const [u8])
let unistr = (data.glyphs.as_slice() as *const [u8])
.byte_add(data.bytes_per_glyph as usize * data.num_glyphs as usize);
let mut i = 0usize;
@ -136,9 +132,7 @@ pub fn parse_pc_screen_font(
}
/// Parses a Vec<u8> into a [PCScreenFont].
pub fn parse_psfu(
data: Vec<u8>,
) -> Result<PCScreenFont, crate::Error<'static>> {
pub fn parse_psfu(data: Vec<u8>) -> Result<PCScreenFont, crate::Error<'static>> {
let data = parse_raw_pc_screen_font(data)?;
parse_pc_screen_font(data)
}

View file

@ -13,7 +13,7 @@ pub const fn i16_as_u8_slice(mut value: i16) -> [u8; 6] {
}
i = 5;
while value > 0 {
let digit = value%10;
let digit = value % 10;
let char = b'0' + digit as u8;
buf[i] = char;
value = value / 10;
@ -30,7 +30,7 @@ pub const fn u32_as_u8_slice(mut value: u32) -> [u8; 10] {
buf[0] = b'0';
}
while value > 0 {
let digit = value%10;
let digit = value % 10;
let char = b'0' + digit as u8;
buf[i] = char;
value = value / 10;
@ -47,7 +47,7 @@ pub const fn u8_as_u8_slice(mut value: u8) -> [u8; 3] {
buf[0] = b'0';
}
while value > 0 {
let digit = value%10;
let digit = value % 10;
let char = b'0' + digit as u8;
buf[i] = char;
value = value / 10;
@ -64,7 +64,7 @@ pub const fn usize_as_u8_slice(mut value: usize) -> [u8; 20] {
buf[0] = b'0';
}
while value > 0 {
let digit = value%10;
let digit = value % 10;
let char = b'0' + digit as u8;
buf[i] = char;
value = value / 10;
@ -81,7 +81,7 @@ pub const fn u64_as_u8_slice(mut value: u64) -> [u8; 20] {
buf[0] = b'0';
}
while value > 0 {
let digit = value%10;
let digit = value % 10;
let char = b'0' + digit as u8;
buf[i] = char;
value = value / 10;
@ -103,7 +103,7 @@ pub fn str_as_i16(mut value: &[u8]) -> i16 {
continue;
}
out *= 10;
out += (byte-b'0') as i16;
out += (byte - b'0') as i16;
}
let mut reversed = 0;
@ -125,7 +125,7 @@ pub fn str_as_u32(value: &[u8]) -> u32 {
continue;
}
out *= 10;
out += (byte-b'0') as u32;
out += (byte - b'0') as u32;
}
let mut reversed = 0;
@ -147,7 +147,7 @@ pub fn str_as_u128(value: &[u8]) -> u128 {
continue;
}
out *= 10;
out += (byte-b'0') as u128;
out += (byte - b'0') as u128;
}
let mut reversed = 0;
@ -169,7 +169,7 @@ pub fn str_as_u64(value: &[u8]) -> u64 {
continue;
}
out *= 10;
out += (byte-b'0') as u64;
out += (byte - b'0') as u64;
}
let mut reversed = 0;
@ -180,4 +180,4 @@ pub fn str_as_u64(value: &[u8]) -> u64 {
}
reversed
}
}