纯 Rust 实现的 Qualcomm Sahara + Firehose 协议工具
Warning
本项目还在开发中,不建议在生产环境中使用。
- Sahara 握手:Loader 上传 + PblHack 恢复,支持跳过(设备已在 Firehose 模式时)
- Firehose XML 引擎:通过 XML 命令读写扇区、擦除分区
- GPT 解析:主备 GPT 表 + 多 LUN(UFS)支持
- rawprogram.xml:解析并执行 QFIL 格式的刷机布局
- Sparse 镜像:自动检测并展开 Android sparse 镜像
- 分区操作:按名称 dump、flash、erase
- SHA256 校验:设备端 SHA256 摘要验证
- 跨平台:Windows (COM)、Linux (ttyUSB)、macOS
$ qedl devices
Devices (1)
Qualcomm HS-USB QDLoader 9008
├── VID:PID 05C6:9008
├── Location 1-1
└── Interfaces
└── COM3 EDL Qualcomm HS-USB QDLoader 9008 05C6:9008
$ qedl gpt
32 partitions:
boot LBA 131072 - 2097151 1.0 GiB LUN 0
system LBA 2097152 - 25165823 11.0 GiB LUN 0
userdata LBA 25165824 - 121775103 46.0 GiB LUN 0
$ qedl dump boot boot.img
[OK] dumped boot (4.0 MiB) to "boot.img" @ 2.3 MB/s
# 安装
cargo install qedl-cli
# 列出设备
qedl devices
# 导出分区
qedl dump boot boot.img
# 刷入分区
qedl write boot boot.img
# 从 rawprogram.xml 刷机
qedl flash rawprogram0.xml --image-dir ./images
# 重启设备
qedl rebootcargo install qedl-cli- Rust 2024 edition
- Windows: 需要 Qualcomm USB 驱动
use qedl::QedlClient;
use std::path::Path;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = QedlClient::builder()
.port("COM3")
.loader("prog_firehose.mbn")
.build();
client.init().await?;
// 列出分区
for p in client.partitions() {
println!("{}: LUN {} LBA {}-{}", p.name, p.physical_partition, p.first_lba, p.last_lba);
}
// Dump 分区
client.dump("boot", "boot.img").await?;
// 写入分区
client.write("boot", Path::new("boot.img")).await?;
// 擦除分区
client.erase("userdata", true, qedl::EraseMethod::WriteZero).await?;
// 重启
client.reboot().await?;
Ok(())
}| 命令 | 说明 |
|---|---|
qedl devices |
列出 EDL/DIAG 设备 |
qedl info |
设备信息 |
qedl gpt |
打印 GPT 分区表 |
qedl dump <分区> <文件> |
导出分区(-r 断点续传) |
qedl read <分区> <文件> |
dump 的别名 |
qedl dump-partitions |
导出所有分区(-o 指定目录) |
qedl write <分区> <文件> |
写入分区 |
qedl erase <分区> |
擦除分区(--native-erase 使用原生命令) |
qedl flash <rawprogram> [patch] |
从 XML 刷机(--image-dir 指定目录) |
qedl verify <分区> <文件> |
SHA256 校验 |
qedl peek <地址> <大小> |
读取物理内存(-o 输出到文件) |
qedl poke <地址> <数据> |
写入物理内存 |
qedl xml <XML> |
发送原始 XML(-f 从文件读取) |
qedl genxml <输出> |
从 GPT 生成 rawprogram.xml |
qedl reboot |
重启设备 |
| 配置项 | 默认值 | 说明 |
|---|---|---|
--port |
自动检测 | 串口名称(COM3, /dev/ttyUSB0) |
--serial |
— | 按序列号筛选设备 |
--loader |
— | Sahara loader 文件路径 |
--timeout |
45000 | 串口超时(毫秒) |
--dry-run |
false | 仅解析,跳过执行 |
-v / -vv |
info | debug / trace 日志 |
--wait-device |
— | 等待设备出现(可选超时秒数) |
--no-switch-edl |
false | 禁止自动 DIAG→EDL 切换 |
--force-mode |
— | 强制指定模式(edl/diag) |
qedl-rs/
├── qedl-core/ # 核心类型、错误定义、协议常量
├── qedl-transport/ # USB/串口传输抽象
├── qedl-sahara/ # Sahara 握手协议
├── qedl-firehose/ # Firehose XML 命令引擎
├── qedl-storage/ # GPT 解析 + 分区映射
├── qedl-image/ # rawprogram/patch XML + sparse 展开
├── qedl-job/ # 任务编排(flash/dump/erase)
├── qedl/ # 统一 SDK 门面
├── qedl-cli/ # CLI 二进制
├── docs/ # 架构文档
└── README.md
感谢所有为 qedl-rs 做出贡献的人!
- serialport-rs — Rust 串口库
- rusb — Rust USB 库