Skip to content

Commit 8f1fc28

Browse files
committed
modules: fix mod loader and add rust module
1 parent a9b2a38 commit 8f1fc28

14 files changed

Lines changed: 300 additions & 13 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ add_custom_command(OUTPUT ${install_stamp_file}
135135
COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --prefix ${sysroot_dir} --component initrd
136136
COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --prefix ${iso_dir} --component iso
137137
COMMAND ${CMAKE_COMMAND} -E touch ${install_stamp_file}
138-
DEPENDS nightingale_kernel kernel_modules c elf sh ${userland_programs} generate_headers
138+
DEPENDS nightingale_kernel kernel_modules rust_kernel_modules c elf sh ${userland_programs} generate_headers
139139
COMMENT "Installing initrd to sysroot and ISO files to ISO directory"
140140
)
141141
add_custom_target(install_to_sysroot DEPENDS ${install_stamp_file})

include/elf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ typedef struct {
102102
#define SHT_SHLIB 10
103103
#define SHT_DYNSYM 11
104104

105+
#define SHF_WRITE 0x1
106+
#define SHF_ALLOC 0x2
107+
#define SHF_EXECINSTR 0x4
108+
105109
typedef struct {
106110
Elf64_Word st_name;
107111
unsigned char st_info;

kernel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_subdirectory(modules)
2+
add_subdirectory(rust)
23

34
add_executable(nightingale_kernel
45
../libc/ctype.c

kernel/include/ng/vmm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ enum fault_result {
1616
#endif
1717

1818
void *vmm_reserve(size_t);
19+
void *vmm_hold(size_t);
1920

2021
END_DECLS

kernel/rust/CMakeLists.txt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Find Rust toolchain
2+
find_program(CARGO_COMMAND cargo REQUIRED)
3+
find_program(RUSTC_COMMAND rustc REQUIRED)
4+
5+
# Rust target specification - use built-in x86_64-unknown-none
6+
set(RUST_TARGET "x86_64-unknown-none")
7+
set(RUST_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/target")
8+
9+
# Rust flags to match kernel compilation requirements
10+
set(RUST_FLAGS "-C code-model=kernel -C relocation-model=static")
11+
12+
# Build profile selection based on CMAKE_BUILD_TYPE
13+
if(CMAKE_BUILD_TYPE STREQUAL "Release")
14+
set(RUST_BUILD_PROFILE "release")
15+
set(RUST_PROFILE_FLAG "--release")
16+
else()
17+
set(RUST_BUILD_PROFILE "debug")
18+
set(RUST_PROFILE_FLAG "")
19+
endif()
20+
21+
# List of Rust modules to build
22+
list(APPEND rust_modules_list
23+
hello_rust_mod
24+
)
25+
26+
foreach(rust_module ${rust_modules_list})
27+
set(module_dir "${CMAKE_CURRENT_SOURCE_DIR}/${rust_module}")
28+
set(module_lib "${RUST_TARGET_DIR}/${RUST_TARGET}/${RUST_BUILD_PROFILE}/lib${rust_module}.a")
29+
set(module_ko "${CMAKE_CURRENT_BINARY_DIR}/${rust_module}.ko")
30+
set(temp_dir "${CMAKE_CURRENT_BINARY_DIR}/temp_${rust_module}")
31+
32+
# Build Rust static library with cargo
33+
add_custom_command(
34+
OUTPUT ${module_lib}
35+
COMMAND ${CMAKE_COMMAND} -E env RUSTFLAGS=${RUST_FLAGS}
36+
${CARGO_COMMAND} build
37+
--target ${RUST_TARGET}
38+
--target-dir ${RUST_TARGET_DIR}
39+
${RUST_PROFILE_FLAG}
40+
--manifest-path ${module_dir}/Cargo.toml
41+
DEPENDS
42+
${module_dir}/Cargo.toml
43+
${module_dir}/src/lib.rs
44+
WORKING_DIRECTORY ${module_dir}
45+
COMMENT "Building Rust module: ${rust_module}"
46+
VERBATIM
47+
)
48+
49+
# Convert static library to relocatable object (.ko)
50+
# Extract object files from the archive and combine them
51+
add_custom_command(
52+
OUTPUT ${module_ko}
53+
COMMAND ${CMAKE_COMMAND} -E make_directory ${temp_dir}
54+
COMMAND cd ${temp_dir} && ar x ${module_lib}
55+
COMMAND sh -c "ld.lld -r -o ${module_ko} ${temp_dir}/*.o"
56+
COMMAND ${CMAKE_COMMAND} -E rm -rf ${temp_dir}
57+
DEPENDS ${module_lib}
58+
COMMENT "Creating kernel module: ${rust_module}.ko"
59+
)
60+
61+
add_custom_target(${rust_module}_rust_ko ALL DEPENDS ${module_ko})
62+
list(APPEND rust_module_ko_files ${module_ko})
63+
64+
# Install .ko file to lib directory (same as C modules)
65+
install(FILES ${module_ko} DESTINATION lib COMPONENT initrd)
66+
endforeach()
67+
68+
add_custom_target(rust_kernel_modules DEPENDS ${rust_module_ko_files})

kernel/rust/Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kernel/rust/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[workspace]
2+
members = ["common", "hello_rust_mod"]
3+
resolver = "2"
4+
5+
[profile.dev]
6+
panic = "abort"
7+
opt-level = 0
8+
9+
[profile.release]
10+
panic = "abort"
11+
opt-level = 3
12+
lto = true

kernel/rust/common/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "nightingale_kernel"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
path = "src/lib.rs"
8+
9+
[dependencies]
10+
11+
[profile.dev]
12+
panic = "abort"
13+
14+
[profile.release]
15+
panic = "abort"

kernel/rust/common/src/lib.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#![no_std]
2+
3+
pub use core::panic::PanicInfo;
4+
5+
#[repr(C)]
6+
pub struct ModInfo {
7+
pub name: *const u8,
8+
pub init: Option<extern "C" fn(*const Mod) -> i32>,
9+
pub fini: Option<extern "C" fn(*const Mod)>,
10+
}
11+
12+
// SAFETY: ModInfo contains raw pointers that point to static data,
13+
// which is safe to share between threads in a kernel context
14+
unsafe impl Sync for ModInfo {}
15+
16+
#[repr(C)]
17+
pub struct Mod {
18+
_private: [u8; 0],
19+
}
20+
21+
pub const MODINIT_SUCCESS: i32 = 0;
22+
pub const MODINIT_FAILURE: i32 = 1;
23+
24+
pub mod ffi {
25+
extern "C" {
26+
pub fn printf(fmt: *const u8, ...) -> i32;
27+
}
28+
}
29+
30+
#[cfg(not(test))]
31+
#[panic_handler]
32+
pub fn panic(_info: &PanicInfo) -> ! {
33+
// TODO: call the existing C panic function
34+
loop {}
35+
}
36+
37+
/// Helper macro to create a null-terminated byte string literal
38+
///
39+
/// # Example
40+
/// ```ignore
41+
/// use nightingale_kernel::cstr;
42+
/// let s = cstr!("Hello, world!");
43+
/// ```
44+
#[macro_export]
45+
macro_rules! cstr {
46+
($s:expr) => {
47+
concat!($s, "\0").as_ptr() as *const u8
48+
};
49+
}
50+
51+
/// Helper macro to define a kernel module with proper exports
52+
///
53+
/// # Example
54+
/// ```ignore
55+
/// use nightingale_kernel::*;
56+
///
57+
/// fn my_init(_mod: *const Mod) -> i32 {
58+
/// unsafe {
59+
/// ffi::printf(cstr!("Module loaded!\n"));
60+
/// }
61+
/// MODINIT_SUCCESS
62+
/// }
63+
///
64+
/// kernel_module! {
65+
/// name: "my_module",
66+
/// init: my_init,
67+
/// }
68+
/// ```
69+
#[macro_export]
70+
macro_rules! kernel_module {
71+
(name: $name:expr, init: $init:expr $(, fini: $fini:expr)? $(,)?) => {
72+
#[no_mangle]
73+
pub extern "C" fn modinit(mod_ptr: *const $crate::Mod) -> i32 {
74+
$init(mod_ptr)
75+
}
76+
77+
$(
78+
#[no_mangle]
79+
pub extern "C" fn modfini(mod_ptr: *const $crate::Mod) {
80+
$fini(mod_ptr)
81+
}
82+
)?
83+
84+
#[used]
85+
#[no_mangle]
86+
#[link_section = ".data"]
87+
static modinfo: $crate::ModInfo = $crate::ModInfo {
88+
name: $crate::cstr!($name),
89+
init: Some(modinit),
90+
fini: kernel_module!(@fini $($fini)?),
91+
};
92+
};
93+
(@fini) => { None };
94+
(@fini $fini:expr) => { Some(modfini) };
95+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "hello_rust_mod"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["staticlib"]
8+
path = "src/lib.rs"
9+
10+
[dependencies]
11+
nightingale_kernel = { path = "../common" }
12+
13+
[profile.dev]
14+
panic = "abort"
15+
16+
[profile.release]
17+
panic = "abort"

0 commit comments

Comments
 (0)