Fix relocation issue where an invalid dyn_hdr was loaded, make xunilos

run init at startup, add init build script, delete userspace stub
This commit is contained in:
csd4ni3l
2026-05-07 19:33:03 +02:00
parent 64206d3596
commit 7f27952167
7 changed files with 33 additions and 192 deletions
+1
View File
@@ -1 +1,2 @@
doomgeneric* doomgeneric*
init
+5
View File
@@ -0,0 +1,5 @@
bash build_libxunil.sh
cd user/init
cargo build --target x86_64-unknown-none --release
cp ./target/x86_64-unknown-none/release/init ../../assets/init
cd ../..
-4
View File
@@ -1,4 +0,0 @@
[unstable]
json-target-spec = true
build-std-features = ["compiler-builtins-mem"]
build-std = ["core", "compiler_builtins", "alloc"]
+10 -9
View File
@@ -13,14 +13,11 @@ use x86_64::{
use crate::{ use crate::{
arch::{arch::FRAME_ALLOCATOR, syscall::memset}, arch::{arch::FRAME_ALLOCATOR, syscall::memset},
driver::elf::{ driver::elf::header::{
header::{ DT_JMPREL, DT_NEEDED, DT_NULL, DT_PLTREL, DT_PLTRELSZ, DT_RELA, DT_RELASZ, DT_STRSZ,
DT_JMPREL, DT_NEEDED, DT_NULL, DT_PLTREL, DT_PLTRELSZ, DT_RELA, DT_RELAENT, DT_RELASZ, DT_STRTAB, DT_SYMTAB, Elf64Dyn, Elf64Ehdr, Elf64Phdr, Elf64Rela, Elf64Sym, PF_X,
DT_STRSZ, DT_STRTAB, DT_SYMENT, DT_SYMTAB, Elf64Dyn, Elf64Ehdr, Elf64Phdr, Elf64Rela, PT_DYNAMIC, PT_LOAD, R_X86_64_64, R_X86_64_GLOB_DAT, R_X86_64_JUMP_SLOT, R_X86_64_NONE,
Elf64Sym, PF_X, PT_DYNAMIC, PT_LOAD, R_X86_64_64, R_X86_64_GLOB_DAT, R_X86_64_RELATIVE, SHN_UNDEF, STB_WEAK,
R_X86_64_JUMP_SLOT, R_X86_64_NONE, R_X86_64_RELATIVE, SHN_UNDEF, STB_WEAK,
},
reloc::elf_do_reloc,
}, },
util::{align_down, align_up}, util::{align_down, align_up},
}; };
@@ -111,7 +108,11 @@ pub unsafe fn load_program(
parse_dyn( parse_dyn(
hdr, hdr,
pt_dynamic_header, pt_dynamic_header,
unsafe { elf_bytes.as_ptr().add((*phdr).p_offset as usize) as *const Elf64Dyn }, unsafe {
elf_bytes
.as_ptr()
.add((*pt_dynamic_header).p_offset as usize) as *const Elf64Dyn
},
load_bias, load_bias,
); );
+16 -3
View File
@@ -17,13 +17,19 @@ pub mod task;
pub mod userspace_stub; pub mod userspace_stub;
pub mod util; pub mod util;
use crate::arch::arch::{infinite_idle, init, kernel_crash}; use crate::arch::arch::{infinite_idle, init, kernel_crash, run_elf};
use crate::driver::elf::loader::load_file;
use crate::driver::graphics::base::rgb; use crate::driver::graphics::base::rgb;
use crate::driver::graphics::framebuffer::{init_framebuffer, with_framebuffer}; use crate::driver::graphics::framebuffer::{init_framebuffer, with_framebuffer};
use crate::driver::keyboard::init_keyboard; use crate::driver::keyboard::init_keyboard;
use crate::driver::serial::{ConsoleWriter, init_serial_console, with_serial_console}; use crate::driver::serial::{ConsoleWriter, init_serial_console, with_serial_console};
use crate::driver::timer::TIMER; use crate::driver::timer::TIMER;
use crate::userspace_stub::userspace_init;
#[repr(C, align(16))]
struct AlignedElf([u8; include_bytes!("../../assets/init").len()]);
static INIT_ELF: AlignedElf = AlignedElf(*include_bytes!("../../assets/init"));
static INIT_ELF_BYTES: &[u8] = &INIT_ELF.0;
/// Sets the base revision to the latest revision supported by the crate. /// Sets the base revision to the latest revision supported by the crate.
/// See specification for further info. /// See specification for further info.
/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler. /// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
@@ -125,7 +131,14 @@ unsafe extern "C" fn kmain() -> ! {
println!("Could not get date at boot. Will default to 0.") println!("Could not get date at boot. Will default to 0.")
} }
userspace_init(&mut mapper) let (entry_point, heap_base) = load_file(&mut mapper, INIT_ELF_BYTES);
println!("Entry point: {:?}", entry_point);
with_framebuffer(|fb| fb.swap());
run_elf(entry_point, heap_base);
loop {}
} }
#[panic_handler] #[panic_handler]
-175
View File
@@ -1,175 +0,0 @@
use alloc::string::ToString;
use x86_64::structures::paging::OffsetPageTable;
use crate::{
arch::arch::{run_elf, sleep},
driver::{
elf::loader::load_file,
graphics::{
base::rgb,
framebuffer::with_framebuffer,
primitives::{
circle_filled, circle_outline, rectangle_filled, rectangle_outline,
triangle_outline,
},
},
mouse::MOUSE,
serial::with_serial_console,
timer::TIMER,
},
print, println,
util::{serial_print, test_performance},
};
static CURSOR_BYTES: &[u8] = include_bytes!("../../assets/cursors/default.bmp");
#[repr(C, align(16))]
struct AlignedElf([u8; include_bytes!("../../assets/doomgeneric").len()]);
static TEST_ELF: AlignedElf = AlignedElf(*include_bytes!("../../assets/doomgeneric"));
static TEST_ELF_BYTES: &[u8] = &TEST_ELF.0;
const BMP_HEADER_SIZE: usize = 138;
pub const CURSOR_W: usize = 24;
pub const CURSOR_H: usize = 24;
fn unix_to_hms(timestamp: u64) -> (u64, u64, u64) {
let seconds = timestamp % 86400;
let h = seconds / 3600;
let m = (seconds % 3600) / 60;
let s = seconds % 60;
(h, m, s)
}
fn boot_animation() {
let mut i = 1;
while i < 10 {
let mut width = 0;
let mut height = 0;
with_framebuffer(|fb| {
fb.clear(rgb(77, 171, 245));
width = fb.width;
height = fb.height;
});
let text_width = ("XunilOS Loading".len() + ".".repeat(i).len()) * 4 * 2;
with_serial_console(|serial_console| {
serial_console.clear(width / 2 - text_width / 2, height / 2)
});
println!(
"{}",
"XunilOS Loading".to_string() + &".".repeat(i).as_str()
);
i += 1;
with_framebuffer(|fb| fb.swap());
sleep(200);
}
with_serial_console(|serial_console| {
serial_console.clear(0, 0);
});
with_framebuffer(|fb| {
fb.clear(rgb(77, 171, 245));
});
}
pub fn userspace_init(mapper: &mut OffsetPageTable) -> ! {
// this is just a stub
let (entry_point, heap_base) = load_file(mapper, TEST_ELF_BYTES);
println!("Entry point: {:?}", entry_point);
with_framebuffer(|fb| fb.swap());
run_elf(entry_point, heap_base);
loop {}
// boot_animation();
// let mut mouse_status = 0;
// let mut width = 0;
// let mut height = 0;
// let mut mouse_x = 100;
// let mut mouse_y = 100;
// let mut i = 0;
// loop {
// with_serial_console(|serial_console| serial_console.clear(0, 0));
// with_framebuffer(|fb| fb.clear(rgb(77, 171, 245)));
// // mouse_status = MOUSE.get_status();
// with_framebuffer(|mut fb| {
// width = fb.width;
// height = fb.height;
// let (x_delta, y_delta) = MOUSE.take_motion();
// if x_delta != 0 {
// mouse_x = (mouse_x as isize + x_delta as isize).max(0) as usize;
// }
// if y_delta != 0 {
// mouse_y = (mouse_y as isize + y_delta as isize).max(0) as usize;
// }
// if mouse_x > width {
// mouse_x = width - CURSOR_W;
// }
// if mouse_y > height {
// mouse_y = height - CURSOR_H;
// }
// rectangle_filled(&mut fb, 700, 400, 200, 200, rgb(0, 0, 0));
// rectangle_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
// circle_filled(&mut fb, 200, 200, 100, rgb(0, 0, 0));
// circle_outline(&mut fb, 400, 200, 100, rgb(0, 0, 0));
// triangle_outline(&mut fb, 100, 400, 200, 400, 150, 600, rgb(0, 0, 0));
// let pixels = &CURSOR_BYTES[BMP_HEADER_SIZE..]; // remove header
// for row in 0..CURSOR_H {
// let src_row = (CURSOR_H - 1 - row) * CURSOR_W * 4;
// for col in 0..CURSOR_W {
// let i = src_row + col * 4; // 4 because rgba
// let b = pixels[i];
// let g = pixels[i + 1];
// let r = pixels[i + 2];
// let a = pixels[i + 3];
// if a < 255 {
// continue;
// }
// let color = rgb(r, g, b);
// fb.put_pixel((mouse_x + col) as usize, (mouse_y + row) as usize, color);
// }
// }
// });
// let (hours, minutes, seconds) =
// unix_to_hms(TIMER.get_date_at_boot() + (TIMER.now().elapsed()) / 1000);
// print!(
// "{:?}:{:?}:{:?}\nMouse status: {:?}\nDesktop Size: {:?}",
// hours,
// minutes,
// seconds,
// mouse_status,
// (width, height)
// );
// with_framebuffer(|fb| {
// fb.swap();
// });
// sleep(1000 / 165);
// }
}