当前位置: 首页 > news >正文

TockOS,一种新安全软件架构的RTOS介绍

在这里插入图片描述

文章目录

    • 1. TockOS介绍
      • 详细总结
    • 2. TockOS开源项目的目录结构
    • 3. 胶囊(Capsules)
      • 胶囊的本质
      • 胶囊的特点
      • 胶囊的应用场景
    • 4. 胶囊的实现
      • 模块化设计
      • 安全隔离
      • 事件驱动
      • 可复用性

1. TockOS介绍

Tock 是一款面向 Cortex-M 和 RISC-V 微控制器的安全嵌入式操作系统,依赖硬件内存保护单元(MPU)保障安全。其内核与扩展(胶囊)用 Rust 编写,能运行多种语言的多个独立不可信进程,进程数量受微控制器闪存和内存限制,默认采用抢占式循环调度算法。Tock 采用微内核架构,内核提供 command、subscribe、allow、yield 四个主要系统调用,通过 MPU 保护自身和其他进程免受恶意进程代码侵害,同时借助 Rust 的类型安全特性确保内核和胶囊代码的安全性。
在这里插入图片描述

在这里插入图片描述

详细总结

  1. Tock概述:Tock是用于Cortex-M和RISC-V微控制器的安全嵌入式操作系统,要求硬件配备内存保护单元(MPU),内核和胶囊使用Rust编写。
  2. 进程相关
    • 编写语言与数量限制:支持用任意语言编写多个独立的不可信进程,进程数量受微控制器闪存和随机存取存储器(RAM)的限制。
    • 调度算法:默认采用抢占式循环调度算法,也可配置使用其他调度算法。
  3. 系统架构
    • 代码分类:代码分为核心内核、胶囊和进程三类。核心内核因需操作特定内存地址外设等功能,可使用“unsafe” Rust代码;胶囊不能使用unsafe特性,以保证代码安全。进程可由任意语言编写。
    • 系统调用:内核提供四个主要系统调用,具体如下:
系统调用功能特点参数
command进程向内核发起调用非阻塞,长时间操作会立即返回并在完成时发出回调驱动ID
subscribe在进程中注册用于接收内核上调用的回调非阻塞驱动ID
allow允许内核访问进程内存非阻塞驱动ID
yield暂停进程直到回调被调用阻塞
  1. 安全机制:借助硬件MPU,若进程试图访问非法内存,会触发异常,内核捕获异常并终止该进程,以此保护内核和其他进程。同时,Rust的类型安全特性防止内存错误使用,保障内核和胶囊代码安全。

2. TockOS开源项目的目录结构

TockOS的开源项目的目录结构如下图:

Hardware
Board_Support
Chip_Support
Architecture_Support
Capsules
Kernel_Space
User_Space
Legend
Physical Hardware
Board Implementations
Common Board Code
nRF52
STM32
SAM4L
Cortex-M Support
RISC-V Support
MPU Implementation
Core Capsules
Extra Capsules
System Capsules
Kernel Core
Scheduler
Process Management
System Call Interface
Hardware Abstraction Layer
User Applications
User Space
Kernel Space
Hardware Interface
Driver Layer

3. 胶囊(Capsules)

Tock 是一个为物联网(IoT)设备设计的开源、多任务、安全的嵌入式操作系统。在 Tock OS 里,“胶囊(Capsules)”是其核心抽象概念之一,下面为你介绍其本质。

胶囊的本质

胶囊本质上是一种模块化的软件组件,是Tock OS用于实现设备驱动和系统服务的关键机制。它以面向对象的方式来封装设备的功能和状态,能把不同的硬件设备和系统服务进行抽象,从而让它们能在 Tock 内核中以独立、安全且可复用的形式存在。

胶囊的特点

  1. 模块化设计:胶囊具备模块化特性,每个胶囊都负责特定的功能,像传感器驱动、通信协议栈或者文件系统服务等。如此一来,开发者可以按需添加或者移除胶囊,以此实现系统功能的定制。
  2. 安全隔离:Tock OS 借助内存保护和能力机制保证各个胶囊间的安全隔离。每个胶囊只能访问其被授权的资源,这样就能防止恶意或者有缺陷的胶囊对系统其他部分造成影响。
  3. 事件驱动:胶囊采用事件驱动的编程模型。胶囊会对来自硬件或者其他胶囊的事件做出响应,然后执行相应的操作。这种模型有助于降低系统的复杂性,提高系统的响应能力。
  4. 可复用性:胶囊是可复用的软件组件。开发者可以在不同的项目中复用已有的胶囊,或者基于现有的胶囊开发新的功能。

胶囊的应用场景

  • 设备驱动:为各类硬件设备(如传感器、执行器等)实现驱动程序。
  • 系统服务:实现诸如网络协议栈、文件系统、电源管理等系统服务。
  • 应用程序支持:为应用程序提供必要的接口和服务,确保应用程序能够安全、高效地运行。

4. 胶囊的实现

以下将结合 Tock OS 源代码来解释胶囊的实现,聊聊胶囊的各个特点以及对应的源代码。在 Tock OS 里,胶囊通常是 Rust 语言编写的结构体和相关的特征(trait)实现。

模块化设计

模块化设计体现为每个胶囊负责特定功能,且独立于其他胶囊。以 virtual_alarm 胶囊为例,它实现了一个虚拟闹钟服务。

// 定义一个虚拟闹钟的结构体
pub struct VirtualMuxAlarm<'a, A: Alarm> {alarm: &'a A,// 其他状态字段next_alarm: Option<Ticks>,callbacks: VecDeque<(Ticks, Callback)>,
}// 为 VirtualMuxAlarm 实现相关的方法和特征
impl<'a, A: Alarm> VirtualMuxAlarm<'a, A> {// 初始化虚拟闹钟pub fn new(alarm: &'a A) -> VirtualMuxAlarm<'a, A> {VirtualMuxAlarm {alarm: alarm,next_alarm: None,callbacks: VecDeque::new(),}}// 设置闹钟pub fn set_alarm(&mut self, when: Ticks, callback: Callback) {// 实现设置闹钟的逻辑// ...}
}

在上述代码中,VirtualMuxAlarm 结构体封装了虚拟闹钟的功能和状态。它依赖于一个实现了 Alarm 特征的底层闹钟设备,但本身是一个独立的模块,可被其他模块复用。

安全隔离

Tock OS 通过内存保护和能力机制确保胶囊间的安全隔离。在 Rust 中,这主要通过所有权和借用规则来实现。例如,在 virtual_alarm 胶囊中,VirtualMuxAlarm 结构体持有对底层闹钟设备的不可变引用:

pub struct VirtualMuxAlarm<'a, A: Alarm> {alarm: &'a A,// ...
}

这里的生命周期参数 'a 确保了 VirtualMuxAlarm 不会持有底层闹钟设备的引用超过其生命周期,避免了悬空引用和内存安全问题。同时,胶囊只能访问其被授权的资源,通过 Rust 的私有性规则(pub 和非 pub 成员)来限制对内部状态的访问。

事件驱动

胶囊采用事件驱动的编程模型。以 button 胶囊为例,它会对按钮按下和释放事件做出响应:

// 定义按钮事件的回调特征
pub trait ButtonClient {fn pressed(&self, btn_num: usize);fn released(&self, btn_num: usize);
}// 定义按钮胶囊结构体
pub struct Button<'a, C: ButtonClient> {client: &'a C,// 其他状态字段btn_state: [bool; NUM_BUTTONS],
}// 实现按钮胶囊的方法
impl<'a, C: ButtonClient> Button<'a, C> {// 处理按钮事件pub fn handle_interrupt(&mut self) {for i in 0..NUM_BUTTONS {let new_state = self.read_button_state(i);if new_state != self.btn_state[i] {if new_state {self.client.pressed(i);} else {self.client.released(i);}self.btn_state[i] = new_state;}}}// 读取按钮状态fn read_button_state(&self, btn_num: usize) -> bool {// 实现读取按钮状态的逻辑// ...}
}

在这个例子中,Button 胶囊会在检测到按钮状态变化时调用 ButtonClient 特征的 pressedreleased 方法,从而实现事件驱动的编程模型。

可复用性

胶囊的可复用性体现在多个方面。例如,virtual_alarm 胶囊可以在不同的项目中复用,只要提供一个实现了 Alarm 特征的底层闹钟设备即可:

// 在某个项目中使用 VirtualMuxAlarm
let hardware_alarm = get_hardware_alarm();
let virtual_alarm = VirtualMuxAlarm::new(&hardware_alarm);// 设置闹钟
virtual_alarm.set_alarm(Ticks::from_ms(1000), Callback::new(...));

通过这种方式,开发者可以在不同的项目中复用 VirtualMuxAlarm 胶囊,而无需重新实现闹钟功能。

相关文章:

  • 激活函数:神经网络的 “魔法开关”,开启智能之门(三)
  • 【Linux运维涉及的基础命令与排查方法大全】
  • Anaconda、conda和PyCharm在Python开发中各自扮演的角色
  • 机器学习06-RNN
  • EasyRTC打造无人机低延迟高清实时通信监控全场景解决方案
  • 电气动调节单座V型球阀带阀杆节流套沟槽孔板的作用-耀圣
  • 【Web API系列】Web Shared Storage API 深度解析:WindowSharedStorage 接口实战指南
  • RK3588 ubuntu20禁用自带的TF卡挂载,并设置udev自动挂载
  • JDBC对数据的增删改查操作:从Statement到PrepareStatement
  • Jupyter Notebook 中切换/使用 conda 虚拟环境的方式(解决jupyter notebook 环境默认在base下面的问题)
  • C语言文件操作完全手册:读写·定位·实战
  • 机器学习第二篇 多变量线性回归
  • go中map和slice非线程安全
  • Hive学习
  • 画布交互系统深度优化:从动态缩放、小地图到拖拽同步的全链路实现方案
  • 【Pandas】pandas DataFrame truediv
  • Android RecyclerView 多布局场景下的设计思考:SRP 与 OCP 的权衡与优化
  • 基于扣子(Coze.cn)与火山引擎构建高性能智能体的实践指南
  • Docker:重塑应用开发与部署的未来[特殊字符]
  • Codeforces Round 1019 (Div. 2)
  • 最高法:家长以监督为名虚构事实诋毁学校的,应承担侵权责任
  • 美国国务院:鲁比奥将不参加在伦敦举行的乌克兰问题会谈
  • 上海市委财经委会议分析研判当前经济运行情况,调度部署下阶段重点工作
  • 著名水声学家陆佶人逝世,曾参加我国第一代核潜艇主动声纳研制
  • “从山顶到海洋”科技成果科普巡展在重庆启动,免费开放
  • 00后为购演唱会门票转账近16万元“解封”银行卡,民警及时追回