A modern, user-friendly tool for interacting with Qualcomm devices in Emergency Download (EDL) mode.
Built with .NET, edl-ng provides tools for both Sahara and Firehose protocols, enabling device flashing, partition management, and low-level device interaction.
- Cross-Platform: Designed to run on Windows, Linux, and macOS with a single executable.
- Sahara Protocol Support:
- Upload Firehose programmers (
.elffiles). - Device information retrieval (Serial Number, HWID, RKH).
- Collect 64-bit crash dumps from devices in Sahara MemoryDebug mode (normally USB PID
0x900E).
- Upload Firehose programmers (
- Firehose Protocol Support:
- Automatic Firehose configuration.
- GPT Management: Print GUID Partition Table.
- Partition Operations:
- Read partition to a file.
- Write file to a partition.
- Automatic LUN scanning to find partitions.
- Sector Operations:
- Read raw sectors to a file.
- Write file to raw sectors.
- Device Control: Reset or power off the device.
- Get detailed storage information (sector size, LUN count).
- Flexible Device Detection:
- Specify USB VID/PID.
- Uses the native Windows QDLoader COM interface or LibUsbDotNet.
- Linux and macOS use libusb exclusively; serial-port devices are not supported on those platforms.
- Configurable:
- Specify memory type (UFS, eMMC/SD, NVMe, SPINOR etc.).
- Set maximum payload size for Firehose.
- Adjust logging levels.
edl-ng can be downloaded from:
- Releases
- Arch Linux CN repo [Maintainer = @Cryolitia]
The general command structure is:
edl-ng [global-options] <command> [command-options-and-arguments]
Run edl-ng --help for a full list of commands and options, or refer to the specific command help using edl-ng <command> --help.
upload-loader: Connects in Sahara mode and uploads the specified Firehose loader. (e.g., qsahara_device_programmer.xml, xbl_s_devprg_ns.melf or prog_firehose_*.elf)ramdump [-o <directory>] [segment-filter]: Collects Sahara 64-bit crashdump regions. The output directory defaults to the current directory.printgpt: Reads and prints the GPT from the device.read-part <partition_name> <filename>: Reads a partition to a file.read-sector <start_sector> <num_sectors> <filename>: Reads sectors to a file.read-lun <filename>: Reads the entire LUN (all sectors) to a file.dump-rawprogram <dump_save_dir>: Reads all partitions to individual files from a certain LUN and generates rawprogram XML file.write-part <partition_name> <filename>: Writes data from a file to a partition.write-sector <start_sector> <filename>: Writes data from a file to sectors.erase-part <partition_name>: Erases a partition by name from the device.erase-sector <start_sector> <sectors>: Erases a specified number of sectors from a given LUN and start LBA.provision <xmlfile>: Performs UFS provisioning using an XML file.rawprogram <xmlfile_patterns>: Processes rawprogramN.xml and patchN.xml files for flashing.reset: Resets or powers off the device.--mode <reset|off|edl>: Reset mode (default:reset).--delay <seconds>: Delay before executing power command.
-
Flash a flat build to device using rawprogram XML files
edl-ng --loader prog_firehose_ddr.elf --memory UFS rawprogram rawprogram*.xml patch*.xml
-
Collect all regions from a
0x900Ecrashdump device:edl-ng ramdump -o ./ramdump
To collect selected regions, pass a comma-separated, case-sensitive filter supporting
*and?:edl-ng ramdump -o ./ramdump OCIMEM,CODERAM,DDR*Each region is written to
<filename>.partialand replaces the final file only after the region is complete. A failed transfer leaves the partial file for diagnosis while preserving any existing completed dump. KELF is downloaded as an ordinary region, butedl-ngdoes not currently parse it or generateminidump.elf. The command searches for PID0x900Eby default; use the global--vid/--pidoptions for targets using different identifiers. A Firehose loader is not required for ramdump collection. -
Print GPT from LUN 0 (UFS memory):
edl-ng --loader prog_firehose_ddr.elf --memory UFS printgpt --lun 0
-
Read the 'modem' partition from any LUN to
modem.bin:edl-ng --loader prog_firehose_ddr.elf read-part modem modem.bin
-
Write
modem.binto the 'modem' partition found in any LUN:edl-ng --loader prog_firehose_ddr.elf write-part modem modem.bin
-
Read the entire LUN 0 to
lun0.bin:edl-ng --loader prog_firehose_ddr.elf --memory UFS read-lun lun0.bin --lun 0
-
Dump all partitions from LUN 0 to directory and generate rawprogram XML:
edl-ng --loader prog_firehose_ddr.elf --memory UFS dump-rawprogram ./partitions --lun 0
This will create partition files (e.g.,
system.bin,vendor.bin), GPT files (gpt_main0.bin,gpt_backup0.bin), andrawprogram0.xml. -
Write
lun0.binto the entire LUN 0:edl-ng --loader prog_firehose_ddr.elf --memory UFS write-sector 0 lun0.bin --lun 0
-
Reboot the device:
edl-ng --loader prog_firehose_ddr.elf reset
- Snapdragon 835 (MSM8998)
- Dragonwing QCS6490
- Dragonwing QCS8550
- Snapdragon X Elite (SC8380)
SoCs older than MSM8998 are not tested and may not yet be supported.
Devices with vendor customized DevPrg may not be supported as well.
- .NET 9 SDK (no need to install .NET runtime if using pre-built binaries).
- Qualcomm USB Drivers:
- Windows: Both Qualcomm® USB Driver (QUD) and WinUSB driver (Zadig) are supported.
- Linux/macOS: Only
libusbis supported. You may also need to configure udev rules on Linux to allow user access to the device.
- Firehose Programmer: An appropriate
.elfprogrammer file for your specific device (e.g.,prog_firehose_*.elforxbl_s_devprg_ns.melf).
-
Clone the repository.
-
Ensure you have the .NET 9 SDK installed.
-
Navigate to the solution directory (
/) and run:dotnet build
-
The executable
edl-ngwill be located inQCEDL.CLI/bin/<Configuration>/net9.0/<Platform>/. For example:QCEDL.CLI/bin/Debug/net9.0/win-x64/edl-ng.
This project is licensed under the MIT license.
This project is inspired by gus33000/QCEDL.NET and bkerler/edl.