4. INTEGRITY分区与任务管理
INTEGRITY 是一款面向安全关键领域的分离内核(Separation Kernel)实时操作系统。它的核心思想是:把多个功能上互不信任、安全等级各异的应用,放进彼此隔离的“分区(Partition)”中运行,由内核统一保证时间与空间上的强隔离。理解分区与任务管理,本质上就是理解 INTEGRITY 如何用“分区”这一抽象,把资源、时间、地址空间和调度策略组织成可验证的结构。
一、分区、任务与地址空间的关系
在 INTEGRITY 中,分区是资源分配与隔离的基本单位,任务(Task)是调度的基本单位。一个分区可以包含一个或多个任务,这些任务共享该分区的地址空间、堆栈池、信号量与文件系统视图;而不同分区之间默认不能直接访问对方内存,必须通过内核提供的受控通信机制(如 Connection、Channel、SharedMemory)交换数据。这种“分区内共享、分区间隔离”的结构,是空间分区(Spatial Partitioning)的落地方式。
每个分区在配置时会被赋予一段独立的物理或虚拟地址空间,内核通过 MMU 页表把该分区限制在自己的地址窗口内。任务若试图访问窗口外的地址,会触发内存保护异常,由内核捕获并处理。因此,空间分区的关键不是“应用自觉不越界”,而是“硬件与内核强制其无法越界”。
二、分区创建:从配置到运行
INTEGRITY 的分区通常在集成阶段通过配置文件(如 .int 文件或基于 MULTI 工具链的工程配置)静态定义,而不是在运行时随意创建。这样做是为了让系统在启动前就完成资源分配与可调度性分析,符合安全关键系统“设计即验证”的要求。一个典型的分区定义包含以下要素:
- 分区名称与 ID:用于内核识别与调试跟踪,例如
Partition_A。 - 地址空间范围:起始地址与长度,决定该分区可访问的物理/虚拟内存窗口。
- 任务列表:该分区内所有任务的入口、优先级、周期、执行时间预算。
- 时间窗口:在时间分区调度中分配给该分区的执行时间片。
- 通信端点:该分区允许使用的 Connection、Channel 或共享内存区域。
下面是一个简化的分区配置片段示例(参数为教学假设值,非实测结果):
Partition_A {
id = 1;
memory = { base = 0x40000000; size = 0x00100000; };
tasks = {
Task_A1 { priority = 10; period = 10ms; budget = 2ms; entry = "a1_main"; };
Task_A2 { priority = 20; period = 20ms; budget = 3ms; entry = "a2_main"; };
};
time_window = { offset = 0ms; duration = 5ms; };
connections = { Channel_AB; };
};
配置完成后,内核在启动阶段会为每个分区建立地址映射、初始化任务控制块(TCB)、注册时间窗口,并把分区置为可调度状态。若某个分区的内存窗口与另一个分区重叠,或时间窗口总长度超过主时间框架周期,配置工具会在集成阶段报错,而不是等到运行时才暴露问题。
三、任务调度策略与优先级配置
INTEGRITY 支持多种调度策略,最常用的是基于优先级的抢占式调度与时间分区调度(Time Partitioning Scheduling,TPS)。在优先级抢占模式下,每个分区内部的任务按优先级排序,高优先级任务就绪时立即抢占低优先级任务;而分区之间则通过时间窗口轮转,保证每个分区在固定周期内获得确定的 CPU 时间。
优先级配置需要遵循两条原则:第一,同一分区内,周期越短、实时性要求越高的任务,优先级应越高;第二,不同分区之间的优先级不直接比较,因为时间分区调度器已经用时间窗口隔离了它们。换句话说,分区 A 的优先级 10 任务和分区 B 的优先级 15 任务,不会因为数值大小而互相抢占,它们只在各自的时间窗口内运行。
以图中三个分区为例,主时间框架周期设为 30ms,分区 A 获得 0–5ms,分区 B 获得 5–15ms,分区 C 获得 15–25ms,剩余 5ms 作为内核与空闲开销。在分区 A 的 5ms 窗口内,任务 A1(优先级 10)先运行 2ms,然后任务 A2(优先级 20)运行 3ms;若 A1 在 2ms 内未完成,它会继续占用窗口,直到预算耗尽或被内核挂起。这种“窗口内优先级抢占、窗口间时间隔离”的机制,就是时间分区(Temporal Partitioning)的核心。
四、时间分区与空间分区的实践要点
在实际工程中,时间分区与空间分区往往需要配合使用。空间分区解决“谁能访问哪块内存”,时间分区解决“谁能在什么时候使用 CPU”。两者结合,才能构成完整的分离保障。
空间分区的实践要点包括:为每个分区分配独立的地址窗口,避免任何重叠;把共享内存显式声明为 SharedMemory 区域,并限制读写权限;禁止分区直接调用其他分区的函数或访问其全局变量;所有跨分区数据交换必须经过内核通信对象。调试时,可以通过内核的异常日志观察是否有分区越界访问,若出现 MEMORY_PROTECTION_FAULT,说明该分区的地址窗口配置或指针使用存在问题。
时间分区的实践要点包括:先计算每个分区的总执行预算,确保所有分区预算之和不超过主时间框架周期的 80%–90%,留出内核与中断开销;为每个任务设置合理的周期与执行时间,避免预算不足导致任务被截断;使用内核提供的时间监控接口(如 TimeBudget 统计)观察每个分区的实际消耗,若某分区频繁超预算,应优化其任务代码或调整窗口长度。
| 分区 | 地址窗口 | 时间窗口 | 任务优先级范围 | 通信端点 |
|---|---|---|---|---|
| 分区 A | 0x4000_0000–0x400F_FFFF | 0–5ms | 10–20 | Channel_AB |
| 分区 B | 0x5000_0000–0x500F_FFFF | 5–15ms | 15–30 | Channel_AB, SharedMem_BC |
| 分区 C | 0x6000_0000–0x600F_FFFF | 15–25ms | 25–40 | SharedMem_BC |
需要强调的是,表中的地址、时间与优先级均为教学示例,实际项目必须根据目标硬件、任务集和可调度性分析结果重新计算。INTEGRITY 的配置工具通常会在集成阶段执行可调度性检查,若发现某个分区的任务集在给定窗口内无法完成,会给出警告或错误,开发者应据此调整任务预算或窗口分配,而不是强行忽略。
五、结果观察与判断依据
分区与任务配置完成后,如何判断系统是否按预期运行?可以从三个层面观察:第一,内核启动日志中是否报告所有分区成功创建、地址窗口无冲突、时间窗口无重叠;第二,运行时通过调试通道查看各分区的任务切换记录,确认高优先级任务在窗口内被正确调度,低优先级任务没有越过窗口边界;第三,若系统集成了时间监控,可读取每个分区的实际执行时间与预算的比值,若长期接近或超过 100%,说明该分区需要优化或扩容。
当出现任务未按时执行、分区通信失败或系统复位时,应优先检查:地址窗口是否被意外修改、时间窗口是否被其他分区侵占、跨分区通信是否使用了未声明的端点。INTEGRITY 的分离特性使得这些问题通常被限制在单个分区内,不会像单体内核那样扩散到整个系统,这也是它在安全关键领域被广泛采用的重要原因。