feat: DLL, console
This commit is contained in:
parent
1a6f5303cf
commit
264618fe3b
@ -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"
|
||||
|
@ -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
20
examples/con.rs
Normal 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
2
link.x
@ -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
46
src/dll.rs
Normal 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
40
src/dll/console.rs
Normal 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);
|
||||
}
|
||||
}
|
@ -18,3 +18,4 @@ SF_SYS_MISC = 68
|
||||
SSF_HEAP_INIT = 11
|
||||
SSF_MEM_ALLOC = 12
|
||||
SSF_MEM_FREE = 13
|
||||
SSF_LOAD_DLL = 19
|
||||
|
@ -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"));
|
||||
unsafe {
|
||||
sys::exit();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user