commit before bed, i'm making good progress
This commit is contained in:
parent
83f6c5cea4
commit
b3558c2508
11 changed files with 207 additions and 45 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -23,4 +23,11 @@ Cargo.lock
|
|||
# Generated grub files
|
||||
kernel/grub/
|
||||
aphrodite-grub.iso
|
||||
aphrodite.iso
|
||||
aphrodite.iso
|
||||
|
||||
# Generated files
|
||||
kernel.flat
|
||||
config.aphro.tmp
|
||||
|
||||
# Per-developer files
|
||||
config.aphro
|
20
kernel/build
20
kernel/build
|
@ -7,6 +7,10 @@ if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
|
|||
|
||||
get_version
|
||||
|
||||
cp config.aphro config.aphro.tmp
|
||||
|
||||
export $(grep -Ev '^#' config.aphro.tmp | xargs)
|
||||
|
||||
cd ../kernel
|
||||
|
||||
cargo build --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint
|
||||
|
@ -15,13 +19,17 @@ cargo build --target i686-unknown-none.json --release -Zbuild-std --bin entrypoi
|
|||
cp target/i686-unknown-none/release/entrypoint kernel.flat
|
||||
# copy it out
|
||||
|
||||
rm -rf grub
|
||||
rm -rf grub aphrodite.iso aphrodite-grub.iso
|
||||
|
||||
cp -r ./grub_template ./grub
|
||||
if [[ $CONFIG_BUILD_GRUB = "true" ]]; then
|
||||
cp -r ./grub_template ./grub
|
||||
|
||||
cp kernel.flat ./grub/boot/aphrodite.kernel
|
||||
cp kernel.flat ./grub/boot/aphrodite.kernel
|
||||
|
||||
sed -i "s@%{VERSION}@$VERSION@g" ./grub/boot/grub/grub.cfg
|
||||
sed -i "s@%{VERSION}@$VERSION@g" ./grub/boot/grub/grub.cfg
|
||||
|
||||
grub-mkrescue -o aphrodite-grub.iso grub
|
||||
cp aphrodite-grub.iso aphrodite.iso
|
||||
grub-mkrescue -o aphrodite-grub.iso grub
|
||||
cp aphrodite-grub.iso aphrodite.iso
|
||||
fi
|
||||
|
||||
reset_version_vars
|
26
kernel/build.rs
Normal file
26
kernel/build.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
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_PREUSER_HALT_ON_PANIC, values("true", "false", none()))"#);
|
||||
println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_SPIN_ON_PANIC, 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()))"#);
|
||||
// End checks
|
||||
|
||||
// Configuration name used when a config is required but should always evaluate to true
|
||||
println!(r#"cargo:rustc-check-cfg=cfg(NONE, values("false", none()))"#);
|
||||
|
||||
for (var, val) in env {
|
||||
if !var.starts_with("CONFIG_") {
|
||||
continue
|
||||
}
|
||||
println!("cargo:rerun-if-env-changed={}", var);
|
||||
println!("cargo:rustc-cfg={}=\"{}\"", var, val);
|
||||
}
|
||||
}
|
23
kernel/config.aphro.example
Normal file
23
kernel/config.aphro.example
Normal file
|
@ -0,0 +1,23 @@
|
|||
# config.aphro for aphrodite devel-83f6c5c-out-of-tree
|
||||
|
||||
# Begin metadata
|
||||
|
||||
# Set VERSION=generate to attempt to autogenerate a version based on git information
|
||||
VERSION=generate
|
||||
# SUFFIX is unset
|
||||
|
||||
# End metadata
|
||||
|
||||
# Begin configs
|
||||
CONFIG_DISABLE_MULTIBOOT2_SUPPORT=false
|
||||
CONFIG_PREUSER_HALT_ON_PANIC=false
|
||||
CONFIG_PREUSER_SPIN_ON_PANIC=true
|
||||
|
||||
CONFIG_PREUSER_OUTPUT_DEBUG=true
|
||||
CONFIG_PREUSER_OUTPUT_INFO=true
|
||||
CONFIG_PREUSER_OUTPUT_WARN=true
|
||||
CONFIG_PREUSER_OUTPUT_ERROR=true
|
||||
CONFIG_PREUSER_OUTPUT_FATAL=true
|
||||
|
||||
CONFIG_BUILD_GRUB=true
|
||||
# End configs
|
|
@ -1,10 +1,10 @@
|
|||
function get_version() {
|
||||
local TEMP_SUFFIX
|
||||
if [[ $VERSION = "generate" ]]; then
|
||||
unset VERSION
|
||||
fi
|
||||
if git diff-index HEAD -- 2>&1 > /dev/null
|
||||
then
|
||||
echo -n
|
||||
# N/A
|
||||
else
|
||||
TEMP_SUFFIX="-out-of-tree"
|
||||
fi
|
||||
SUFFIX="$SUFFIX$TEMP_SUFFIX"
|
||||
|
|
Binary file not shown.
|
@ -1,8 +1,8 @@
|
|||
set timeout=15
|
||||
set default=0
|
||||
|
||||
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-0b87ccb' {
|
||||
echo 'Loading Aphrodite aphrodite-devel-0b87ccb ...'
|
||||
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-generate' {
|
||||
echo 'Loading Aphrodite aphrodite-generate ...'
|
||||
multiboot2 /boot/aphrodite.kernel
|
||||
boot
|
||||
}
|
Binary file not shown.
|
@ -15,6 +15,13 @@ pub fn interrupts_enabled() -> bool {
|
|||
(flags & (1 << 9)) == 0
|
||||
}
|
||||
|
||||
/// Disables interrupts.
|
||||
pub fn disable_interrupts() {
|
||||
unsafe {
|
||||
asm!("cli")
|
||||
}
|
||||
}
|
||||
|
||||
/// Disables interrupts and returns the value of them.
|
||||
pub fn pop_irq() -> u32 {
|
||||
let flags: u32;
|
||||
|
|
|
@ -6,31 +6,102 @@ use super::ports;
|
|||
use paste::paste;
|
||||
|
||||
macro_rules! message_funcs {
|
||||
($func_name:ident, $prefix:literal) => {
|
||||
($func_name:ident, $prefix:literal, $level:ident) => {
|
||||
paste! {
|
||||
/// Outputs a $func_name message &str to the debug serial port.
|
||||
pub fn [< s $func_name s >](s: &str) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||
ports::outbs(super::DEBUG_PORT, s.as_bytes());
|
||||
}
|
||||
/// Outputs a $func_name message &str and a newline to the debug serial port.
|
||||
pub fn [< s $func_name sln >](s: &str) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||
ports::outbs(super::DEBUG_PORT, s.as_bytes());
|
||||
ports::outb(super::DEBUG_PORT, b'\n');
|
||||
}
|
||||
|
||||
/// Outputs a $func_name message &\[u8] to the debug serial port.
|
||||
pub fn [< s $func_name b >](s: &[u8]) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||
ports::outbs(super::DEBUG_PORT, s);
|
||||
}
|
||||
/// Outputs a $func_name message &\[u8] and a newline to the debug serial port.
|
||||
pub fn [< s $func_name bln >](s: &[u8]) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||
ports::outbs(super::DEBUG_PORT, s);
|
||||
ports::outb(super::DEBUG_PORT, b'\n');
|
||||
}
|
||||
|
||||
/// Outputs a(n) $func_name message u8 to the debug serial port.
|
||||
pub fn [< s $func_name u >](s: u8) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||
ports::outb(super::DEBUG_PORT, s);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/// Outputs a $func_name message &str to the debug serial port without a prefix.
|
||||
pub fn [< s $func_name snp >](s: &str) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, s.as_bytes());
|
||||
}
|
||||
/// Outputs a $func_name message &str and a newline to the debug serial port without a prefix.
|
||||
pub fn [< s $func_name snpln >](s: &str) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, s.as_bytes());
|
||||
ports::outb(super::DEBUG_PORT, b'\n');
|
||||
}
|
||||
|
||||
/// Outputs a $func_name message &\[u8] to the debug serial port without a prefix.
|
||||
pub fn [< s $func_name bnp >](s: &[u8]) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, s);
|
||||
}
|
||||
/// Outputs a $func_name message &\[u8] and a newline to the debug serial port without a prefix.
|
||||
pub fn [< s $func_name bnpln >](s: &[u8]) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outbs(super::DEBUG_PORT, s);
|
||||
ports::outb(super::DEBUG_PORT, b'\n');
|
||||
}
|
||||
|
||||
/// Outputs a(n) $func_name message u8 to the debug serial port without a prefix.
|
||||
pub fn [< s $func_name unp >](s: u8) {
|
||||
if cfg!($level = "false") {
|
||||
return
|
||||
}
|
||||
ports::outb(super::DEBUG_PORT, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message_funcs!(debug, "[DEBUG] ");
|
||||
message_funcs!(info, "[INFO] ");
|
||||
message_funcs!(warning, "[WARN] ");
|
||||
message_funcs!(error, "[ERROR] ");
|
||||
message_funcs!(fatal, "[FATAL] ");
|
||||
message_funcs!(output, "");
|
||||
message_funcs!(debug, "[DEBUG] ", CONFIG_PREUSER_OUTPUT_DEBUG);
|
||||
message_funcs!(info, "[INFO] ", CONFIG_PREUSER_OUTPUT_INFO);
|
||||
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);
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(unexpected_cfgs)]
|
||||
#![feature(ptr_metadata)]
|
||||
|
||||
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
|
||||
use aphrodite::multiboot2::{BootInfo, CString, ColorInfo, FramebufferInfo, MemoryMap, PaletteColorDescriptor, RawMemoryMap, RootTag, Tag};
|
||||
use aphrodite::arch::x86::output::*;
|
||||
|
||||
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
|
||||
#[unsafe(link_section = ".multiboot2")]
|
||||
#[unsafe(no_mangle)]
|
||||
static MULTIBOOT2_HEADER: [u8; 29] = [
|
||||
|
@ -17,7 +19,7 @@ static MULTIBOOT2_HEADER: [u8; 29] = [
|
|||
0xe9, 0x55, 0x00, 0x00, 0x00
|
||||
];
|
||||
|
||||
// The root tag, provided directly from the multiboot bootloader.
|
||||
// The root tag, provided directly from the multiboot2 bootloader.
|
||||
static mut RT: *const RootTag = core::ptr::null();
|
||||
// The boot info struct, created from all of the tags.
|
||||
static mut BI: BootInfo = BootInfo {
|
||||
|
@ -40,30 +42,36 @@ static mut MAGIC: u32 = 0xFFFFFFFF;
|
|||
#[unsafe(no_mangle)]
|
||||
extern "C" fn _start() -> ! {
|
||||
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.
|
||||
// we force using ebx and eax as the output of an empty assembly block to let it know.
|
||||
asm!(
|
||||
"mov ebx, ebx", out("ebx") O, // Bootloader-specific data(ebx)
|
||||
out("eax") MAGIC, // Magic number(eax)
|
||||
"", out("ebx") O, // Bootloader-specific data(ebx)
|
||||
out("eax") MAGIC, // Magic number(eax)
|
||||
options(nomem, nostack, preserves_flags, pure)
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
match MAGIC {
|
||||
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
|
||||
0x36D76289 => { // Multiboot2
|
||||
RT = O as *const RootTag; // This is unsafe rust! We can do whatever we want! *manical laughter*
|
||||
|
||||
sdebugs("Total boot info length: ");
|
||||
soutputb(&aphrodite::u32_as_u8_slice((*RT).total_len));
|
||||
soutputu(b'\n');
|
||||
sdebugs("Total boot info length is ");
|
||||
sdebugbnp(&aphrodite::u32_as_u8_slice((*RT).total_len));
|
||||
sdebugunp(b'\n');
|
||||
|
||||
sdebugs("Root tag address is: ");
|
||||
soutputb(&aphrodite::usize_as_u8_slice(O as usize));
|
||||
soutputu(b'\n');
|
||||
sdebugs("Root tag address is ");
|
||||
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.
|
||||
panic!("total length < 16")
|
||||
}
|
||||
|
||||
soutputu(b'\n');
|
||||
let end_addr = O as usize+(*RT).total_len as usize;
|
||||
|
||||
sdebugunp(b'\n');
|
||||
|
||||
let mut ptr = O as usize;
|
||||
ptr += size_of::<RootTag>();
|
||||
|
@ -71,19 +79,14 @@ extern "C" fn _start() -> ! {
|
|||
let mut current_tag = core::ptr::read_volatile(ptr as *const Tag);
|
||||
|
||||
loop {
|
||||
sdebugs("Tag address is: ");
|
||||
soutputb(&aphrodite::usize_as_u8_slice(ptr));
|
||||
soutputu(b'\n');
|
||||
sdebugs("Tag address is ");
|
||||
sdebugbnpln(&aphrodite::usize_as_u8_slice(ptr));
|
||||
|
||||
sdebugs("Tag type is: ");
|
||||
soutputb(&aphrodite::u32_as_u8_slice(current_tag.tag_type));
|
||||
soutputu(b'\n');
|
||||
sdebugs("Tag type is ");
|
||||
sdebugbnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_type));
|
||||
|
||||
sdebugs("Tag length is: ");
|
||||
soutputb(&aphrodite::u32_as_u8_slice(current_tag.tag_len));
|
||||
soutputu(b'\n');
|
||||
|
||||
soutputu(b'\n');
|
||||
sdebugs("Tag length is ");
|
||||
sdebugbnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_len));
|
||||
|
||||
match current_tag.tag_type {
|
||||
0 => { // Ending tag
|
||||
|
@ -188,14 +191,16 @@ extern "C" fn _start() -> ! {
|
|||
BI.framebuffer_info = Some((*framebufferinfo).clone());
|
||||
BI.color_info = Some(colorinfo);
|
||||
},
|
||||
4294967295 => { // oh no, THIS bug happened
|
||||
panic!("your code is fucked up")
|
||||
},
|
||||
_ => { // Unknown/unimplemented tag type, ignore
|
||||
// TODO: Add info message
|
||||
sinfos("Unknown tag type ");
|
||||
sinfobnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_type));
|
||||
}
|
||||
}
|
||||
sinfounp(b'\n');
|
||||
ptr = ptr + current_tag.tag_len as usize;
|
||||
if ptr>end_addr {
|
||||
panic!("current tag length would put pointer out-of-bounds")
|
||||
}
|
||||
current_tag = core::ptr::read_volatile(ptr as *const Tag);
|
||||
}
|
||||
},
|
||||
|
@ -210,13 +215,28 @@ extern "C" fn _start() -> ! {
|
|||
|
||||
#[unsafe(link_section = ".panic")]
|
||||
#[panic_handler]
|
||||
fn handle_panic(info: &PanicInfo) -> ! {
|
||||
#[cfg(not(CONFIG_PREUSER_HALT_ON_PANIC = "false"))]
|
||||
fn halt_on_panic(info: &PanicInfo) -> ! {
|
||||
let message = info.message().as_str().unwrap_or("");
|
||||
if message != "" {
|
||||
sfatals(message);
|
||||
aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n');
|
||||
}
|
||||
aphrodite::arch::x86::interrupts::disable_interrupts();
|
||||
unsafe {
|
||||
asm!("hlt", options(noreturn));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(link_section = ".panic")]
|
||||
#[panic_handler]
|
||||
#[cfg(all(CONFIG_PREUSER_SPIN_ON_PANIC = "true", CONFIG_PREUSER_HALT_ON_PANIC = "false"))]
|
||||
fn spin_on_panic(info: &PanicInfo) -> ! {
|
||||
let message = info.message().as_str().unwrap_or("");
|
||||
if message != "" {
|
||||
sfatals(message);
|
||||
aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n');
|
||||
}
|
||||
aphrodite::arch::x86::interrupts::disable_interrupts();
|
||||
loop {}
|
||||
}
|
Loading…
Add table
Reference in a new issue