progress!! multiboot2 tag reading is still very broke though
This commit is contained in:
parent
0b87ccb219
commit
83f6c5cea4
21 changed files with 207 additions and 120 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -18,4 +18,9 @@ Cargo.lock
|
||||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
|
# Generated grub files
|
||||||
|
kernel/grub/
|
||||||
|
aphrodite-grub.iso
|
||||||
|
aphrodite.iso
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -2,7 +2,6 @@
|
||||||
"rust-analyzer.cargo.allTargets": false,
|
"rust-analyzer.cargo.allTargets": false,
|
||||||
"rust-analyzer.check.allTargets": false,
|
"rust-analyzer.check.allTargets": false,
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"kernel/Cargo.toml",
|
"kernel/Cargo.toml"
|
||||||
"patcher/Cargo.toml"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,3 +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
|
cpu: reset_on_triple_fault=0
|
||||||
|
|
||||||
|
ata0-master: type=cdrom, path=../kernel/aphrodite.iso, status=inserted
|
||||||
|
boot: cdrom
|
26
emulation/bx_enh_dbg.ini
Normal file
26
emulation/bx_enh_dbg.ini
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# bx_enh_dbg_ini
|
||||||
|
SeeReg[0] = TRUE
|
||||||
|
SeeReg[1] = TRUE
|
||||||
|
SeeReg[2] = TRUE
|
||||||
|
SeeReg[3] = TRUE
|
||||||
|
SeeReg[4] = FALSE
|
||||||
|
SeeReg[5] = FALSE
|
||||||
|
SeeReg[6] = FALSE
|
||||||
|
SeeReg[7] = FALSE
|
||||||
|
SingleCPU = FALSE
|
||||||
|
ShowIOWindows = TRUE
|
||||||
|
ShowButtons = TRUE
|
||||||
|
SeeRegColors = TRUE
|
||||||
|
ignoreNxtT = TRUE
|
||||||
|
ignSSDisasm = TRUE
|
||||||
|
UprCase = 0
|
||||||
|
DumpInAsciiMode = 3
|
||||||
|
isLittleEndian = TRUE
|
||||||
|
DefaultAsmLines = 512
|
||||||
|
DumpWSIndex = 0
|
||||||
|
DockOrder = 0x123
|
||||||
|
ListWidthPix[0] = 354
|
||||||
|
ListWidthPix[1] = 411
|
||||||
|
ListWidthPix[2] = 512
|
||||||
|
MainWindow = 0, 0, 895, 500
|
||||||
|
FontName = Normal
|
|
@ -1,5 +1,6 @@
|
||||||
[build]
|
[build]
|
||||||
target = "i686-unknown-none.json"
|
target = "i686-unknown-none.json"
|
||||||
|
rustflags = ["-Clink-arg=--script=link.x"]
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["core"]
|
build-std = ["core"]
|
12
kernel/build
12
kernel/build
|
@ -7,23 +7,21 @@ if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
|
||||||
|
|
||||||
get_version
|
get_version
|
||||||
|
|
||||||
cd ../patcher
|
|
||||||
cargo build --release
|
|
||||||
cd ../kernel
|
cd ../kernel
|
||||||
|
|
||||||
RUSTFLAGS='-Clink-arg=--script=link.x' cargo build --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint
|
cargo build --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint
|
||||||
# build the kernel's entrypoint
|
# build the kernel's entrypoint
|
||||||
|
|
||||||
cp target/i686-unknown-none/release/entrypoint kernel.flat
|
cp target/i686-unknown-none/release/entrypoint kernel.flat
|
||||||
# copy it out
|
# copy it out
|
||||||
|
|
||||||
../patcher/target/release/patcher
|
|
||||||
# run the custom patching program to add the multiboot2 header
|
|
||||||
|
|
||||||
rm -rf grub
|
rm -rf grub
|
||||||
|
|
||||||
cp -r ./grub_template ./grub
|
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
|
4
kernel/build_and_emulate
Executable file
4
kernel/build_and_emulate
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
./build
|
||||||
|
./emulate
|
4
kernel/emulate
Executable file
4
kernel/emulate
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd ../emulation
|
||||||
|
bochs -q
|
|
@ -1,9 +1,13 @@
|
||||||
function get_version() {
|
function get_version() {
|
||||||
local TEMP_SUFFIX
|
local TEMP_SUFFIX
|
||||||
if [[ ! $(git diff-index --quiet HEAD --) ]]; then
|
if git diff-index HEAD -- 2>&1 > /dev/null
|
||||||
|
then
|
||||||
|
echo -n
|
||||||
|
# N/A
|
||||||
|
else
|
||||||
TEMP_SUFFIX="-out-of-tree"
|
TEMP_SUFFIX="-out-of-tree"
|
||||||
fi
|
fi
|
||||||
SUFFIX="${SUFFIX:-$TEMP_SUFFIX}"
|
SUFFIX="$SUFFIX$TEMP_SUFFIX"
|
||||||
|
|
||||||
VERSION="${VERSION:-devel-$(git rev-parse --short HEAD)$SUFFIX}"
|
VERSION="${VERSION:-devel-$(git rev-parse --short HEAD)$SUFFIX}"
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,8 @@
|
||||||
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-6985552-out-of-tree' {
|
set timeout=15
|
||||||
set root='hd1,gpt2'
|
set default=0
|
||||||
echo 'Loading Aphrodite aphrodite-devel-6985552-out-of-tree ...'
|
|
||||||
|
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-0b87ccb' {
|
||||||
|
echo 'Loading Aphrodite aphrodite-devel-0b87ccb ...'
|
||||||
multiboot2 /boot/aphrodite.kernel
|
multiboot2 /boot/aphrodite.kernel
|
||||||
|
boot
|
||||||
}
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
|
set timeout=15
|
||||||
|
set default=0
|
||||||
|
|
||||||
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-%{VERSION}' {
|
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-%{VERSION}' {
|
||||||
set root='hd1,gpt2'
|
|
||||||
echo 'Loading Aphrodite aphrodite-%{VERSION} ...'
|
echo 'Loading Aphrodite aphrodite-%{VERSION} ...'
|
||||||
multiboot2 /boot/aphrodite.kernel
|
multiboot2 /boot/aphrodite.kernel
|
||||||
|
boot
|
||||||
}
|
}
|
Binary file not shown.
|
@ -1,9 +1,10 @@
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
OUTPUT_FORMAT(binary)
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
.text : {
|
.text : {
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
|
KEEP(*(.multiboot2))
|
||||||
KEEP(*(.start))
|
KEEP(*(.start))
|
||||||
KEEP(*(.text))
|
KEEP(*(.text))
|
||||||
KEEP(*(.panic))
|
KEEP(*(.panic))
|
||||||
|
|
|
@ -18,6 +18,11 @@ macro_rules! message_funcs {
|
||||||
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||||
ports::outbs(super::DEBUG_PORT, s);
|
ports::outbs(super::DEBUG_PORT, s);
|
||||||
}
|
}
|
||||||
|
/// Outputs a(n) $func_name message u8 to the debug serial port.
|
||||||
|
pub fn [< s $func_name u >](s: u8) {
|
||||||
|
ports::outbs(super::DEBUG_PORT, $prefix.as_bytes());
|
||||||
|
ports::outb(super::DEBUG_PORT, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,4 +32,5 @@ message_funcs!(info, "[INFO] ");
|
||||||
message_funcs!(warning, "[WARN] ");
|
message_funcs!(warning, "[WARN] ");
|
||||||
message_funcs!(error, "[ERROR] ");
|
message_funcs!(error, "[ERROR] ");
|
||||||
message_funcs!(fatal, "[FATAL] ");
|
message_funcs!(fatal, "[FATAL] ");
|
||||||
|
message_funcs!(output, "");
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,5 @@
|
||||||
//! Stuff related to errors.
|
//! Stuff related to errors.
|
||||||
|
|
||||||
/// Converts an i16 to an [u8; 6].
|
|
||||||
pub fn i16_as_u8_slice(mut value: i16) -> [u8; 6] {
|
|
||||||
let mut buf = [0u8; 6];
|
|
||||||
let mut i = 0;
|
|
||||||
if value < 0 {
|
|
||||||
buf[i] = b'-';
|
|
||||||
value = -value;
|
|
||||||
}
|
|
||||||
i = 5;
|
|
||||||
while value > 0 {
|
|
||||||
let digit = value%10;
|
|
||||||
let char = b'0' + digit as u8;
|
|
||||||
buf[i] = char;
|
|
||||||
value = value / 10;
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
buf
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error used by aphrodite
|
/// An error used by aphrodite
|
||||||
pub struct Error<'a> {
|
pub struct Error<'a> {
|
||||||
message: &'a str,
|
message: &'a str,
|
||||||
|
@ -27,7 +8,7 @@ pub struct Error<'a> {
|
||||||
|
|
||||||
impl core::fmt::Debug for Error<'_> {
|
impl core::fmt::Debug for Error<'_> {
|
||||||
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(core::str::from_utf8(&i16_as_u8_slice(self.code)).unwrap())?;
|
f.write_str(core::str::from_utf8(&crate::i16_as_u8_slice(self.code)).unwrap())?;
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
f.write_str(self.message)
|
f.write_str(self.message)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +16,7 @@ impl core::fmt::Debug for Error<'_> {
|
||||||
|
|
||||||
impl core::fmt::Display for Error<'_> {
|
impl core::fmt::Display for Error<'_> {
|
||||||
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(core::str::from_utf8(&i16_as_u8_slice(self.code)).unwrap())?;
|
f.write_str(core::str::from_utf8(&crate::i16_as_u8_slice(self.code)).unwrap())?;
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
f.write_str(self.message)
|
f.write_str(self.message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#![feature(ptr_metadata)]
|
#![feature(ptr_metadata)]
|
||||||
|
|
||||||
mod constants;
|
mod constants;
|
||||||
|
mod util;
|
||||||
pub mod multiboot2;
|
pub mod multiboot2;
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
@ -11,4 +12,5 @@ mod errors;
|
||||||
#[allow(unused_imports)] // if there are no constants, then it gives a warning
|
#[allow(unused_imports)] // if there are no constants, then it gives a warning
|
||||||
pub use constants::*;
|
pub use constants::*;
|
||||||
|
|
||||||
pub use errors::*;
|
pub use errors::*;
|
||||||
|
pub use util::*;
|
57
kernel/src/include/util.rs
Normal file
57
kernel/src/include/util.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
//! Utility functions
|
||||||
|
|
||||||
|
/// Converts an i16 to an [u8; 6].
|
||||||
|
pub fn i16_as_u8_slice(mut value: i16) -> [u8; 6] {
|
||||||
|
let mut buf = [0u8; 6];
|
||||||
|
let mut i = 0;
|
||||||
|
if value < 0 {
|
||||||
|
buf[i] = b'-';
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
if value == 0 {
|
||||||
|
buf[0] = b'0';
|
||||||
|
}
|
||||||
|
i = 5;
|
||||||
|
while value > 0 {
|
||||||
|
let digit = value%10;
|
||||||
|
let char = b'0' + digit as u8;
|
||||||
|
buf[i] = char;
|
||||||
|
value = value / 10;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
buf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts an u32 to an [u8; 10].
|
||||||
|
pub fn u32_as_u8_slice(mut value: u32) -> [u8; 10] {
|
||||||
|
let mut buf = [0u8; 10];
|
||||||
|
let mut i = 9;
|
||||||
|
if value == 0 {
|
||||||
|
buf[0] = b'0';
|
||||||
|
}
|
||||||
|
while value > 0 {
|
||||||
|
let digit = value%10;
|
||||||
|
let char = b'0' + digit as u8;
|
||||||
|
buf[i] = char;
|
||||||
|
value = value / 10;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
buf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts an usize(32 or 64 bit) to an [u8; 10].
|
||||||
|
pub fn usize_as_u8_slice(mut value: usize) -> [u8; 20] {
|
||||||
|
let mut buf = [0u8; 20];
|
||||||
|
let mut i = 19;
|
||||||
|
if value == 0 {
|
||||||
|
buf[0] = b'0';
|
||||||
|
}
|
||||||
|
while value > 0 {
|
||||||
|
let digit = value%10;
|
||||||
|
let char = b'0' + digit as u8;
|
||||||
|
buf[i] = char;
|
||||||
|
value = value / 10;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
buf
|
||||||
|
}
|
|
@ -6,6 +6,16 @@
|
||||||
|
|
||||||
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
|
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
|
||||||
use aphrodite::multiboot2::{BootInfo, CString, ColorInfo, FramebufferInfo, MemoryMap, PaletteColorDescriptor, RawMemoryMap, RootTag, Tag};
|
use aphrodite::multiboot2::{BootInfo, CString, ColorInfo, FramebufferInfo, MemoryMap, PaletteColorDescriptor, RawMemoryMap, RootTag, Tag};
|
||||||
|
use aphrodite::arch::x86::output::*;
|
||||||
|
|
||||||
|
#[unsafe(link_section = ".multiboot2")]
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
static MULTIBOOT2_HEADER: [u8; 29] = [
|
||||||
|
0xd6, 0x50, 0x52, 0xe8, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0x12, 0xaf, 0xad, 0x17,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0xe9, 0x55, 0x00, 0x00, 0x00
|
||||||
|
];
|
||||||
|
|
||||||
// The root tag, provided directly from the multiboot bootloader.
|
// The root tag, provided directly from the multiboot bootloader.
|
||||||
static mut RT: *const RootTag = core::ptr::null();
|
static mut RT: *const RootTag = core::ptr::null();
|
||||||
|
@ -31,10 +41,9 @@ static mut MAGIC: u32 = 0xFFFFFFFF;
|
||||||
extern "C" fn _start() -> ! {
|
extern "C" fn _start() -> ! {
|
||||||
unsafe { // Copy values provided by the bootloader out
|
unsafe { // Copy values provided by the bootloader out
|
||||||
asm!(
|
asm!(
|
||||||
"mov {0:e}, eax", out(reg) MAGIC // Magic number
|
"mov ebx, ebx", out("ebx") O, // Bootloader-specific data(ebx)
|
||||||
);
|
out("eax") MAGIC, // Magic number(eax)
|
||||||
asm!(
|
options(nomem, nostack, preserves_flags, pure)
|
||||||
"mov {0:e}, ebx", out(reg) O // Bootloader-specific data
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -42,38 +51,66 @@ extern "C" fn _start() -> ! {
|
||||||
0x36D76289 => { // Multiboot2
|
0x36D76289 => { // Multiboot2
|
||||||
RT = O as *const RootTag; // This is unsafe rust! We can do whatever we want! *manical laughter*
|
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("Root tag address is: ");
|
||||||
|
soutputb(&aphrodite::usize_as_u8_slice(O as usize));
|
||||||
|
soutputu(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 mut ptr = O as usize;
|
let mut ptr = O as usize;
|
||||||
ptr += size_of::<RootTag>();
|
ptr += size_of::<RootTag>();
|
||||||
|
|
||||||
let mut current_tag = ptr as *const Tag;
|
let mut current_tag = core::ptr::read_volatile(ptr as *const Tag);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match (*current_tag).tag_type {
|
sdebugs("Tag address is: ");
|
||||||
|
soutputb(&aphrodite::usize_as_u8_slice(ptr));
|
||||||
|
soutputu(b'\n');
|
||||||
|
|
||||||
|
sdebugs("Tag type is: ");
|
||||||
|
soutputb(&aphrodite::u32_as_u8_slice(current_tag.tag_type));
|
||||||
|
soutputu(b'\n');
|
||||||
|
|
||||||
|
sdebugs("Tag length is: ");
|
||||||
|
soutputb(&aphrodite::u32_as_u8_slice(current_tag.tag_len));
|
||||||
|
soutputu(b'\n');
|
||||||
|
|
||||||
|
soutputu(b'\n');
|
||||||
|
|
||||||
|
match current_tag.tag_type {
|
||||||
0 => { // Ending tag
|
0 => { // Ending tag
|
||||||
if (*current_tag).tag_len != 8 { // Unexpected size, something is probably up
|
if current_tag.tag_len != 8 { // Unexpected size, something is probably up
|
||||||
panic!("size of ending tag != 8");
|
panic!("size of ending tag != 8");
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
},
|
},
|
||||||
4 => { // Basic memory information
|
4 => { // Basic memory information
|
||||||
if (*current_tag).tag_len != 16 { // Unexpected size, something is probably up
|
if current_tag.tag_len != 16 { // Unexpected size, something is probably up
|
||||||
panic!("size of basic memory information tag != 16");
|
panic!("size of basic memory information tag != 16");
|
||||||
}
|
}
|
||||||
|
|
||||||
BI.mem_lower = Some(*((current_tag as usize + 8) as *const u32));
|
BI.mem_lower = Some(*((ptr + 8) as *const u32));
|
||||||
BI.mem_upper = Some(*((current_tag as usize + 12) as *const u32));
|
BI.mem_upper = Some(*((ptr + 12) as *const u32));
|
||||||
// The end result of the above is adding an offset to a pointer and retrieving the value at that pointer
|
// The end result of the above is adding an offset to a pointer and retrieving the value at that pointer
|
||||||
},
|
},
|
||||||
5 => { // BIOS boot device, ignore
|
5 => { // BIOS boot device, ignore
|
||||||
if (*current_tag).tag_len != 20 { // Unexpected size, something is probably up
|
if current_tag.tag_len != 20 { // Unexpected size, something is probably up
|
||||||
panic!("size of bios boot device tag != 20");
|
panic!("size of bios boot device tag != 20");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
1 => { // Command line
|
1 => { // Command line
|
||||||
if (*current_tag).tag_len < 8 { // Unexpected size, something is probably up
|
if current_tag.tag_len < 8 { // Unexpected size, something is probably up
|
||||||
panic!("size of command line tag < 8");
|
panic!("size of command line tag < 8");
|
||||||
}
|
}
|
||||||
let cstring = CStr::from_ptr((current_tag as usize + 8) as *const i8);
|
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
|
||||||
// creates a &core::ffi::CStr from the start of the command line...
|
// creates a &core::ffi::CStr from the start of the command line...
|
||||||
|
|
||||||
let cstring = CString {
|
let cstring = CString {
|
||||||
|
@ -86,11 +123,11 @@ extern "C" fn _start() -> ! {
|
||||||
// ...before the BootInfo's commandline is set.
|
// ...before the BootInfo's commandline is set.
|
||||||
},
|
},
|
||||||
6 => { // Memory map tag
|
6 => { // Memory map tag
|
||||||
if (*current_tag).tag_len < 16 { // Unexpected size, something is probably up
|
if current_tag.tag_len < 16 { // Unexpected size, something is probably up
|
||||||
panic!("size of memory map tag < 16");
|
panic!("size of memory map tag < 16");
|
||||||
}
|
}
|
||||||
let rawmemorymap: *const RawMemoryMap = core::ptr::from_raw_parts(
|
let rawmemorymap: *const RawMemoryMap = core::ptr::from_raw_parts(
|
||||||
current_tag, ((*current_tag).tag_len / *((current_tag as usize + 8usize) as *const u32)) as usize
|
ptr as *const 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
|
// 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
|
// and has all of the [aphrodite::multiboot2::MemorySection]s for the memory map
|
||||||
|
@ -103,10 +140,10 @@ extern "C" fn _start() -> ! {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
2 => { // Bootloader name
|
2 => { // Bootloader name
|
||||||
if (*current_tag).tag_len < 8 { // Unexpected size, something is probably up
|
if current_tag.tag_len < 8 { // Unexpected size, something is probably up
|
||||||
panic!("size of command line tag < 8");
|
panic!("size of command line tag < 8");
|
||||||
}
|
}
|
||||||
let cstring = CStr::from_ptr((current_tag as usize + 8) as *const i8);
|
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
|
||||||
// creates a &core::ffi::CStr from the start of the bootloader name...
|
// creates a &core::ffi::CStr from the start of the bootloader name...
|
||||||
|
|
||||||
let cstring = CString {
|
let cstring = CString {
|
||||||
|
@ -119,26 +156,26 @@ extern "C" fn _start() -> ! {
|
||||||
// ...before the BootInfo's bootloader_name is set.
|
// ...before the BootInfo's bootloader_name is set.
|
||||||
},
|
},
|
||||||
8 => { // Framebuffer info
|
8 => { // Framebuffer info
|
||||||
if (*current_tag).tag_len < 40 { // Unexpected size, something is probably up
|
if current_tag.tag_len < 40 { // Unexpected size, something is probably up
|
||||||
panic!("size of framebuffer info tag < 40");
|
panic!("size of framebuffer info tag < 40");
|
||||||
}
|
}
|
||||||
let framebufferinfo: *const FramebufferInfo = current_tag as *const FramebufferInfo;
|
let framebufferinfo: *const FramebufferInfo = ptr as *const FramebufferInfo;
|
||||||
let colorinfo: ColorInfo;
|
let colorinfo: ColorInfo;
|
||||||
match (*framebufferinfo).fb_type {
|
match (*framebufferinfo).fb_type {
|
||||||
0 => { // Indexed
|
0 => { // Indexed
|
||||||
colorinfo = ColorInfo::Palette {
|
colorinfo = ColorInfo::Palette {
|
||||||
num_colors: *((current_tag as usize + 40) as *const u32),
|
num_colors: *((ptr + 40) as *const u32),
|
||||||
palette: (current_tag as usize + 44) as *const PaletteColorDescriptor
|
palette: (ptr + 44) as *const PaletteColorDescriptor
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
1 => { // RGB
|
1 => { // RGB
|
||||||
colorinfo = ColorInfo::RGBColor {
|
colorinfo = ColorInfo::RGBColor {
|
||||||
red_field_position: *((current_tag as usize + 40) as *const u8),
|
red_field_position: *((ptr + 40) as *const u8),
|
||||||
red_mask_size: *((current_tag as usize + 41) as *const u8),
|
red_mask_size: *((ptr + 41) as *const u8),
|
||||||
green_field_position: *((current_tag as usize + 42) as *const u8),
|
green_field_position: *((ptr + 42) as *const u8),
|
||||||
green_mask_size: *((current_tag as usize + 43) as *const u8),
|
green_mask_size: *((ptr + 43) as *const u8),
|
||||||
blue_field_position: *((current_tag as usize + 44) as *const u8),
|
blue_field_position: *((ptr + 44) as *const u8),
|
||||||
blue_mask_size: *((current_tag as usize + 45) as *const u8)
|
blue_mask_size: *((ptr + 45) as *const u8)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
2 => { // EGA Text
|
2 => { // EGA Text
|
||||||
|
@ -151,11 +188,15 @@ extern "C" fn _start() -> ! {
|
||||||
BI.framebuffer_info = Some((*framebufferinfo).clone());
|
BI.framebuffer_info = Some((*framebufferinfo).clone());
|
||||||
BI.color_info = Some(colorinfo);
|
BI.color_info = Some(colorinfo);
|
||||||
},
|
},
|
||||||
|
4294967295 => { // oh no, THIS bug happened
|
||||||
|
panic!("your code is fucked up")
|
||||||
|
},
|
||||||
_ => { // Unknown/unimplemented tag type, ignore
|
_ => { // Unknown/unimplemented tag type, ignore
|
||||||
// TODO: Add info message
|
// TODO: Add info message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_tag = (current_tag as usize + (*current_tag).tag_len as usize) as *const Tag;
|
ptr = ptr + current_tag.tag_len as usize;
|
||||||
|
current_tag = core::ptr::read_volatile(ptr as *const Tag);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => { // Unknown bootloader, panic
|
_ => { // Unknown bootloader, panic
|
||||||
|
@ -172,7 +213,7 @@ extern "C" fn _start() -> ! {
|
||||||
fn handle_panic(info: &PanicInfo) -> ! {
|
fn handle_panic(info: &PanicInfo) -> ! {
|
||||||
let message = info.message().as_str().unwrap_or("");
|
let message = info.message().as_str().unwrap_or("");
|
||||||
if message != "" {
|
if message != "" {
|
||||||
aphrodite::arch::x86::output::sfatals(message);
|
sfatals(message);
|
||||||
aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n');
|
aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n');
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "patcher"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
|
@ -1,45 +0,0 @@
|
||||||
use std::{fs, io::Write};
|
|
||||||
|
|
||||||
static MULTIBOOT_HEADER: [u32; 6] = [
|
|
||||||
// Magic fields
|
|
||||||
0xE85250D6, // Magic number
|
|
||||||
0x00000000, // Architecture, 0=i386
|
|
||||||
0x00000018, // length of MULTIBOOT_HEADER
|
|
||||||
0x17ADAF12, // checksum=all magic field excluding this+this=0
|
|
||||||
|
|
||||||
// Ending tag- empty flags, size 8
|
|
||||||
0x00000000,
|
|
||||||
0x00000008
|
|
||||||
];
|
|
||||||
|
|
||||||
fn from_u32(from: &mut [u32]) -> &[u8] {
|
|
||||||
if cfg!(target_endian = "big") {
|
|
||||||
for byte in from.iter_mut() {
|
|
||||||
*byte = byte.to_le();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let len = from.len().checked_mul(4).unwrap();
|
|
||||||
let ptr: *const u8 = from.as_ptr().cast();
|
|
||||||
unsafe { std::slice::from_raw_parts(ptr, len) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let path = "./kernel.flat";
|
|
||||||
let mut buf = fs::read(path).unwrap();
|
|
||||||
buf = [
|
|
||||||
from_u32(&mut (MULTIBOOT_HEADER.clone())).to_vec(),
|
|
||||||
vec![ // jump past patch text
|
|
||||||
0xE9, 0x55, 0x00, 0x00, 0x00
|
|
||||||
],
|
|
||||||
b"Multiboot2 header patched by Aphrodite ".to_vec(),
|
|
||||||
b"APHROKERN: OSS at github.com/AverseABFun/Aphrodite".to_vec(),
|
|
||||||
buf
|
|
||||||
].concat();
|
|
||||||
fs::OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.open(path)
|
|
||||||
.unwrap()
|
|
||||||
.write(buf.as_mut_slice())
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue