mirror of
https://github.com/XunilGroup/XunilOS.git
synced 2026-04-25 11:49:03 +02:00
Make Doom run by improving and fixing libc stubs, adding proper heap
allocation, adding a timer, a framebuffer swap, rectangle and buffer draw syscall, moving the header files to the correct directory, disabling stack protection, AVX and MMX, while enabling SSE, fix interrupt handler popping in the wrong order, improve load_segment_to_memory alignment, add load_from_ptr to framebuffer for very quick drawing, serial_print as well as render font in consolewriter, zero the memory in sbrk, add a fake file system and methods to libxunil for DOOM, add correct printf, vsnprintf add _start which calls the main function in libxunil, mark all registers as used inside syscalls for no memory corruption, add build_helloworld.sh script
This commit is contained in:
@@ -1,17 +1,23 @@
|
||||
use core::ptr::null_mut;
|
||||
use core::{mem, ptr::null_mut, usize};
|
||||
|
||||
use crate::{
|
||||
heap::ALLOCATOR,
|
||||
heap::{ALLOCATOR, LinkedNode},
|
||||
syscall::{BRK, syscall1},
|
||||
util::align_up,
|
||||
};
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn sbrk(increment: i64) -> i64 {
|
||||
unsafe { syscall1(BRK, increment as usize) as i64 }
|
||||
pub fn sbrk(increment: i64) -> isize {
|
||||
unsafe { syscall1(BRK, increment as isize) as isize }
|
||||
}
|
||||
|
||||
const MAX_SIZE: u64 = 18446744073709551615;
|
||||
|
||||
#[repr(C, align(16))]
|
||||
struct Header {
|
||||
size: usize,
|
||||
_pad: usize,
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn calloc(count: u64, size: u64) -> *mut u8 {
|
||||
if count != 0 && size > MAX_SIZE / count {
|
||||
@@ -19,19 +25,16 @@ pub extern "C" fn calloc(count: u64, size: u64) -> *mut u8 {
|
||||
}
|
||||
|
||||
let mut total = count * size;
|
||||
|
||||
if total == 0 {
|
||||
total = 1;
|
||||
}
|
||||
|
||||
let ptr = malloc(total);
|
||||
|
||||
if ptr.is_null() {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
memset(ptr, 0, total as usize);
|
||||
|
||||
ptr
|
||||
}
|
||||
|
||||
@@ -40,78 +43,126 @@ pub extern "C" fn free(ptr: *mut u8) {
|
||||
if ptr.is_null() {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
let size = *(((ptr as usize) - core::mem::size_of::<usize>()) as *const usize);
|
||||
|
||||
unsafe {
|
||||
let header_ptr = (ptr as usize - mem::size_of::<Header>()) as *mut Header;
|
||||
let total = (*header_ptr).size;
|
||||
let mut allocator = ALLOCATOR.lock();
|
||||
allocator
|
||||
.add_free_memory_region(ptr as usize - core::mem::size_of::<usize>(), size as usize);
|
||||
allocator.add_free_memory_region(header_ptr as usize, total);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn malloc(size: u64) -> *mut u8 {
|
||||
let req = size as usize;
|
||||
let req = if req == 0 { 1 } else { req };
|
||||
|
||||
let hdr = mem::size_of::<Header>();
|
||||
let needed_unaligned = match hdr.checked_add(req) {
|
||||
Some(v) => v,
|
||||
None => return null_mut(),
|
||||
};
|
||||
let align_req = 16;
|
||||
let needed = align_up(needed_unaligned, align_req);
|
||||
|
||||
let mut allocator = ALLOCATOR.lock();
|
||||
|
||||
if let Some(region) = allocator.find_region(size as usize, 16) {
|
||||
return region.1 as *mut u8;
|
||||
} else {
|
||||
let start_addr: i64 = sbrk(size as i64);
|
||||
if start_addr == -1 {
|
||||
return null_mut();
|
||||
if let Some(region) = allocator.find_region(needed) {
|
||||
unsafe {
|
||||
let header_ptr = region.start as *mut Header;
|
||||
header_ptr.write(Header {
|
||||
size: region.end - region.start,
|
||||
_pad: 0,
|
||||
});
|
||||
return (region.start + hdr) as *mut u8;
|
||||
}
|
||||
|
||||
unsafe { allocator.add_free_memory_region(start_addr as usize, size as usize) };
|
||||
drop(allocator);
|
||||
malloc(size)
|
||||
}
|
||||
|
||||
let min_region = mem::size_of::<LinkedNode>();
|
||||
let req_region = core::cmp::max(needed, min_region);
|
||||
|
||||
let align = align_req;
|
||||
let over = match req_region.checked_add(align) {
|
||||
Some(v) => v,
|
||||
None => return null_mut(),
|
||||
};
|
||||
if over > i64::MAX as usize {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
let raw_start = sbrk(over as i64);
|
||||
if raw_start == -1 {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
let raw_start = raw_start as usize;
|
||||
let aligned_start = align_up(raw_start, align);
|
||||
let usable = over - (aligned_start - raw_start);
|
||||
|
||||
if usable < min_region {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
allocator.add_free_memory_region(aligned_start, usable);
|
||||
}
|
||||
|
||||
drop(allocator);
|
||||
malloc(size)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn memcpy(dest_str: *mut u8, src_str: *const u8, n: usize) -> *mut u8 {
|
||||
unsafe { core::ptr::copy(src_str, dest_str, n) };
|
||||
|
||||
dest_str
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn memset(str: *mut u8, c: i64, n: usize) -> *mut u8 {
|
||||
unsafe {
|
||||
core::ptr::write_bytes(str, c as u8, n);
|
||||
pub extern "C" fn memset(dst: *mut u8, c: i64, n: usize) -> *mut u8 {
|
||||
if dst.is_null() || n == 0 {
|
||||
return dst;
|
||||
}
|
||||
|
||||
str
|
||||
unsafe {
|
||||
let val = c as u8;
|
||||
let mut i = 0usize;
|
||||
while i < n {
|
||||
*dst.add(i) = val;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
dst
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 {
|
||||
if size == 0 {
|
||||
free(ptr);
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
if ptr.is_null() {
|
||||
return malloc(size as u64);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
if size == 0 {
|
||||
free(ptr);
|
||||
let hdr = mem::size_of::<Header>();
|
||||
let header_ptr = (ptr as usize - hdr) as *mut Header;
|
||||
let total = (*header_ptr).size;
|
||||
let old_payload = total.saturating_sub(hdr);
|
||||
|
||||
if size <= old_payload {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let new_ptr = malloc(size as u64);
|
||||
if new_ptr.is_null() {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
let header = ((ptr as usize) - core::mem::size_of::<usize>()) as *mut usize;
|
||||
let old_size = *header;
|
||||
|
||||
if old_size == size {
|
||||
return ptr;
|
||||
} else if size < old_size {
|
||||
let mut allocator = ALLOCATOR.lock();
|
||||
let difference = old_size.abs_diff(size);
|
||||
let start = (ptr as usize) + size;
|
||||
*header = size;
|
||||
allocator.add_free_memory_region(start as usize, difference as usize);
|
||||
return ptr;
|
||||
} else {
|
||||
let new_ptr = malloc(size as u64);
|
||||
if new_ptr.is_null() {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
core::ptr::copy_nonoverlapping(ptr, new_ptr, old_size);
|
||||
free(ptr);
|
||||
return new_ptr;
|
||||
}
|
||||
core::ptr::copy_nonoverlapping(ptr, new_ptr, old_payload);
|
||||
free(ptr);
|
||||
new_ptr
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user