diff options
Diffstat (limited to 'rust/kernel/lib.rs')
| -rw-r--r-- | rust/kernel/lib.rs | 78 | 
1 files changed, 78 insertions, 0 deletions
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs new file mode 100644 index 000000000000..abd46261d385 --- /dev/null +++ b/rust/kernel/lib.rs @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! The `kernel` crate. +//! +//! This crate contains the kernel APIs that have been ported or wrapped for +//! usage by Rust code in the kernel and is shared by all of them. +//! +//! In other words, all the rest of the Rust code in the kernel (e.g. kernel +//! modules written in Rust) depends on [`core`], [`alloc`] and this crate. +//! +//! If you need a kernel C API that is not ported or wrapped yet here, then +//! do so first instead of bypassing this crate. + +#![no_std] +#![feature(core_ffi_c)] + +// Ensure conditional compilation based on the kernel configuration works; +// otherwise we may silently break things like initcall handling. +#[cfg(not(CONFIG_RUST))] +compile_error!("Missing kernel configuration for conditional compilation"); + +#[cfg(not(test))] +#[cfg(not(testlib))] +mod allocator; +pub mod error; +pub mod prelude; +pub mod print; +pub mod str; + +#[doc(hidden)] +pub use bindings; +pub use macros; + +/// Prefix to appear before log messages printed from within the `kernel` crate. +const __LOG_PREFIX: &[u8] = b"rust_kernel\0"; + +/// The top level entrypoint to implementing a kernel module. +/// +/// For any teardown or cleanup operations, your type may implement [`Drop`]. +pub trait Module: Sized + Sync { +    /// Called at module initialization time. +    /// +    /// Use this method to perform whatever setup or registration your module +    /// should do. +    /// +    /// Equivalent to the `module_init` macro in the C API. +    fn init(module: &'static ThisModule) -> error::Result<Self>; +} + +/// Equivalent to `THIS_MODULE` in the C API. +/// +/// C header: `include/linux/export.h` +pub struct ThisModule(*mut bindings::module); + +// SAFETY: `THIS_MODULE` may be used from all threads within a module. +unsafe impl Sync for ThisModule {} + +impl ThisModule { +    /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer. +    /// +    /// # Safety +    /// +    /// The pointer must be equal to the right `THIS_MODULE`. +    pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule { +        ThisModule(ptr) +    } +} + +#[cfg(not(any(testlib, test)))] +#[panic_handler] +fn panic(info: &core::panic::PanicInfo<'_>) -> ! { +    pr_emerg!("{}\n", info); +    // SAFETY: FFI call. +    unsafe { bindings::BUG() }; +    // Bindgen currently does not recognize `__noreturn` so `BUG` returns `()` +    // instead of `!`. See <https://github.com/rust-lang/rust-bindgen/issues/2094>. +    loop {} +}  |