库兼容

在介绍整体架构那个章节,我们大致看过了RUST在linux内核的库和普通程序有一些不同

本章我们讲尝试解析这些区别的由来

库的问题

无论如何,内核由于某种原因,可能需要对某些基础库进行修改, 但是这种修改,会引入上游兼容的问题:

  • 上游软件库的版本更新,本地怎么同步?
  • 在同步时可能有冲突
  • 本地版本的开发可能会和上游版本差异越来越大

内核对于上述问题给出了统一的解决建议:

  • 本地版本修改,应该尽快合入上游分支
  • 上游分支应该提供对于内核的兼容机制
  • 最终,内核不应该保留外部库的副本,应该采用上游库

从core开始

core crate是RUST中第一个最底层的包,core在RUST中,总是会被作为一个预导入包导入,参考预导入包

core crate 设计的初衷就是把一些可以跨平台的、最基础的类型抽象,单独作为一个crate,从而达到跨平台使用的目的

core兼容性

经过刚才的讨论,可以看到,core crate 从设计上讲,几乎不会存在兼容性问题,但是鉴于Linux内核的特殊性, 还存在 以下兼容性问题

  • core的库中提供了浮点数的计算(Linux内核中为了硬件兼容 一般不允许浮点计算)
  • i128/u128类型,在内核中也不应该使用

基于上述原因,rust 需要对core进行修改和兼容性适配,但是万幸, 我们可以看到,目前兼容问题只是disable掉部分功能,LINUX 采用了 一个比较hack的方案来解决

  • Linux不需要修改core的源码,因此不需要在内核维护一个core的版本分支
  • Linux需要重新编译core
  • Linux通过重定向core中内核不支持的函数为自己实现的函数,实现方法为Makefile:redirect-intrinsics
  • 重定向函数定义在: linux/rust/compiler_builtins.rs
  • 重定向函数默认行为都为panic

alloc

引用官方说明alloc

alloc 是 Rust 标准库的一部分,它的实现使用了许多不稳定的特性。通常情况下, 该库(以及 core 和其他库)由编译器提供,因此这些不稳定特性不会破坏用户的代码。

目前,内核包含一个 alloc 的分叉(与内核支持的 Rust 版本相匹配),并在上面添加了一些功能。 由于这些不稳定的特性,使用不同版本的编译器编译内核会变得复杂,但这个分叉只是暂时的: 与上游 Rust(及其他)讨论的 alloc 原始计划已在 rust/alloc/README.md 文件中记录。

目前正在与上游 Rust 公司进行讨论,以确定最终的分配解决方案。

总结: - 当前内核迫于无奈 维护了一个alloc分支代码,因为现在必须要修改代码 才可以兼容内核(无法像core一样简单) - 关于内核的兼容性修改,目前正在和RUST社区进行讨论 - 未来会把内核的alloc分支给移除,alloc可以通过简单的配置即可在内核使用

alloc兼容性

allock 关闭的功能:

alloc-cfgs = \               
      --cfg no_borrow \        
      --cfg no_fmt \           
      --cfg no_global_oom_handling \
      --cfg no_macros \
      --cfg no_rc \
      --cfg no_str \
      --cfg no_string \
      --cfg no_sync \
      --cfg no_thin