4. INTEGRITY分区与任务管理

INTEGRITY 是一款面向安全关键领域的分离内核(Separation Kernel)实时操作系统。它的核心思想是:把多个功能上互不信任、安全等级各异的应用,放进彼此隔离的“分区(Partition)”中运行,由内核统一保证时间与空间上的强隔离。理解分区与任务管理,本质上就是理解 INTEGRITY 如何用“分区”这一抽象,把资源、时间、地址空间和调度策略组织成可验证的结构。

一、分区、任务与地址空间的关系

在 INTEGRITY 中,分区是资源分配与隔离的基本单位,任务(Task)是调度的基本单位。一个分区可以包含一个或多个任务,这些任务共享该分区的地址空间、堆栈池、信号量与文件系统视图;而不同分区之间默认不能直接访问对方内存,必须通过内核提供的受控通信机制(如 Connection、Channel、SharedMemory)交换数据。这种“分区内共享、分区间隔离”的结构,是空间分区(Spatial Partitioning)的落地方式。

每个分区在配置时会被赋予一段独立的物理或虚拟地址空间,内核通过 MMU 页表把该分区限制在自己的地址窗口内。任务若试图访问窗口外的地址,会触发内存保护异常,由内核捕获并处理。因此,空间分区的关键不是“应用自觉不越界”,而是“硬件与内核强制其无法越界”。

INTEGRITY 分区—任务—地址空间结构 INTEGRITY 分离内核(调度 / 内存保护 / 分区间通信) 时间分区调度器 · MMU 地址窗口 · Connection / Channel / SharedMemory 分区 A(安全等级高) 任务 A1(优先级 10) 周期 10ms · 执行 2ms 任务 A2(优先级 20) 周期 20ms · 执行 3ms 地址窗口 0x4000_0000 – 0x400F_FFFF 堆栈池 / 信号量 / 文件视图 分区 B(安全等级中) 任务 B1(优先级 15) 周期 15ms · 执行 4ms 任务 B2(优先级 30) 周期 30ms · 执行 5ms 地址窗口 0x5000_0000 – 0x500F_FFFF 堆栈池 / 信号量 / 文件视图 分区 C(安全等级低) 任务 C1(优先级 25) 周期 25ms · 执行 6ms 任务 C2(优先级 40) 周期 50ms · 执行 8ms 地址窗口 0x6000_0000 – 0x600F_FFFF 堆栈池 / 信号量 / 文件视图 Channel SharedMem

二、分区创建:从配置到运行

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)的核心。

时间分区的意义在于:即使分区 C 中的低优先级任务出现死循环或超时,它也只能耗尽自己的 10ms 窗口,无法侵占分区 A 和 B 的 CPU 时间。这为混合安全等级系统提供了可证明的时间隔离。

四、时间分区与空间分区的实践要点

在实际工程中,时间分区与空间分区往往需要配合使用。空间分区解决“谁能访问哪块内存”,时间分区解决“谁能在什么时候使用 CPU”。两者结合,才能构成完整的分离保障。

空间分区的实践要点包括:为每个分区分配独立的地址窗口,避免任何重叠;把共享内存显式声明为 SharedMemory 区域,并限制读写权限;禁止分区直接调用其他分区的函数或访问其全局变量;所有跨分区数据交换必须经过内核通信对象。调试时,可以通过内核的异常日志观察是否有分区越界访问,若出现 MEMORY_PROTECTION_FAULT,说明该分区的地址窗口配置或指针使用存在问题。

时间分区的实践要点包括:先计算每个分区的总执行预算,确保所有分区预算之和不超过主时间框架周期的 80%–90%,留出内核与中断开销;为每个任务设置合理的周期与执行时间,避免预算不足导致任务被截断;使用内核提供的时间监控接口(如 TimeBudget 统计)观察每个分区的实际消耗,若某分区频繁超预算,应优化其任务代码或调整窗口长度。

分区地址窗口时间窗口任务优先级范围通信端点
分区 A0x4000_0000–0x400F_FFFF0–5ms10–20Channel_AB
分区 B0x5000_0000–0x500F_FFFF5–15ms15–30Channel_AB, SharedMem_BC
分区 C0x6000_0000–0x600F_FFFF15–25ms25–40SharedMem_BC

需要强调的是,表中的地址、时间与优先级均为教学示例,实际项目必须根据目标硬件、任务集和可调度性分析结果重新计算。INTEGRITY 的配置工具通常会在集成阶段执行可调度性检查,若发现某个分区的任务集在给定窗口内无法完成,会给出警告或错误,开发者应据此调整任务预算或窗口分配,而不是强行忽略。

五、结果观察与判断依据

分区与任务配置完成后,如何判断系统是否按预期运行?可以从三个层面观察:第一,内核启动日志中是否报告所有分区成功创建、地址窗口无冲突、时间窗口无重叠;第二,运行时通过调试通道查看各分区的任务切换记录,确认高优先级任务在窗口内被正确调度,低优先级任务没有越过窗口边界;第三,若系统集成了时间监控,可读取每个分区的实际执行时间与预算的比值,若长期接近或超过 100%,说明该分区需要优化或扩容。

当出现任务未按时执行、分区通信失败或系统复位时,应优先检查:地址窗口是否被意外修改、时间窗口是否被其他分区侵占、跨分区通信是否使用了未声明的端点。INTEGRITY 的分离特性使得这些问题通常被限制在单个分区内,不会像单体内核那样扩散到整个系统,这也是它在安全关键领域被广泛采用的重要原因。