reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
# eCos:ISR / DSR / thread、CDL 配置系统、HAL 与启动
<CORE RULE>
eCos 有两条同样重要的东西,**只掌握其中一条都会误判**:
```
运行期:ISR → DSR → thread 三层(中断模型)
构建期:CDL 配置系统决定编进什么、向量在哪、谁先跑
```
**同一份源码在不同配置下的产物差异极大**——所以顺序是:
```
先确认配置(CDL),再谈代码
```
</CORE RULE>
## 一、ISR 与 DSR 的分工
- ISR 返回时若带"需要调用 DSR"的位,系统会调用关联的 **DSR(Deferred Service Routine)**
- **若调度器未被锁定,DSR 立即运行**;**若被中断的线程恰在内核调用里锁了调度器,DSR 会被推迟到解锁之后**
- 这个推迟正是 DSR 能安全做某些内核调用的原因——**例如 post 一个信号量、signal 一个条件变量**
## 二、同步级别是 API 的属性
| 级别 | 谁可以调用 |
|---|---|
| **Thread** | 仅线程代码 |
| **DSR** | **DSR 或线程**代码 |
| **ISR** | **ISR、DSR 或线程**代码 |
**调用点落在哪一级,决定了哪些 API 是合法的。**
## 三、三种同步机制
| 机制 | 作用 | 谁能用 |
|---|---|---|
| **与 ISR 同步**(禁中断 + SMP 下自旋锁) | 阻止临界区内 ISR 运行 | 必须**短**且少用 |
| **与 DSR 同步** | 阻止临界区内 DSR 运行(内核里等价于取调度器锁) | **DSR 与线程可用;ISR 不允许使用** |
| **与线程同步**(互斥量、条件变量) | 线程级阻塞与唤醒 | **只有线程可以 lock 互斥量与 wait 条件变量;DSR 可以 signal 条件变量** |
**数据保护按"谁会碰它"分层**:被 ISR 访问的数据在任何层级(**包括 ISR 内部**)都要用 ISR 锁/自旋锁保护;DSR 与线程共享的用 DSR 锁;只有线程访问的用互斥量。
## 四、三种典型驱动模型
1. **全部处理放在 ISR**(DSR 只 signal 条件变量唤醒线程)
2. **处理推迟到 DSR**(DSR 可选地 signal 条件变量并解屏蔽中断)
3. **处理推迟到线程**(DSR 只 signal,线程随后获得完整内核设施)
## 五、CDL:配置系统决定一切
配置由 **CDL 定义**驱动,选项决定"编进什么"。几个有逆向价值的类别:
- **通信通道选择**(通道数量、调试通道、控制台通道及其波特率、控制台默认通道)
- **使用 ROM 监视器时这些通道选项通常失效**——由监视器选择通道;应用可通过配置项声明**自己接管通信**
- **调试/GDB 桩的包含与否**直接影响镜像内容与异常处理去向
- **构建目标**(ROM / ROMRAM / RAM 等)决定镜像是否需要在启动时重定位
**逆向含义**:拿到一个 eCos 镜像,"里面有什么"是配置的产物,不是源码的自然结果。**先把配置项与编入项对上,再解释代码。**
## 六、HAL:向量表与 VSR
- **向量表的位置完全由内存映射决定**:由内存布局工具决定,并体现在布局描述文件里
- 启动时**初始化向量表**
- 同步异常的向量项**大多指向一个默认异常向量**:它保存 CPU 状态并调用异常处理器,后者按配置**路由到调试桩或路由到 eCos**
- **由 ROM 监视器加载的应用,其向量项指向监视器自己的异常向量**——所以异常会进监视器(例如调试器),**除非应用显式替换该项**
- 异常向量的偏移由 HAL 头文件里的编号定义
## 七、虚拟向量:ROM 监视器给 RAM 应用提供的服务表
- 在**静态地址**处有一张表(几十个向量),指向服务函数或数据,让 ROM 配置(如 RedBoot)**为单独链接的 RAM 应用**提供服务
- 服务含:通信通道(控制台/调试)、微秒延时、复位、缓存刷新、**调试/控制台通道切换**、**调试系统调用(线程信息)**、flash 配置访问
- 由 ROM 监视器或按策略由独立/RAM 配置初始化;**无论用不用都保留固定的字节数**
- **代价是间接层**(体积/性能开销,并多一个失败点);收益是**应用可以不含调试桩也能被调试**
## 八、启动顺序(RedBoot / 典型 ROM 配置)
```
复位入口
→ 平台设置宏:禁中断与缓存、初始化内存控制器与时钟、建立并开启 MMU
(ROMRAM 情形还要重定位镜像)
→ HAL 启动:在 0 号位置放置向量指令、复制 .data、设栈、清 .bss
→ 硬件初始化
→ (含调试桩则)初始化调试桩
→ 中断(ctrl-C 类)初始化
→ 【调用构造函数】
→ 进入 cyg_start
```
**构造函数在硬件/桩/中断初始化之后、进入主启动之前运行。**
## 九、构造函数与内存布局的一个真实坑
**向量表所在区域如果与构造函数区域重叠,初始化会把构造函数冲掉**——曾出现过"预期的构造函数在某个地址上,结果被初始化向量表时覆盖"的实例。
**所以**:向量表位置必须按目标内存映射决定,**且如果需要被初始化,就不能放在 flash 里**。
## 十、调试与 GDB 桩
- **调试桩在 HAL 启动阶段被初始化**;异常处理器在**含桩时进 GDB**
- ROM 监视器通常包含 GDB 协议支持,**可以关掉以节省代码与内存**
- 虚拟向量让"不含桩的应用"也能被调试;但**某些较老的 ROM 监视器在异步调试中断上会失败**,除非应用里也配了调试支持
- 相关配置项控制"是否构建带 GDB 的监视器"以及"是否包含桩"
## 十一、平台差异与可配置性
- eCos 覆盖多种架构的 HAL,**不同架构的 HAL 在向量表、启动序列、缓存与 MMU 处理上不同**
- 调度器、定时器、同步原语都受配置影响;**"这版 eCos 的线程模型是怎样的"要由配置回答**
- 内存池与堆的配置同样属于构建期选择
## 决策树
```
拿到 eCos 目标
├─ 先确认配置(CDL)
│ ├─ 构建目标(ROM/ROMRAM/RAM)→ 是否启动时重定位
│ ├─ 是否含调试桩 → 异常去向
│ └─ 通道/控制台/调度器等选项 → 编入了什么
├─ 看到一个很短的中断处理函数
│ └─ 真正工作可能在 DSR(或第三个线程)
├─ 看到一个没有线程入口却反复执行的函数
│ └─ 可能是 DSR
├─ 判断某个内核调用是否合法
│ └─ 查它的同步级别(Thread / DSR / ISR)
├─ 异常去向与预期不符
│ ├─ 是否含调试桩?
│ ├─ 向量项指向 eCos 还是 ROM 监视器?
│ └─ 应用是否替换了向量项
├─ 构造函数"没运行"
│ └─ 查向量表所在区域是否与构造函数区域重叠(会被初始化冲掉)
└─ 找不到某个功能
└─ 可能是配置里就没编进去
```
## 工具与验证
- 配置:CDL 选项与编入项、构建目标、调试桩是否包含
- 分层:ISR 返回值(是否调度 DSR)、DSR 注册与调用点、各调用的同步级别
- HAL:向量表位置(布局文件)、向量项指向、异常处理器路由
- 启动:复位入口 → 平台设置 → HAL 启动 → 构造函数 → 主启动
- 验证:能同时说清「这份镜像是哪套配置构建的 + 中断处理分布在哪几层 + 异常会去哪里」
## 该平台的坑(汇总)
- **把 ISR 当完整的中断处理**:工作可能在 DSR,甚至在第三个线程里
- **把 DSR 当普通线程回调**:它有同步级别与调度约束,且会被调度器锁推迟
- **在 ISR 里套用 DSR 级同步的假设**:ISR 不允许使用 DSR 锁
- **以为 DSR 可以像线程一样等待**:能 signal 条件变量,不能 wait
- **按"中断发生时刻"推断时序**:DSR 的运行时机受调度器锁影响
- **不看配置就解释代码**:CDL 决定编入项、通道、调试桩、构建目标
- **把异常去向当固定**:取决于是否含桩、向量项指向谁、应用是否替换
- **忽略向量表与构造函数区域冲突**:构造函数会被初始化覆盖
- **以为 ROM 监视器加载的应用异常会进 eCos**:默认进监视器
- **把虚拟向量当纯开销**:它让无桩应用也能被调试,是有意的权衡