Skip to content

qualcomm/qdlrs

qdl - Sahara / Firehose tools, in Rust!

Qualcomm SoCs feature the Emergency Download Mode (EDL, widely known as '9008 mode'), a bootrom-initiated device flashing stack.

qdl provides a Rust implementation for the Sahara and Firehose protocols that are used to communicate with a device in that mode.

Contents

cli/ - A CLI tool used to communicate with devices in EDL mode
qdl/ - Sahara / Firehose library, with USB convenience wrappers
qramdump/ - Tool to receive memory dumps from a crashed device

Building

You're expected to have a recent installation of Rust. You can acquire one with rustup.
If you already have an older installation, try rustup update.

Run cargo build [--release] to build all executables within this repo. The binaries will appear in target/debug/ or target/release, respectively.

Use cargo run [--release] --bin <qdl-rs/qramdump> [-- args] to quickly build one of the programs from source and run it.

Running the programs

qdl-rs
Usage: qdl-rs [OPTIONS] --loader-path <FILE> --storage-type <emmc/ufs/nvme/nand> <COMMAND>

Commands:
  dump               Dump the entire storage
  dump-part          Dump a single partition
  flasher            Invoke the flasher
  erase              Erase a partition
  nop                Ask the device to do nothing, hopefully successfully
  overwrite-storage  Overwrite the storage physical partition contents with a raw image Similar to Flasher, but this one only takes a partition dump as input and performs no real validation on the input data
  peek               Peek at memory
  print-gpt          Print the GPT table
  reset              Restart the device
  set-bootable-part  Mark physical storage partition as bootable
  write              Write a partition
  help               Print this message or the help of the given subcommand(s)

Options:
      --backend <usb/serial>

      --bypass-storage
          Accept storage r/w operations, but make them never actually execute (useful for testing USB throughput)
  -d, --dev-path <DEV_PATH>
          E.g. COM4 on Windows
  -l, --loader-path <FILE>

      --hash-packets
          Validate every packet. Slow.
  -L, --phys-part-idx <PHYS_PART_IDX>
          e.g. LUN index for UFS [default: 0]
      --print-firehose-log

      --read-back-verify
          Every <program> operation is read back. VERY SLOW!
      --reset-mode <edl/off/system>
          WARNING: Will be deprecated in release v1.0.0 [default: edl]
      --serial-no <SERIAL_NO>

  -A, --skip-hello-wait
          Work around missing HELLO packet
  -s, --storage-type <emmc/ufs/nvme/nand>

      --sector-size <SECTOR_SIZE>

      --skip-storage-init
          Required for unprovisioned storage media.
      --verbose-sahara

      --verbose-firehose

  -h, --help
          Print help
  -V, --version
          Print version
qramdump
Usage: qramdump [OPTIONS] [REGIONS_TO_DUMP]...

Arguments:
  [REGIONS_TO_DUMP]...

Options:
      --backend <usb/serial>
  -d, --dev-path <DEV_PATH>    E.g. COM4 on Windows
      --serial-no <SERIAL_NO>
      --verbose-sahara
  -h, --help                   Print help
  -V, --version                Print version

Windows

You'll need to acquire an appropriate driver that exposes the device as a USB serial port, or use WinUSB.

Serial is used as the default backend on this platform.

Loader filename on newer platforms

Some newer platforms (e.g. SM8750) require that a file called xbl_s_devprg_ns.melf is used instead of prog_firehose_ddr.elf. This change may be opaque to you if the file has been renamed as part of the binary delivery process.

LUN handling

Due to how the protocol is constructed, particularly when interfacing with UFS, you must specify the LUN (physical storage partition) index on which you want to operate. This does not concern the flasher command (rawproramN.xml files include that information) and operations that aren't storage-related (e.g. peek or nop).

Common usage examples

Flash a full META image

Example with UFS as primary storage, reboots to OS after flashing ends

qdl-rs -l prog_firehose_ddr.elf -s ufs --reset-mode system flasher -p rawprogram*.xml -x patch*.xml

# NOTE: qdl-rs will flash anything you pass as a parameter. Some METAs ship a number of rawprogram0_foo.xml
# files which may be undesirable (e.g. _WIPE_GPT). You can filter those out with e.g.:
find /path/to/build/ -regex '.*/rawprogram[0-9]+\.xml$'
Reboot the device back to the OS
qdl-rs -l prog_firehose_ddr.elf -s ufs reset system
Dump the entire physical storage partition (e.g. LUN)
qdl-rs -l prog_firehose_ddr.elf -s ufs --phys-part-idx 2 dump -o lun2/
Fetch a single partition from LUN2
qdl-rs -l prog_firehose_ddr.elf -s ufs --phys-part-idx 2 dump-part EFI
Overwrite a single partition on LUN0
qdl-rs -l prog_firehose_ddr.elf -s ufs --phys-part-idx 0 write boot boot.img
Print out the partition table on LUN4
qdl-rs -l prog_firehose_ddr.elf -s ufs --phys-part-idx 4 print-gpt
Overwrite the entirety of LUN7 (VERY dangerous, may remove device-unique data)
qdl-rs -l prog_firehose_ddr.elf -s ufs --phys-part-idx 7 overwrite-storage lun7_dump.img
Erase a partition on eMMC (VERY dangerous, may remove device-unique data)
qdl-rs -l prog_firehose_ddr.elf -s emmc erase boot
Set LUN2 as bootable (i.e. containing xbl)
qdl-rs -l prog_firehose_ddr.elf -s ufs set-bootable-part 2

Documentation

Run cargo doc --open to generate and open the latest rustdoc. Learn more here.

Contributing

See CONTRIBUTING.md. Your code is expected to pass cargo fmt and cargo clippy checks - the CI will be on the lookout for that.

License

See the LICENSE file.

Credits

About

Device flashing utility and library

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages