#freebsd #内核模块 #API绑定 #kpi

nightly no-std freebsd-kpi-r14-0

FreeBSD 14.0-RELEASE 内核编程接口

4个版本

0.2.0 2024年2月8日
0.1.3 2023年12月7日
0.1.2 2023年11月25日
0.1.0 2023年11月20日

#258 in 操作系统


freebsd-kmi-rs 中使用

自定义许可证

3.5MB
60K SLoC

FreeBSD 14.0-RELEASE Rust内核编程接口

该仓库仅包含对内核的绑定!

这是不安全的,只是一个绑定!

它尚未经过测试(因为现在正在执行结构对齐测试,请参阅内核编程接口测试

有关“安全”和rust兼容的实现,请参阅内核模块接口

内核模块接口 依赖于这个crate。


变量(特性自动配置)

为了构建针对FreeBSD内核的crate,以针对位于/usr/src/sys/<arch>/conf的conf文件(在/usr/src/sys中)自动配置特性

  • 禁用 default_features
  • 设置特性 BUILD_CONFIG_KERNEL
  • 设置环境变量 KPI_PLATFORM_CFG_PATH

例如

[dependencies]
freebsd-kpi-r14-0 = { path = "../rsandbox_kmod", defailt_features = false, features = ["BUILD_CONFIG_KERNEL"] }

[env]
KPI_PLATFORM_CFG_PATH = "/usr/src/sys/amd64/conf/GENERIC"

如果未设置KPI_PLATFORM_CFG_PATH,则将使用默认路径/usr/src/sys/amd64/conf/GENERICGENERIC

移植指南

请参阅Rustonomicon

私有函数

/// defined in <path to file with filename>:line number
#[repr(C)]
pub struct turnstile 
{
    _data: [u8; 0],
    _marker:
        core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}

外部函数和变量

extern "C"
{
    #[no_mangle]
    pub 
    fn vmem_create(name: *const c_char, base: vmem_addr_t, size: vmem_size_t, 
        quantum: vmem_size_t, qcache_max: vmem_size_t, flags: c_int) -> *mut vmem_t;

    #[no_mangle]
    #[link_name = "wdog_software_attach"]
    pub static mut wdog_software_attach: Option<unsafe extern "C" fn()>;
}

函数指针

一个函数指针如

void (*func)()

Option<unsafe extern "C" fn()>

函数

特殊属性

  • C __returns_twice,Rust #[ffi_returns_twice] 属性已被删除!所有使用它的函数都被注释掉了!
  • C likely, unlikly 也从代码中删除,因为它不是Rustc开发者的内部玩具
  • C __no_return,Rust !
  • C __weak_symbol,Rust #[linkage = "extern_weak"]

其他

  • volatile 参数或字段应该有注释 /// VOLATILE! 并使用 core::ptr::read_volatilecore::ptr::write_volatile 访问
  • C offsetof 对于Rust,有一个宏:offsetof.rs offset_of!()
  • C typeof 在Rust中没有替代方案。

样式

有关格式化和移植的一些指南。

不要使用 rustfmt!。

换行和格式化。

通常,行长度不应超过120个字符。但最多可以到160。

函数格式

// #[ATTRIBUTES] \n
// #[ATTRIBUTES] \n
// [FUNCTION MODIFIERS] \n
// [FUNCTION] [FUNCTION_NAME] [GENERICS][ARGUMENTS] [RETURN_DATA]\n
// [{]
//      [...]
// [}]
//
// where [ARGUMENTS] may be formatted as following:
// ([ARG], [ARG], [ARG])
// -- OR --
// (
//    [ARG],
//    [ARG]
// )
// -- OR --
// ([ARG], [ARG], [ARG],
//  [ARG], [ARG])

#[inline]
pub unsafe
fn function_name<B, C, D>(arg1: u64, arg2: u64, arg3: B, arg4: C, arg5: D) -> u64
where B: SomeTrait, C: SomeTrait, D: SomeTrait
{}

#[inline]
pub unsafe
fn function_name<B, C, D>(
    arg1: u64, 
    arg2: u64,
    arg3: B,
    arg4: C,
    arg5: D
) -> u64
where B: SomeTrait, C: SomeTrait, D: SomeTrait
{}

#[inline]
pub unsafe
fn function_name<B, C, D>(arg1: u64, arg2: u64, 
    arg3: B, arg4: C, arg5: D) -> u64
where   // optiinal \n 
    B: SomeTrait, C: SomeTrait, D: SomeTrait
{}

常量/类型格式

// [VISIBILITY] [CONST] [NAME][:] [DATATYPE] [=] [DATA]
// [VISIBILITY] [TYPE] [TYPE_NAME] = [TYPE]

pub const RW_VAL: u8 = 9;
const D_VAL: &[u8] = b"d_value\0";
const B_VAL: &[&[u8]] = & // \n if list if large, otherwise same line
[
    D_VAL,
    "blabla\0",
];

pub type uint32_t = u32;
pub type callback_fn = // \n if long difinition
    Option<
        unsafe extern "C"
        fn(my_var: u64) -> u64
    >;

pub type callback_fn = unsafe extern "C" fn(my_var: u64) -> u64;
pub type callback_fn = Option<unsafe extern "C" fn() -> u64>;

赋值

//...
let var: u64 = some_struct.read().unwrap();

let var2: Option<Arc<RefCell<MyStructLongName>>> = 
    some_s.get_instance().get_sourcer().read().unwrap();

let var3: Arc<RefCell<MyStructLongName>> =
    io_source.instance()
            .grab()
            .set_source()
            .set_name()
            .start();
//...

结构体

//[DERIVES/MODIFIERS]
//[VISIBILITY][struct][name] \n
//[{] \n
//\t    [field][:] [data][,]
//[}]\n

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct StructName
{
    field: u64,
    field1: Option<Arc<Mutex<MyData>>>,
}

匹配/如果

if var1 == 8
{

}
else
{

}

if var1 == 8 || var_with_long_name > 6 ||
    var_with_anothr_name > 100 ||
    var5 != 8
{

}
else if var2 < 6
{

}
else
{

}

match myvar
{
    3 => return 5,
    6 =>
    {
        something
    },
    9 => return 1,
    _ =>
}

match myvar.get_instance().foo()
    .bar().foobar()
{
    StateA0V1H3
        {
            field1: ...,
            field2: ...,
            field3: ...
        } =>
    {

    },
    StateA4N6(a,b,c,d,e) =>
    {

    },
    StateA5K3B6R3blabla =>
    {

    }
}

安全性

我正在尽力控制推送到这个存储库的内容。不允许其他人向这个存储库提交!这个crate主要包含结构体。但有时'.h'文件包含一些静态函数。这些函数中的代码必须与原始'.h'文件中的内容匹配!否则,任何更改都必须突出显示,并且更改的原因必须在注释部分中。此外,必须提及更改的作者!

请求

请求实现某些内容或修复某些内容,并尽快被拒绝。

只有当获得赞助时。

依赖项