This repository was archived by the owner on Mar 7, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 121
/
Copy pathlib.rs
140 lines (125 loc) · 4.39 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#![no_std]
#![feature(allocator_api, alloc_error_handler, const_fn, const_raw_ptr_deref)]
extern crate alloc;
use core::panic::PanicInfo;
mod allocator;
pub mod bindings;
pub mod c_types;
pub mod chrdev;
mod error;
pub mod file_operations;
pub mod filesystem;
pub mod printk;
#[cfg(kernel_4_13_0_or_greater)]
pub mod random;
pub mod rcu;
pub mod sched;
pub mod sysctl;
mod types;
pub mod user_ptr;
pub use crate::error::{Error, KernelResult};
pub use crate::types::{CStr, Mode};
/// Declares the entrypoint for a kernel module. The first argument should be a type which
/// implements the [`KernelModule`] trait. Also accepts various forms of kernel metadata.
///
/// Example:
/// ```rust,no_run
/// use linux_kernel_module;
/// struct MyKernelModule;
/// impl linux_kernel_module::KernelModule for MyKernelModule {
/// fn init() -> linux_kernel_module::KernelResult<Self> {
/// Ok(MyKernelModule)
/// }
/// }
///
/// linux_kernel_module::kernel_module!(
/// MyKernelModule,
/// author: b"Fish in a Barrel Contributors",
/// description: b"My very own kernel module!",
/// license: b"GPL"
/// );
#[macro_export]
macro_rules! kernel_module {
($module:ty, $($name:ident : $value:expr),*) => {
static mut __MOD: Option<$module> = None;
#[no_mangle]
pub extern "C" fn init_module() -> $crate::c_types::c_int {
match <$module as $crate::KernelModule>::init() {
Ok(m) => {
unsafe {
__MOD = Some(m);
}
return 0;
}
Err(e) => {
return e.to_kernel_errno();
}
}
}
#[no_mangle]
pub extern "C" fn cleanup_module() {
unsafe {
// Invokes drop() on __MOD, which should be used for cleanup.
__MOD = None;
}
}
$(
$crate::kernel_module!(@attribute $name, $value);
)*
};
// TODO: The modinfo attributes below depend on the compiler placing
// the variables in order in the .modinfo section, so that you end up
// with b"key=value\0" in order in the section. This is a reasonably
// standard trick in C, but I'm not sure that rustc guarantees it.
//
// Ideally we'd be able to use concat_bytes! + stringify_bytes! +
// some way of turning a string literal (or at least a string
// literal token) into a bytes literal, and get a single static
// [u8; * N] with the whole thing, but those don't really exist yet.
// Most of the alternatives (e.g. .as_bytes() as a const fn) give
// you a pointer, not an array, which isn't right.
(@attribute author, $value:expr) => {
#[link_section = ".modinfo"]
pub static AUTHOR_KEY: [u8; 7] = *b"author=";
#[link_section = ".modinfo"]
pub static AUTHOR_VALUE: [u8; $value.len()] = *$value;
#[link_section = ".modinfo"]
pub static AUTHOR_NUL: [u8; 1] = *b"\0";
};
(@attribute description, $value:expr) => {
#[link_section = ".modinfo"]
pub static DESCRIPTION_KEY: [u8; 12] = *b"description=";
#[link_section = ".modinfo"]
pub static DESCRIPTION_VALUE: [u8; $value.len()] = *$value;
#[link_section = ".modinfo"]
pub static DESCRIPTION_NUL: [u8; 1] = *b"\0";
};
(@attribute license, $value:expr) => {
#[link_section = ".modinfo"]
pub static LICENSE_KEY: [u8; 8] = *b"license=";
#[link_section = ".modinfo"]
pub static LICENSE_VALUE: [u8; $value.len()] = *$value;
#[link_section = ".modinfo"]
pub static LICENSE_NUL: [u8; 1] = *b"\0";
};
}
/// KernelModule is the top level entrypoint to implementing a kernel module. Your kernel module
/// should implement the `init` method on it, which maps to the `module_init` macro in Linux C API.
/// You can use this method to do whatever setup or registration your module should do. For any
/// teardown or cleanup operations, your type may implement [`Drop`].
///
/// [`Drop`]: https://doc.rust-lang.org/stable/core/ops/trait.Drop.html
pub trait KernelModule: Sized + Sync {
fn init() -> KernelResult<Self>;
}
extern "C" {
fn bug_helper() -> !;
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
unsafe {
bug_helper();
}
}
#[global_allocator]
static ALLOCATOR: allocator::KernelAllocator = allocator::KernelAllocator;