Skip to content

Commit cdd29f9

Browse files
committed
commands WIP
1 parent 7dc1560 commit cdd29f9

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/grub_lib.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,56 @@
1+
#![feature(extern_types)]
2+
13
extern crate alloc;
24

5+
use alloc::vec::Vec;
6+
use alloc::vec;
7+
use alloc::string::String;
38
use core::alloc::{GlobalAlloc, Layout};
49
use core::ffi::c_char;
10+
use core::ffi::c_int;
11+
use core::ffi::c_void;
512

613
use alloc::ffi::CString;
14+
use core::ffi::CStr;
715
use core::panic::PanicInfo;
816

917
extern "C" {
1018
static grub_xputs: extern "C" fn(stri: *const c_char);
1119
pub fn grub_abort();
1220
pub fn grub_malloc(sz: usize) -> *mut u8;
1321
pub fn grub_free(ptr: *mut u8);
22+
pub fn grub_register_command_prio (name: *const c_char,
23+
func: fn (cmd: *const GrubCommand,
24+
argc: c_int, argv: *const *const c_char) ->err_t,
25+
summary: *const c_char,
26+
description: *const c_char,
27+
prio: c_int) -> *mut GrubCommand;
28+
pub fn grub_strlen (s: *const c_char) -> usize;
29+
pub fn grub_unregister_command (cmd: *const GrubCommand);
30+
}
31+
32+
#[no_mangle]
33+
pub extern "C" fn strlen(s: *const c_char) -> usize {
34+
return unsafe { grub_strlen(s) };
35+
}
36+
37+
38+
// TODO: Use code generation?
39+
#[repr(C)]
40+
pub struct GrubCommand {
41+
next: *mut GrubCommand,
42+
prev: *mut *mut GrubCommand,
43+
name: *const c_char,
44+
prio: c_int,
45+
func: *const c_void,
46+
flags: u32,
47+
summary: *const c_char,
48+
description: *const c_char,
49+
data: *const c_void,
1450
}
1551

52+
pub type GrubCommandPtr = *const GrubCommand;
53+
pub type err_t = u32;
1654

1755
struct GrubAllocator;
1856

@@ -44,3 +82,30 @@ fn panic(info: &PanicInfo) -> ! {
4482
}
4583
loop{}
4684
}
85+
86+
fn cmd_callback (cmd: *const GrubCommand,
87+
argc: c_int, argv: *const *const c_char) -> err_t {
88+
let mut argv_vec: Vec<&str> = vec![];
89+
for i in 0..argc {
90+
argv_vec.push(unsafe { CStr::from_ptr(*argv.add(i as usize)) }.to_str().unwrap());
91+
}
92+
93+
return unsafe{(*((*cmd).data as *const fn (argc: usize, argv: &[&str]) -> err_t))} (argc as usize, &argv_vec);
94+
}
95+
96+
pub fn register_command (name: &str, cb: fn (argc: usize, argv: &[&str]) -> err_t,
97+
summary: &str, description: &str) -> GrubCommandPtr {
98+
unsafe {
99+
let cmd = grub_register_command_prio (CString::new(name).unwrap().as_ptr(),
100+
cmd_callback,
101+
CString::new(summary).unwrap().as_ptr(),
102+
CString::new(description).unwrap().as_ptr(),
103+
0);
104+
(*cmd).data = cb as *mut c_void;
105+
return cmd;
106+
}
107+
}
108+
109+
pub fn unregister_command (cmd: GrubCommandPtr) {
110+
unsafe { grub_unregister_command(cmd); }
111+
}

src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![no_std]
22
#![no_main]
3+
#![feature(extern_types)]
34

45
mod grub_lib;
56

@@ -11,7 +12,25 @@ pub static GRUB_MODNAME: [u8; 11] = [b'r', b'u', b's', b't', b'_', b'h', b'e',
1112
#[no_mangle]
1213
pub static GRUB_LICENSE: [u8; 15] = [b'L', b'I', b'C', b'E', b'N', b'S', b'E', b'=', b'G', b'P', b'L', b'v', b'3', b'+', b'\0'];
1314

15+
static mut cmd: grub_lib::GrubCommandPtr = core::ptr::null();
16+
17+
fn rust_hello (_argc: usize, _argv: &[&str]) -> grub_lib::err_t {
18+
grub_lib::xputs("Hello, world\n");
19+
return 0;
20+
}
21+
1422
#[no_mangle]
1523
pub extern "C" fn grub_mod_init() {
1624
grub_lib::xputs("Hello");
25+
unsafe {
26+
cmd = grub_lib::register_command ("rust_hello", rust_hello,
27+
"Rust hello", "Say hello from Rust.");
28+
}
29+
}
30+
31+
#[no_mangle]
32+
pub extern "C" fn grub_mod_fini() {
33+
unsafe {
34+
grub_lib::unregister_command (cmd);
35+
}
1736
}

0 commit comments

Comments
 (0)