feat: DLL, console

This commit is contained in:
Gleb Zaharov 2024-01-30 15:56:39 +03:00
parent 1a6f5303cf
commit 264618fe3b
11 changed files with 132 additions and 6 deletions

View File

@ -8,7 +8,11 @@ edition = "2018"
[[example]]
name = "hwa"
path = "example/hwa.rs"
path = "examples/hwa.rs"
[[example]]
name = "con"
path = "examples/con.rs"
[profile.release]
opt-level = "z"

View File

@ -15,7 +15,7 @@ args = ["clean"]
command = "cargo"
args = ["build", "@@remove-empty(RELEASE_FLAG)"]
[tasks.hwa]
[tasks.example]
command = "cargo"
args = ["objcopy", "@@remove-empty(RELEASE_FLAG)", "--example", "hwa", "--", "-O", "binary", "--strip-all", "rust.kex"]
args = ["objcopy", "@@remove-empty(RELEASE_FLAG)", "--example", "${@}", "--", "-O", "binary", "--strip-all", "${@}.kex"]
#install_crate = { crate_name = "cargo-binutils", binary = "rust-objcopy", test_arg = ["--help"] }

20
examples/con.rs Normal file
View File

@ -0,0 +1,20 @@
#![no_std]
#![no_main]
use cstr_core::cstr;
use kos::{dll::Console, threads::exit};
extern crate alloc;
#[no_mangle]
pub fn kol_main() {
let header = cstr!("Rust!");
let string = "Hi from Rust!";
let con_lib = Console::import(None).unwrap();
con_lib.init(u32::MAX, u32::MAX, u32::MAX, u32::MAX, header);
con_lib.write_string(string);
con_lib.exit(false);
exit();
}

2
link.x
View File

@ -1,6 +1,6 @@
PATH_SIZE = 1024;
PARAMS_SIZE = 256;
STACK_SIZE = 1024*4;
STACK_SIZE = 1024*64;
SECTIONS {
hdr : {

46
src/dll.rs Normal file
View File

@ -0,0 +1,46 @@
use crate::sys;
use cstr_core::CStr;
mod console;
pub use console::Console;
pub struct DLL {
table: *const ImportTableEl,
}
impl DLL {
pub fn load_dll(name: &CStr) -> Result<DLL, &str> {
unsafe {
let table = sys::load_dll(name.as_ptr() as *const u8);
if table as usize == 0 {
return Err("Library load error");
}
return Ok(DLL {
table: table as *const ImportTableEl,
});
}
}
pub fn get_func(&self, name: &CStr) -> Result<*const (), &str> {
unsafe {
let mut i = 0;
loop {
let el = self.table.add(i);
if el as usize == 0 {
return Err("Function not found");
}
let cur_name = CStr::from_ptr((*el).func_name as *const i8);
if cur_name == name {
return Ok((*el).func_addr as *const ());
}
i += 1;
}
}
}
}
#[repr(C)] // Avoid random field order
struct ImportTableEl {
pub func_name: *const u8,
pub func_addr: fn(),
}

40
src/dll/console.rs Normal file
View File

@ -0,0 +1,40 @@
use crate::dll::DLL;
use core::mem::transmute;
use cstr_core::cstr;
use cstr_core::CStr;
pub struct Console {
con_init: extern "stdcall" fn(u32, u32, u32, u32, *const u8),
con_write_string: extern "stdcall" fn(*const u8, u32),
con_exit: extern "stdcall" fn(bool),
}
impl Console {
pub fn import(path: Option<&CStr>) -> Result<Self, &str> {
let lib = DLL::load_dll(path.unwrap_or(cstr!("/sys/lib/console.obj")));
match lib {
Err(e) => return Err(e),
Ok(dll) => unsafe {
Ok(Console {
con_init: transmute(dll.get_func(cstr!("con_init")).ok().unwrap()),
con_write_string: transmute(
dll.get_func(cstr!("con_write_string")).ok().unwrap(),
),
con_exit: transmute(dll.get_func(cstr!("con_exit")).ok().unwrap()),
})
},
}
}
pub fn init(&self, x: u32, y: u32, width: u32, height: u32, title: &CStr) {
(self.con_init)(x, y, width, height, title.as_ptr() as *const u8);
}
pub fn write_string(&self, text: &str) {
(self.con_write_string)(text.as_ptr(), text.len() as u32);
}
pub fn exit(self, close_window: bool) {
(self.con_exit)(close_window);
}
}

View File

@ -18,3 +18,4 @@ SF_SYS_MISC = 68
SSF_HEAP_INIT = 11
SSF_MEM_ALLOC = 12
SSF_MEM_FREE = 13
SSF_LOAD_DLL = 19

View File

@ -2,9 +2,11 @@
mod modules;
mod nanolibc;
pub mod sys;
pub mod allocation;
pub mod dll;
pub mod sys;
pub use modules::*;
#[macro_use]
@ -26,6 +28,8 @@ macro_rules! throw_new {
macro_rules! panic {
($text:expr) => {
debug_write(cstr_core::cstr!("Panic!\n" + $text + "\n"));
sys::exit();
unsafe {
sys::exit();
}
};
}

View File

@ -55,4 +55,8 @@ extern "C" {
// 68.13
#[link_name = "_free"]
pub fn free(block: *const u8) -> bool;
// 68.19
#[link_name = "_load_dll"]
pub fn load_dll(name: *const u8) -> *const u32;
}

View File

@ -17,6 +17,7 @@ section '.text'
public _alloc
public _free
public _get_lang
public _load_dll
_exit:
mov eax, SF_TERMINATE_PROCESS
@ -118,3 +119,9 @@ _get_lang:
int 0x40
ret
_load_dll:
mov eax, SF_SYS_MISC
mov ebx, SSF_LOAD_DLL
mov ecx, [esp + 4 * 1]
int 0x40
ret