feat: DLL, console
This commit is contained in:
parent
1a6f5303cf
commit
264618fe3b
@ -8,7 +8,11 @@ edition = "2018"
|
|||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "hwa"
|
name = "hwa"
|
||||||
path = "example/hwa.rs"
|
path = "examples/hwa.rs"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "con"
|
||||||
|
path = "examples/con.rs"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
|
@ -15,7 +15,7 @@ args = ["clean"]
|
|||||||
command = "cargo"
|
command = "cargo"
|
||||||
args = ["build", "@@remove-empty(RELEASE_FLAG)"]
|
args = ["build", "@@remove-empty(RELEASE_FLAG)"]
|
||||||
|
|
||||||
[tasks.hwa]
|
[tasks.example]
|
||||||
command = "cargo"
|
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"] }
|
#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;
|
PATH_SIZE = 1024;
|
||||||
PARAMS_SIZE = 256;
|
PARAMS_SIZE = 256;
|
||||||
STACK_SIZE = 1024*4;
|
STACK_SIZE = 1024*64;
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
hdr : {
|
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_HEAP_INIT = 11
|
||||||
SSF_MEM_ALLOC = 12
|
SSF_MEM_ALLOC = 12
|
||||||
SSF_MEM_FREE = 13
|
SSF_MEM_FREE = 13
|
||||||
|
SSF_LOAD_DLL = 19
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
mod modules;
|
mod modules;
|
||||||
mod nanolibc;
|
mod nanolibc;
|
||||||
pub mod sys;
|
|
||||||
|
|
||||||
pub mod allocation;
|
pub mod allocation;
|
||||||
|
pub mod dll;
|
||||||
|
pub mod sys;
|
||||||
|
|
||||||
pub use modules::*;
|
pub use modules::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -26,6 +28,8 @@ macro_rules! throw_new {
|
|||||||
macro_rules! panic {
|
macro_rules! panic {
|
||||||
($text:expr) => {
|
($text:expr) => {
|
||||||
debug_write(cstr_core::cstr!("Panic!\n" + $text + "\n"));
|
debug_write(cstr_core::cstr!("Panic!\n" + $text + "\n"));
|
||||||
|
unsafe {
|
||||||
sys::exit();
|
sys::exit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -55,4 +55,8 @@ extern "C" {
|
|||||||
// 68.13
|
// 68.13
|
||||||
#[link_name = "_free"]
|
#[link_name = "_free"]
|
||||||
pub fn free(block: *const u8) -> bool;
|
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 _alloc
|
||||||
public _free
|
public _free
|
||||||
public _get_lang
|
public _get_lang
|
||||||
|
public _load_dll
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
mov eax, SF_TERMINATE_PROCESS
|
mov eax, SF_TERMINATE_PROCESS
|
||||||
@ -118,3 +119,9 @@ _get_lang:
|
|||||||
int 0x40
|
int 0x40
|
||||||
ret
|
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