# QNX 系统启动流程完整文档
---## 1. 全流程概览QNX 系统从上电到应用就绪涉及 8 个主要阶段┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐│ 上电/固件 │ → │ IPL │ → │ Startup │ → │ Kernel │ → │ Boot │ → │ SLM / │ → │ 系统服务 │ → │ 应用程序 ││ (可选安全引导)│ │Initial Pgm│ │ Program │ │ (procnto) │ │ Script │ │ Services │ │ 启动 │ │ 就绪 │└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘PLL 6ms 硬件配置 MMU/中断 mount/ 进程启动 网络/存储 用户交互32ms max 镜像加载 系统页面 进程管理 devb-*/ secpolpush 文件系统跳转startup 内核回调 调度启动 io-sock/ waitfor SSH/shell转移内核 random### 各阶段耗时参考| 阶段 | 典型耗时 | 说明 ||------|---------|------|| PLL | 0–32 ms | 芯片特定与 OS 无关 || 固件/安全引导 | 2–50 ms | x86 BIOS/UEFI 或 ARM ROM monitor || IPL | 6 ms | 至少 6ms主要取决于 IFS 大小 || Startup | 数百 ms | 硬件探测和配置 || Kernel 初始化 | 数十 ms | MMU、分页、中断 || Boot Script | 数百 ms–秒 | 取决于驱动和服务的并行启动 || 应用栈 | 变化 | 依赖服务等待 (waitfor) |---## 2. 第一阶段上电与固件### 2.1 PLL (Phase Locked Loop)从电源施加到处理器执行第一条指令的时间。PLL 将主晶振频率分频到芯片定时器**可能长达 32 毫秒**。此阶段与 OS 无关完全由芯片决定。### 2.2 x86 vs ARM| 架构 | 固件 | 特点 ||------|------|------|| **x86** | BIOS 或 UEFI | 板卡无关的磁盘引导 || **ARM** | ROM monitor | 板卡特定的引导 |### 2.3 Secure Boot可选如果启用安全引导加密验证引导过程的每一阶段。依赖嵌入硬件的**不可变信任根**EEPROM 或 OTP 芯片。#### 引导链验证SoC BOOT CODE (CVK) → 验证 Bootloader#1 → 验证 Bootloader#2 → ... → 验证 IFS → (可选) 完整性保护文件系统任何阶段验证失败 → 引导立即停止。#### 两种实现方案| | 方案 1: OEM 管理密钥 (MRK) | 方案 2: 生产商注入密钥 ||---|---|---|| **密钥控制** | SoC OEM 签名生产商 CVK | 生产商完全控制 || **CVK 存储** | 无需保护存储绑定到 MRK | 哈希在 OTPCVK 在非保护内存 || **密钥更换** | 可替换 | 不可替换 || **制造安全性** | 容忍不安全流程 | 需安全密钥注入 |所有密钥为 PKI 公钥私钥离线保护设备上无私钥。---## 3. 第二阶段IPL (Initial Program Loader)### 3.1 概述IPL 是最小化引导组件尽可能少地使用代码。职责找到 OS 镜像 → 加载到 RAM → 跳转到 QNX startup 代码。### 3.2 五步引导序列| 步骤 | 操作 | 细节 ||------|------|------|| **1** | 完成硬件初始化 | 内存控制器配置、时钟设置、平台特定任务 || **2** | 设置 C 语言栈 | 为编译的 C 代码执行建立环境 || **3** | 查找并验证 OS 镜像 | 定位 IFS 镜像验证启动头startup.h完整性 || **4** | 加载 OS 镜像到内存 | 复制或解压到 RAM || **5** | 跳转到 startup 代码 | 将控制权转交 OS 镜像中的 startup 入口 |### 3.3 影响 IPL 设计的因素| 因素 | x86 | ARM ||------|-----|-----|| **板卡依赖性** | 板卡无关 | **板卡特定**必须为每板定制 || **存储介质** | 标准磁盘 | NOR Flash线性 XIP/ eMMC/SD非线性 || **压缩策略** | 可选 | 按存储性能权衡 |### 3.4 存储介质与压缩| 介质类型 | 特性 | IPL 复杂度 ||----------|------|-----------|| **NOR Flash** | 线性映射支持 XIP | 简单 || **eMMC / SD 卡** | 非线性映射 | 更复杂需读取和解压逻辑 || **SPI NOR Flash** | 非线性映射 | 复杂 |**压缩权衡:**- **压缩 IFS**: 减少存储占用但 IPL 需解压逻辑 → IPL 代码更大- **不压缩 IFS**: 存储占用更大但加载更快 → IPL 更简单### 3.5 IPL 库 API17 个函数| 类 | 函数 | 用途 ||----|------|------|| **核心引导** | image_scan() | 扫描内存查找有效系统镜像 || | image_setup() | 复制 startup 和 OS 镜像到 RAM 并准备执行 || | image_start() | 跳转到可引导 OS 镜像起点 || | jump() | 跳转到指定内存地址 || **串行下载** | image_download_8250() | 通过 8250 UART 下载 || | image_download_ser() | 通过串行下载 || | init_8250() | 初始化 8250 串口 (8N1) || **缓存/模式** | enable_cache() | 启用缓存 || | protected_mode() | 切换到保护模式 (x86) || **x86 视频** | print_string() / print_char() / etc | 调试输出 || **其他** | int15_copy() | 高内存复制到低内存缓冲区 |---## 4. 第三阶段Startup Program### 4.1 概述Startup 是可引导 OS 镜像中**第一个运行的程序**。每个硬件平台有特定变体。### 4.2 三大核心任务| 任务 | 内容 ||------|------|| **1. 硬件配置** | 完成 IPL 无法完成的系统级设置 || **2. 资源检测** | 探测并枚举 CPU、内存、IRQ、缓存等系统资源 || **3. 内核加载** | 加载 OS 内核 (procnto) 并转交控制权 |### 4.3 代码结构_start → _main → main_start() # 汇编入口设置最小 C 执行环境↓_main() # 额外低级初始化↓main() # 大部分 startup 代码配置、检测、内核启动### 4.4 Startup 构建的关键数据结构#### 系统页面 (System Page)Startup 构建的核心数据结构。18 个字段供操作系统在运行时查询cstruct syspage_entry {_Uint16t size; // 结构自身大小_Uint16t total_size; // 总大小含所有子结构_Uint16t type; // SYSPAGE_X86_64 (0x1100) / SYSPAGE_AARCH64 (0x1101)_Uint16t num_cpu; // CPU 数量默认 1syspage_entry_info system_private; // OS 引导时内部信息struct { _Uint16t major; _Uint16t minor; } version; // v2.0syspage_entry_info hwinfo; // 硬件平台总线、设备、IRQsyspage_entry_info qtime; // 时基和时钟信息syspage_entry_info callout; // 内核回调引用syspage_entry_info typed_strings; // confname.h 类型字符串syspage_entry_info strings; // 非类型字符串池syspage_entry_info smp; // SMP IPI 数据union { x86_64_syspage_entry; aarch64_syspage_entry; } un;syspage_array_info asinfo; // 内存映射 (RAM/SRAM/flash/IO)syspage_array_info cpuinfo; // 每 CPU 详情syspage_array_info cacheattr;// 缓存层级syspage_array_info intrinfo; // 中断控制器syspage_entry_info hypinfo; // Hypervisor 功能syspage_array_info cluster; // CPU 集群 (ARM big.LITTLE)};#### 内核回调 (Kernel Callouts)**特性**: 独立于内核的代码片段startup 复制到系统页面。内核通过它们执行硬件特定操作。| 约束 | 说明 ||------|------|| **汇编编写** | 必须位置无关 (PIC)startup 内存被释放后回调移至新地址 || **内联到内核** | 不使用 C return通过 CPU 寄存器通信 || **无静态存储** | 不能分配静态 R/W 存储 || **两个例外** | interrupt_id_*() 和 interrupt_eoi_*() 直接集成到内核代码性能原因 |---## 5. 第四阶段Kernelprocnto### 5.1 内核初始化Startup 将控制权转交给 procnto-smp-instrQNX 8.0 唯一变体。内核执行1. **MMU 初始化** — 创建分页和异常结构2. **中断启用** — 注册中断向量3. **进程管理器启动** — 创建第一个用户空间进程4. **调度器激活** — 开始线程调度### 5.2 procnto 关键启动参数| 参数 | 用途 ||------|------|| -P | 设置无特权最大优先级默认 63 || -mr | 启用 ASLR默认 || -qt | 启用 Pathtrust受信执行 || -d 0777 | 剥离 /proc 目录权限 || -u 0777 | 剥离 /proc 文件权限 || -U | 在启动时检查 AArch64 PAuth 支持 |### 5.3 内核角色procnto-smp-instr 微内核 进程管理器├── 线程调度固定优先级抢占 RR/FIFO/Sporadic├── IPC 内核调用MsgSend/MsgReceive/MsgReply├── 中断分发嵌套中断支持├── 内存管理mmap, shm_open, 虚拟地址空间└── 路径名空间管理资源管理器挂载---## 6. 第五阶段Boot Script启动脚本### 6.1 Buildfile 三段结构OS 镜像由 mkifs 从 buildfile 构建buildfile 有三段┌──────────────────────────────────────┐│ Bootstrap 段 ││ - 处理器架构 ││ - startup 名称 ││ - OS 内核 (procnto-smp-instr) ││ - 环境变量 │├──────────────────────────────────────┤│ [script] Script 段 ││ - 内核启动后由进程管理器执行的命令序列 ││ - 驱动加载、文件系统挂载、服务启动 │├──────────────────────────────────────┤│ Files 段 ││ - 包含在镜像中的文件、目录、符号链接 ││ - 权限、UID/GID、内联文件内容 │└──────────────────────────────────────┘### 6.2 典型启动脚本sh[script] startup-script {# 安全策略推送如有secpolpush# 系统日志slogger2# 基础服务piperandom# 块设备驱动 文件系统挂载devb-eide blk cache64M,autopartition,vnode2000,ncache2000,...waitfor /dev/hd0mount -t qnx6 /dev/hd0t179 /# 网络io-sock -m phy -m pci -d emwaitfor /dev/socket# 安全 shellreopen /dev/con1[session] ksh -l }### 6.3 安全策略版本的启动脚本sh[script] startup-script {secpolpushon -T slogger2_t slogger2 -U 20:20on -u 21:21 -T pipe_t pipeon -u 22:21 -T random_t randomon -T devb_t -u 23 devb-eide blk ...waitfor /dev/hd0on -T io_sock_t io-sock -m phy -m pci -d emwaitfor /dev/socketon -d -t /dev/con1 -T console_t ksh -lreopen /dev/con1}### 6.4 waitfor 机制waitfor /path — 阻塞直到对指定路径 stat() 成功。用于确保服务/设备在依赖方启动前就绪。### 6.5 关键启动参数选择| 工具 | 关键参数 | 说明 ||------|---------|------|| procnto-smp-instr | -P 255 -mr -qt | 最大优先级、ASLR、Pathtrust || devb-eide | blk cache64M,vnode2000 | 磁盘缓存、vnode 数量 || io-sock | -m phy -m pci -d em | PHY 模块、PCI 总线、E1000 驱动 || slogger2 | — | 系统日志守护进程 |---## 7. 第六阶段系统服务启动### 7.1 文件系统可用性/proc/boot/ # IFS 只读内容始终可用/dev/hd0t179/ # 块设备分区waitfor 后/ # 挂载的可写文件系统### 7.2 关键系统服务启动顺序| 顺序 | 服务 | 作用 ||------|------|------|| 1 | slogger2 | 系统日志所有后续服务输出记录 || 2 | pipe / random | 管道管理器 / 安全随机数 || 3 | devb-* / devc-* | 块设备/字符设备驱动 || 4 | mount | 文件系统挂载 || 5 | io-sock | 网络栈 || 6 | sshd / ksh | 远程/本地 shell 访问 |### 7.3 SLM (System Launch and Monitor)SLM 管理有依赖关系的复杂多进程应用启动。支持- **DAG 依赖解析** — 有向无环图依赖满足后并行启动- **组件状态机** — Idle→Starting→Started→Stopping→Session stopped→Fault→DSS- **6 种线程** — Main/Controller/Client Handler/Worker/Pulse Handler/Watchdog---## 8. 优化策略### 8.1 镜像大小优化| 策略 | 效果 ||------|------|| 删除不常用程序 | 减小 IFS → 更快加载 || 镜像压缩 | 存储更小但解压耗时 || 仅保留必须组件 | startup procnto 闪存驱动/网络 少量 .so | 组件越少启动失败概率越低。### 8.2 并行化- 显式 waitfor 仅用于严格依赖- IO 和计算重叠加载镜像同时初始化设备- 使用 SLM 的 DAG 并行启动### 8.3 驱动按需加载- io-sock 驱动热加载: mount -T io-sock em- Screen GPU 模块仅硬件渲染需要时加载- 减少启动时不必要的模块初始化### 8.4 PLL 优化32ms 的 PLL 锁定时间 — 某些芯片可通过配置降低但完全由 SoC 决定。---## 9. /proc/boot 与 IFS引导完成后OS 镜像内容以只读文件系统呈现于 /proc/boot/proc/boot/├── procnto-smp-instr # 内核├── startup-* # 启动程序├── .script # 启动脚本├── devc-ser8250-* # 串口驱动├── ksh # Korn shell├── ls, cat, pidin # 基本工具└── ...---## 10. 镜像部署### 10.1 镜像构建工具链Buildfile (.build) → mkifs → IFS 镜像 (.ifs)Buildfile (.build) → mkefs → EFS 镜像 (.efs)IPL IFS EFS → 组合工具 → 单一可引导镜像### 10.2 传输方式| 平台 | 方法 ||------|------|| **x86** | 标准磁盘引导 (BIOS/UEFI dloader) || **ARM** | SD 卡 / eMMC / USB / 串行下载 |### 10.3 镜像内容选择**可引导镜像** 包含:- startup-* procnto-smp-instr- 驱动和管理器- 应用程序和数据文件**不可引导镜像** (第二文件系统):- 不含内核和 startup- 独立配置场景---## 11. 调试与诊断| 工具 | 用途 ||------|------|| pidin | 引导后检查进程状态、abilities、安全类型 || dumpifs | 转储 IFS 镜像内容 || tracelogger | 内核事件跟踪 || traceprinter | 显示跟踪文件内容 || secpolgenerate | 策略生成期间的错误监控 || slog2info | 查看系统日志 |---