reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
122
vendor-new/rev-skills/.claude/skills/re-fw-emulate/SKILL.md
Normal file
122
vendor-new/rev-skills/.claude/skills/re-fw-emulate/SKILL.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
name: re-fw-emulate
|
||||
description: >
|
||||
固件仿真:QEMU 用户态/全系统。
|
||||
触发词:仿真、QEMU、firmadyne、跑固件
|
||||
capabilities: [emulation]
|
||||
---
|
||||
|
||||
# 固件仿真(QEMU)
|
||||
|
||||
## 何时使用 / 何时不用
|
||||
|
||||
- 用:需要运行固件内程序观察行为/验证假设(固件 web 界面、服务端逻辑)
|
||||
- 用:rootfs 已解出、需要整体启动(全系统仿真)
|
||||
- 不用:只需静态分析([[re-fw-rootfs]] 已覆盖)
|
||||
- 不用:有实物板子且必须真实硬件交互(走 [[re-hardware-io]],硬件提取/接口调试)
|
||||
- 不用:目标只是解包看内容(走 [[re-fw-extract]])
|
||||
|
||||
## 工具准备
|
||||
|
||||
所有工具先验证再使用。仿真 = 动态执行,默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则);用户态仿真优先(最轻可行方案)。
|
||||
|
||||
### qemu-user —— 用户态仿真(最轻)
|
||||
|
||||
- Linux: `apt install qemu-user` / `dnf install qemu-user` / `pacman -S qemu-user`
|
||||
- macOS: `brew install qemu`(含用户态与系统态)
|
||||
- Windows/WSL: WSL 内 Linux 版
|
||||
- 验证: `qemu-arm --version`、`qemu-mips --version`(大端)、`qemu-mipsel --version`(小端)
|
||||
|
||||
### qemu-system —— 全系统仿真
|
||||
|
||||
- Linux: `apt install qemu-system-arm qemu-system-mips` / `dnf install qemu-system-arm qemu-system-mips` / `pacman -S qemu-system-arm qemu-system-mips`
|
||||
- macOS: `brew install qemu`
|
||||
- Windows/WSL: WSL 内 Linux 版
|
||||
- 验证: `qemu-system-arm --version`
|
||||
|
||||
### binfmt_misc —— 直接执行交叉程序
|
||||
|
||||
- Linux: `apt install binfmt-support qemu-user-static`(Debian/Ubuntu 装 qemu-user-static 即自动注册各架构 binfmt 条目;Fedora 用 systemd binfmt 配置);手动注册: `update-binfmts --enable qemu-arm`(或 /etc/binfmt.d/ 配置文件)
|
||||
- macOS/Windows: 不支持,用 `qemu-<arch>` 显式调用
|
||||
- 验证: `ls /proc/sys/fs/binfmt_misc/` 可见 qemu-arm 条目;之后可直接执行 `./rootfs_out/usr/sbin/httpd`
|
||||
|
||||
### gdb-multiarch + gdbserver —— 交叉调试
|
||||
|
||||
- Linux: `apt install gdb-multiarch` / `dnf install gdb-multiarch` / `pacman -S gdb-multiarch`;gdbserver: `apt install gdbserver`(或随 gdb 包提供)
|
||||
- macOS: `brew install gdb`(需 Developer Tools 授权,见 [[re-analyze/platform-tips]] macOS 分支)或 WSL 内 Linux 版
|
||||
- Windows/WSL: WSL 内 Linux 版
|
||||
- 验证: `gdb-multiarch --version`
|
||||
|
||||
### firmadyne —— 全系统自动仿真框架(思路参考,可选装)
|
||||
|
||||
- 安装: `git clone https://github.com/firmadyne/firmadyne`,依赖 qemu-system-* 与预编译内核(scripts/ 下下载),首次搭建较重
|
||||
- 验证: `ls sources/` 有 getArch.py 等脚本;`which qemu-system-mips`
|
||||
- 多数单程序分析不需要它——用户态优先([[re-analyze/platform-tips]] 先给最轻可行方案)
|
||||
|
||||
## 操作步骤
|
||||
|
||||
按顺序执行,每步记下结果。
|
||||
|
||||
1. **用户态仿真(最轻,优先)**:
|
||||
```sh
|
||||
file rootfs_out/usr/sbin/httpd # 确认架构:ARM 32/64、MIPS(BE/EL)、RISC-V
|
||||
qemu-arm -L rootfs_out rootfs_out/usr/sbin/httpd # -L 把 rootfs 当 sysroot(动态库/链接器从 rootfs 加载)
|
||||
# 大端 MIPS: qemu-mips -L rootfs_out ...
|
||||
# 小端 MIPS: qemu-mipsel -L rootfs_out ...
|
||||
```
|
||||
缺库报错 → 交叉 `ldd` / `readelf -d` 看依赖,从 rootfs 补库;Web 服务类程序可加 `-E` 传环境变量。
|
||||
- `-strace` 记录客户程序系统调用(等效仿真内 strace——排查 mmap/ioctl 崩溃点直接用它)
|
||||
- `-0 <argv0>` 伪造 argv[0](程序按调用名分支时用);`-cpu <型号>` 指定 CPU(如 `qemu-arm -cpu cortex-a9`)
|
||||
- 跑不起来但静态可分析 → 回 [[re-fw-rootfs]] / [[re-binary-core]],不在仿真上死磕。
|
||||
|
||||
2. **全系统仿真**:
|
||||
```sh
|
||||
# ARM(vexpress 平台)+ 内核与 initramfs:
|
||||
qemu-system-arm -M vexpress-a9 -kernel vmlinuz -initrd initramfs.img -nographic \
|
||||
-append "console=ttyAMA0 root=/dev/ram rdinit=/sbin/init"
|
||||
# MIPS(malta 平台,大端示例):
|
||||
qemu-system-mips -M malta -kernel vmlinuz -initrd initramfs.img -nographic \
|
||||
-append "console=ttyS0 rdinit=/sbin/init"
|
||||
```
|
||||
把 rootfs 制作成磁盘镜像(ext2 挂 root)或 initramfs(cpio 打包 rootfs_out);firmadyne 的脚本就是自动化这套流程。
|
||||
rootfs 已是磁盘镜像时直接挂盘:
|
||||
```sh
|
||||
qemu-system-arm -M vexpress-a9 -kernel vmlinuz -drive file=rootfs.ext2,format=raw \
|
||||
-nographic -append "console=ttyAMA0 root=/dev/mmcblk0 rdinit=/sbin/init"
|
||||
```
|
||||
root 设备名按平台磁盘控制器定(vexpress=mmcblk0、malta 的 IDE=/dev/sda 等,以 `-M` 平台文档为准)。
|
||||
|
||||
3. **外设缺失用 stub/回环**:
|
||||
- 用户态:程序 mmap 固定地址(GPIO/UART 寄存器)崩溃 → `strace` 定位访问点,`LD_PRELOAD` 提供 stub 库返回假寄存器值
|
||||
- 全系统:`-device` 挂虚拟外设(e1000 / virtio 等);真实芯片外设(wifi/基带)QEMU 无法模拟 → 打补丁跳过初始化或 stub 该 ioctl
|
||||
- 先确定程序初始化到哪一步崩(串口输出/日志),再决定 stub 哪部分
|
||||
|
||||
4. **交叉调试(qemu -g + gdb-multiarch)**:
|
||||
```sh
|
||||
qemu-arm -g 1234 -L rootfs_out rootfs_out/usr/sbin/httpd & # -g 起 gdbstub
|
||||
gdb-multiarch rootfs_out/usr/sbin/httpd
|
||||
(gdb) target remote :1234
|
||||
```
|
||||
全系统内:把 gdbserver 放进 rootfs,`gdbserver :1234 /usr/sbin/httpd`,宿主 `target remote <qemu_ip>:1234`;调试手法按 [[re-gdb]]。
|
||||
|
||||
5. **网络隔离下仿真**:
|
||||
- 用户态:不是网络沙箱(socket/connect 经 syscall 转发到宿主内核),需要受控网络时改用全系统方案
|
||||
- 全系统:QEMU 不加网络参数会默认建 NIC(e1000)+ user 后端——先显式 `-nic none` 确认行为,需要受控网络再加 `-nic user,restrict=on`(用户态 NAT,仅模拟出站)
|
||||
- 分析回连/协议前先隔离([[re-analyze/platform-tips]] 最高原则),流量抓包与协议重建转 [[re-protocol]];firmadyne 默认带网卡也需按此原则先行隔离
|
||||
|
||||
## 跨域联合
|
||||
|
||||
- [[re-firmware]]:工作流第 4 步固定调用本技能
|
||||
- 架构识别与指令级深挖:ARM(向量表/Thumb/MMIO 外设交叉)→ [[re-arm]];RISC-V(RV32/RV64/ecall)→ [[re-riscv]](选对 qemu-<arch> 前先对照)
|
||||
- 仿真内动态行为观察 → [[re-tracing]] + [[re-gdb]](默认沙箱内,[[re-analyze/platform-tips]] 最高原则)
|
||||
- 固件运行产生通信 → [[re-protocol]];仿真内 ELF 深挖 → [[re-binary-core]]
|
||||
- 仿真不成的程序回退静态 → [[re-fw-rootfs]]
|
||||
|
||||
## 常见坑与陷阱
|
||||
|
||||
- **外设寄存器访问崩溃**:现象——程序 mmap 固定地址后读 GPIO/UART 寄存器段错误;原因——QEMU 用户态不模拟外设,地址无映射;对策——strace 定位访问点,LD_PRELOAD stub 返回模拟值(步骤 3)
|
||||
- **架构选错直接 segfault**:现象——qemu-arm 跑 MIPS 程序秒崩;原因——没先 `file`/`readelf` 确认架构与字节序(大端 mips ≠ mipsel);对策——步骤 1 先确认,选对 qemu-<arch>
|
||||
- **网卡型号不符 → 初始化卡死**:现象——程序在网卡初始化处挂起不退出;原因——固件按特定芯片初始化,默认挂的 e1000 不匹配,ioctl 无返回;对策——按固件预期加 `-device <型号>` 等虚拟网卡,或先 `-nic none` 观察是否跳过(步骤 5)
|
||||
- **时间戳/时钟函数陷阱**:现象——程序读时间怪异(1970/倒退),行为与真实设备不同;原因——QEMU 虚拟时钟与墙钟不同步;对策——`-rtc base=utc` 固定,或 stub 掉 clock_gettime 相关调用
|
||||
- **网络未隔离就仿真**:现象——固件真实回连外网(C2/升级服务器);原因——QEMU 默认就建 NIC + user 后端(restrict=off),跳过显式隔离即联网;对策——全系统仿真显式 `-nic none`,用户态也非网络沙箱(步骤 5),回连分析前按 [[re-analyze/platform-tips]] 隔离
|
||||
- 命令族速查与操作序列见 [[commands]];工具特有坑与版本差异见 [[gotchas]]
|
||||
@@ -0,0 +1,114 @@
|
||||
# QEMU 仿真命令速查与操作序列(用户态 / 全系统)
|
||||
|
||||
分工:qemu-user(用户态,跑单程序最轻)→ qemu-system(全系统,启动完整固件)→ binfmt_misc(直接执行交叉程序)→ gdb-multiarch(交叉调试)。参数以本机 `qemu-<arch> --help` / `qemu-system-<arch> --help` 为准(版本差异见 [[gotchas]])。
|
||||
|
||||
## 命令族速查
|
||||
|
||||
### qemu-user —— 用户态仿真
|
||||
|
||||
| 用途 | 命令 |
|
||||
|---|---|
|
||||
| 架构对应 | `qemu-arm`(32 位)/ `qemu-aarch64` / `qemu-mips`(大端)/ `qemu-mipsel`(小端)/ `qemu-riscv64` 等 |
|
||||
| 基本运行 | `qemu-arm -L <rootfs> <rootfs>/usr/sbin/httpd` |
|
||||
| sysroot | `-L <path>`(动态库/链接器从 rootfs 加载;缺 `-L` 报 ld-linux 找不到) |
|
||||
| 环境变量 | `-E VAR=value`(可多个;Web 服务常传 `-E LD_LIBRARY_PATH=...`) |
|
||||
| 伪造 argv[0] | `-0 <argv0>`(程序按调用名分支时用) |
|
||||
| 系统调用日志 | `-strace`(等效仿真内 strace,排查 mmap/ioctl 崩溃点) |
|
||||
| gdbstub | `-g <port>`(等 gdb 连接,配合 gdb-multiarch) |
|
||||
| 指定 CPU | `-cpu <型号>`(`-cpu help` 列全部,如 cortex-a9) |
|
||||
| 限定地址空间 | `-B <size>`(guest 地址空间大小,老内核小空间时用) |
|
||||
| 启动即暂停 | `-g` 之外可用 `-d in_asm` 反汇编日志(调试/取证) |
|
||||
|
||||
### qemu-system —— 全系统仿真
|
||||
|
||||
| 用途 | 命令 |
|
||||
|---|---|
|
||||
| 平台选择 | `-M vexpress-a9`(ARM)/ `-M malta`(MIPS)/ `-M virt`(通用)——`-M help` 列全部 |
|
||||
| 内核与 initramfs | `-kernel vmlinuz -initrd initramfs.img` |
|
||||
| 挂磁盘镜像 | `-drive file=rootfs.ext2,format=raw` |
|
||||
| 串口到终端 | `-nographic`(`-serial mon:stdio` 变体) |
|
||||
| 内核参数 | `-append "console=ttyAMA0 root=/dev/ram rdinit=/sbin/init"` |
|
||||
| 网络(显式添加) | `-netdev user,id=n0 -device e1000,netdev=n0`(用户态 NAT,仅出站) |
|
||||
| 网络简写 | `-nic user,model=e1000`(新版推荐;`-net` 旧语法已标记弃用) |
|
||||
| 完全断网 | 显式 `-nic none`(或 `-nodefaults`)——不加网络参数会默认建 NIC + user 后端 |
|
||||
| 虚拟外设 | `-device virtio-net-pci,netdev=n0` / `-device e1000` 等(`-device help` 列全部) |
|
||||
| 固定时钟 | `-rtc base=utc`(避免时间怪异,见 [[gotchas]]) |
|
||||
| 内存 | `-m 256`(按固件需求,常见 64-256MB) |
|
||||
| gdbstub | `-s`(1234 端口)/ `-S`(启动即暂停等 gdb) |
|
||||
|
||||
### binfmt_misc —— 直接执行交叉程序
|
||||
|
||||
```sh
|
||||
# Debian/Ubuntu:apt install binfmt-support qemu-user-static 后自动注册
|
||||
# 手动注册:update-binfmts --enable qemu-arm(或 /etc/binfmt.d/ 配置文件)
|
||||
ls /proc/sys/fs/binfmt_misc/ # 可见 qemu-arm 等条目
|
||||
./rootfs_out/usr/sbin/httpd # 之后可直接执行(等效 qemu-arm -L rootfs_out ...)
|
||||
# 注意:binfmt 直接执行不带 -L sysroot,动态链接程序仍需设置 QEMU_LD_PREFIX 或先解出依赖
|
||||
```
|
||||
|
||||
### gdb-multiarch + gdbserver —— 交叉调试
|
||||
|
||||
```sh
|
||||
qemu-arm -g 1234 -L rootfs_out rootfs_out/usr/sbin/httpd & # 用户态 gdbstub
|
||||
gdb-multiarch rootfs_out/usr/sbin/httpd
|
||||
(gdb) target remote :1234
|
||||
# 全系统内:rootfs 里放 gdbserver,gdbserver :1234 /usr/sbin/httpd
|
||||
# 宿主 (gdb) target remote <qemu_guest_ip>:1234
|
||||
```
|
||||
|
||||
## 常用操作序列
|
||||
|
||||
### 1. 用户态跑单个固件程序(最轻,优先)
|
||||
|
||||
```
|
||||
file 确认架构与字节序 → qemu-<arch> -L <rootfs> <程序>
|
||||
→ 缺库:readelf -d 看依赖,从 rootfs 补(或 -E LD_LIBRARY_PATH)
|
||||
→ 崩溃:加 -strace 看系统调用,定位到 mmap/ioctl 访问点再决定 stub(序列 4)
|
||||
```
|
||||
|
||||
### 2. 全系统启动(initramfs 与磁盘镜像两式)
|
||||
|
||||
```
|
||||
式一(initramfs):cpio 打包 rootfs_out → -kernel vmlinuz -initrd initramfs.img -append "rdinit=/sbin/init"
|
||||
式二(磁盘镜像):dd/ext2 制作 rootfs.ext2 → -kernel vmlinuz -drive file=rootfs.ext2,format=raw -append "root=/dev/<设备>"
|
||||
→ 串口看不到输出先核对 console= 参数与 -M 平台(ttyAMA0=ttyS0 因平台而异)
|
||||
```
|
||||
|
||||
### 3. 仿真内交叉调试(用户态 / 全系统)
|
||||
|
||||
```
|
||||
用户态:qemu-arm -g 1234 → gdb-multiarch target remote :1234
|
||||
全系统:gdbserver 放进 rootfs → 在固件里启动 gdbserver → 宿主 target remote <guest_ip>:1234
|
||||
→ 调试手法(断点/内存/单步)按 [[re-gdb]]
|
||||
```
|
||||
|
||||
### 4. 外设缺失 stub(GPIO/UART 寄存器崩溃)
|
||||
|
||||
```
|
||||
qemu-<arch> -strace 定位首个崩溃访问(如 mmap 固定地址后读 [addr])
|
||||
→ LD_PRELOAD 提供 stub 库:该地址返回模拟值(用户态)
|
||||
→ 全系统:-device 挂虚拟外设(e1000/virtio);真实芯片外设打补丁跳过初始化
|
||||
→ 先确认程序初始化到哪一步崩(串口输出/日志),再决定 stub 范围
|
||||
```
|
||||
|
||||
### 5. 网络隔离下仿真
|
||||
|
||||
```
|
||||
全系统先 -nic none(不加网络参数会默认建 NIC + user 后端)确认行为 → 需要受控网络再加 -nic user,model=e1000,restrict=on
|
||||
→ 回连/协议分析前按 [[re-analyze/platform-tips]] 隔离;抓包与协议重建转 [[re-protocol]]
|
||||
→ firmadyne 默认带网卡,同样先隔离再跑
|
||||
```
|
||||
|
||||
## 实现教训(内化)
|
||||
|
||||
- 用户态先行:单程序 80% 场景 qemu-user 足够,别一上来搭全系统
|
||||
- `-L` 不匹配的典型症状是 ld-linux 报错——先把 sysroot 指对再谈其他
|
||||
- `-strace` 是仿真内排障第一工具:崩溃/挂起先看系统调用流
|
||||
- 全系统串口无输出先查 `console=` 与 `-M` 平台匹配(console 设备名因平台/内核而异)
|
||||
- 仿真是验证手段不是目的:跑不动且静态可分析就回退静态([[re-fw-rootfs]] / [[re-binary-core]])
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 仿真 = 动态执行,默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则)
|
||||
- 架构识别先做([[re-arm]] / [[re-riscv]] / [[re-mips]] 对照),选错 qemu-<arch> 秒崩
|
||||
- 产物与日志 sha256 入档([[re-triage]] 惯例);仿真结论写 [[re-analyze/analysis-contract]]
|
||||
@@ -0,0 +1,43 @@
|
||||
# QEMU 仿真工具特有坑与边界
|
||||
|
||||
## 架构与启动
|
||||
|
||||
- **架构/字节序选错秒崩**:大端 MIPS(qemu-mips)与小端(qemu-mipsel)互跑直接 Invalid ELF/segfault——先 `file`/`readelf -h` 确认;ARM 32/64(qemu-arm vs qemu-aarch64)同理
|
||||
- **-L sysroot 不匹配**:缺 `-L` 或指向错误目录 → 报 ld-linux 找不到/加载器版本不符——sysroot 必须含目标架构的 `/lib`、`/usr/lib` 与动态链接器
|
||||
- **内核与 rootfs 不匹配**:全系统内核必须支持 rootfs 的文件系统与架构(如 ext2 内核没编入 → 挂载失败 Kernel panic)——换内核或换文件系统格式
|
||||
- **console 参数与平台不匹配**:`console=ttyAMA0`(vexpress)vs `console=ttyS0`(malta)——串口无输出先核对,别先怀疑内核坏了
|
||||
- **-M 平台与设备模型耦合**:同一内核在不同 -M 平台(vexpress/virt)下设备树不同——换平台要同步换 -append/root 设备名
|
||||
|
||||
## 外设与内存
|
||||
|
||||
- **用户态不模拟外设**:mmap 固定地址(GPIO/UART 寄存器)后访问直接段错误——`-strace` 定位访问点,LD_PRELOAD stub 返回模拟值(见 [[commands]] 序列 4)
|
||||
- **网卡型号与固件预期不符导致初始化挂起**:固件按特定芯片初始化时 ioctl 无返回、程序卡死——默认挂的 e1000 未必匹配,按固件预期加 `-device <型号>`/virtio;也可先 `-nic none` 确认是否能跳过网络初始化(见 [[commands]] 序列 5)
|
||||
- **内存给太小**:固件按真实内存初始化(malloc 上限/分区表),`-m 32` 可能启动失败——常见 64-256MB 起步试
|
||||
- **时间/时钟怪异**:QEMU 虚拟时钟与墙钟不同步(读时间 1970/倒退)——`-rtc base=utc` 固定,或 stub 掉 clock_gettime 相关调用
|
||||
|
||||
## qemu-user 边界
|
||||
|
||||
- **只仿真用户态指令**:特权指令/内核路径(驱动 ioctl 真实设备)不工作——需要完整内核行为的程序必须全系统仿真
|
||||
- **进程模型差异**:qemu-user 对 fork/线程有支持但受限(老版本多线程程序偶发崩溃)——多线程目标优先全系统
|
||||
- **共享内存/IPC 受限**:POSIX shm、跨进程通信在用户态仿真下不可靠——依赖共享内存的多进程固件走全系统
|
||||
- **-strace 输出量大**:全量系统调用日志可 GB 级——`-strace` 后管道 grep 目标调用(open/connect/mmap)
|
||||
|
||||
## 网络与隔离
|
||||
|
||||
- **qemu-system 默认有网络**:未显式声明网络时 QEMU 会自动创建默认 NIC(`e1000`)与 user 模式后端(`type=user,net=10.0.2.0,restrict=off`)——**分析不可信固件必须显式 `-nic none`**(或 `-nodefaults`)才真正无网络;需要受控出站时用 `-nic user,restrict=on` 或隔离 TAP / network namespace
|
||||
- **qemu-user 不是网络沙箱**:guest 的 socket/connect 经 syscall 转发到宿主内核,可直接访问宿主回环与网络——从 qemu-user 跑出站连接不代表隔离,回连分析同样按 [[re-analyze/platform-tips]] 隔离
|
||||
- **user 模式不是隔离**:`-nic user` 的 guest 出站直达宿主网络栈——回连分析前仍按 [[re-analyze/platform-tips]] 隔离(断外网/fake DNS),firmadyne 默认网卡同样先隔离
|
||||
- **guest 内需要 IP 固定**:user 模式 NAT 的 DHCP/地址分配与固件假设不符时程序初始化失败——`-nic user,net=192.168.x.0/24` 定制网段
|
||||
|
||||
## 版本差异
|
||||
|
||||
- **QEMU 8/9/10/11 世代**:网络配置推荐 `-nic`/`-netdev` 简写(`-net` 旧语法仍兼容但标记弃用);`-device` 支持的外设模型持续扩充;新版对 ARM/MIPS 平台支持更完整(老版可能缺某些 -M 平台)
|
||||
- **qemu-user 与 qemu-system 分包**:发行版拆分为 qemu-user(各架构用户态)+ qemu-system-<arch>——只装其一会出现"命令不存在";Debian 系 `apt install qemu-user qemu-system-arm qemu-system-mips` 按需装
|
||||
- **qemu-user-static**:Debian 系含静态链接的 qemu-<arch>-static(binfmt 直接执行用);普通 qemu-user 是动态链接版,无法给宿主上 binfmt 用
|
||||
- **内核侧**:同 -M 平台下不同版本内核的设备树/驱动行为有差异——固件配套内核缺失时试同架构近版本内核
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 仿真 = 动态执行,默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则)
|
||||
- 跑不动且静态可分析就回退静态([[re-fw-rootfs]] / [[re-binary-core]]),不在仿真上死磕
|
||||
- 仿真结果与真实硬件行为有差距(时序/外设/内核驱动)——涉及硬件交互的结论用 [[re-hardware-io]] 验证
|
||||
Reference in New Issue
Block a user