29 Commits

Author SHA1 Message Date
Bjorn Andersson
ce6faee104 Merge pull request #118 from igoropaniuk/readme_update
Readme update + cosmetic improvements
2025-06-26 15:32:35 -05:00
Maxim Paymushkin
02c008adfd add support sparse attribute
Signed-off-by: Maxim Paymushkin <maxim.paymushkin.development@gmail.com>
2025-06-26 13:19:21 +02:00
Igor Opaniuk
228ab33af8 make: simplify check-cached target
Simplify "check-cached" target, as the previous sometimes
provides wrong results.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2025-06-25 15:27:35 +02:00
Igor Opaniuk
d48d852ca2 makefile: add check and check-cached targets
`check` target runs checkpatch.pl on all sources files.
`check-cached` target runs checkpatch.pl on staged changes.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2025-06-24 20:15:20 +02:00
Igor Opaniuk
6c0fbcce08 tests: add initial test set
Add tests make target and a simple test that executes qdl in dry-run mode
for a synthetic reference FLAT build with VIP table generation.

The FLAT build contains:
- patch0.xml
- patch1.xml
- rawprogram0.xml
- rawprogram1.xml

All binaries that these XML files point to are filled with zeros, generated
during github action  execution.

Tests ensures that the table is generated correctly by comparing
calculated and expected SHA256 hashes of DigestToSign.bin file.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2025-06-20 11:51:49 +02:00
Igor Opaniuk
4ed250c184 qdl: add support for vip table of digests generation
Add support for Digests Table generation for Validated Image
Programming (VIP), which is activated when Secure Boot is enabled
on the target. VIP controls which packets are allowed to be issued to
the target. Controlling the packets that can be sent to the target is
done through hashing. The target applies a hashing function to all
received data, comparing the resulting hash digest against an existing
digest table in memory. If the calculated hash digest matches the next
entry in the table, the packet (data or command) is accepted; otherwise,
the packet is rejected, and the target halts.

This change introduces logic for VIP table generation.
In the current VIP design the first signed hash table can be a
maximum of 8 KB. Considering that it must be in MBN format, and in
addition to the raw hash table, it also includes an MBN header,
a signature, and certificates, the number of hash digests it can
contain is limited to 54 hashes (a 40-byte MBN header +
a 1696-byte hash table + a 256-byte signature + 6144 bytes of certificates).
All hashes left are stored in the additional ChainedTableOfDigests<n>.bin
files.

To generate table of digests run QDL with --create-digests param,
providing a path to store VIP tables.

As a result 3 types of files are generated:
- DIGEST_TABLE.bin - contains the SHA256 table of digests for all firehose
  packets to be sent to the target. It is an intermediary table and is
  used only for the subsequent generation of "DigestsToSign.bin" and
  "ChainedTableOfDigests.bin" files. It is not used by QDL for VIP
  programming.

- DigestsToSign.bin - first 53 digests + digest of ChainedTableOfDigests.bin.
  This file has to be converted to MBN format and then signed with sectools:

  $ sectools mbn-tool generate --data DigestsToSign.bin --mbn-version 6
    --outfile DigestsToSign.bin.mbn
  $ sectools secure-image --sign DigestsToSign.bin.mbn --image-id=VIP

  Please check the security profile for your SoC to determine which version of
  the MBN format should be used.

- ChainedTableOfDigests<n>.bin - contains left digests, split on
  multiple files with 255 digests + appended hash of next table.

For example, for 400 packets supposed to be sent to the target, these files
will be generated (all digests are 32 bytes in size):

DIGEST_TABLE.bin
 _____________
| Digest 0    |
| Digest 1    |
| etc.        |
|             |
| Digest 399  |
|_____________|

DigestsTableToSign.bin  ChainedTableOfDigests0.bin  ChainedTableOfDigests1.bin
 ___________________       ___________________       ____________
| Digest 0          |     | Digest 53         |     | Digest 308 |
| Digest 1          |     | Digest 54         |     | Digest 309 |
| etc.              |     | etc.              |     | etc.       |
| Digest 52         |     | Digest 307        |     | Digest 399 |
| Next table digest |     | Next table digest |     |____________|
|___________________|     |___________________|

When QDL is executed with --debug parameter, it will also report
Firehose packet SHA-256 hashes, for example:

FIREHOSE WRITE: <?xml version="1.0"?>
<data><patch SECTOR_SIZE_IN_BYTES="4096" byte_offset="72" filename="DISK"
physical_partition_number="5" size_in_bytes="8"
start_sector="NUM_DISK_SECTORS-1" value="NUM_DISK_SECTORS-5."/></data>

FIREHOSE PACKET SHA256: a27b1459042ea36f654c5eed795730bf73ce37ce5e92e204fe06833e5e5e1749

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2025-06-10 20:36:52 +02:00
Igor Opaniuk
672abb1e81 qdl: add support for dry run execution
This mode assists in validating the `rawprogram_.xml` and `patch_.xml`
files, as well as the Firehose commands that are expected to be sent
to the Firehose programmer.

Dry run implementation is also expected to be extended for
the Digests Table generation required for Firehose Validated Image
Programming (VIP).

Example of usage:
$ qdl --dry-run --serial=0AA94EFD --debug prog_firehose_ddr.elf rawprogram*.xml patch*.xml
qdl version v2.1-24-g30ac3a8-dirty
This is a dry-run execution of QDL. No actual flashing has been performed
waiting for programmer...
FIREHOSE WRITE: <?xml version="1.0"?>
<data><configure MemoryName="ufs" MaxPayloadSizeToTargetInBytes="1048576"
verbose="0" ZLPAwareHost="1" SkipStorageInit="0"/></data>

FIREHOSE WRITE: <?xml version="1.0"?>
<data><configure MemoryName="ufs" MaxPayloadSizeToTargetInBytes="0"
verbose="0" ZLPAwareHost="1" SkipStorageInit="0"/></data>

accepted max payload size: 0
FIREHOSE WRITE: <?xml version="1.0"?>
<data><program SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="131072"
physical_partition_number="0" start_sector="6" filename="efi.bin"/></data>

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2025-05-15 02:41:08 +02:00
Igor Opaniuk
f066304676 qdl: decouple transport logic
Decouple the flashing logic from the underlying type of communication.
This is needed for introducing simulation mode, where no real flashing is
performed, but firehose packets are used for other tasks, like
VIP table generation.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2025-05-15 02:41:08 +02:00
Julien Vanier
b3dccab6a6 Add Windows compatibility
Make build compatible with Windows using MSYS2 MINGW64 compiler. Add a small compatibility file for functions that don't exist in MINGW64.

Signed-off-by: Julien Vanier <jvanier@gmail.com>
2025-05-02 19:00:09 -04:00
Dmitry Baryshkov
ab17b2e78d make: don't rebuild util.o (and dependencies) unnecessary
Using fake target name forces make to rebuild all targets that depend on
it. Properly specify version.h as a target name and use double-colon to
let make know that it's a special build target.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
2025-03-19 16:02:11 +02:00
Christopher Obbard
cfdb938111 Use provided VERSION argument before calling git
In some environments where git isn't present (e.g. in Debian pbuilder),
building qdl fails due. Fix the order such that we check if VERSION is
provided first & use that, only if VERSION is not provided then call
git directly to get the version.

Signed-off-by: Christopher Obbard <christopher.obbard@linaro.org>
2025-02-07 14:18:01 -06:00
Christopher Obbard
21966c61d0 Use VERSION instead of GITREF
The variable name VERSION is more descriptive of the code than GITREF.
Use VERSION instead.

Signed-off-by: Christopher Obbard <christopher.obbard@linaro.org>
2025-02-07 14:18:01 -06:00
Christopher Obbard
2872a8ea62 Fix version.h generation
Currently the build fails when parallelised with:

  make[1]: *** No rule to make target 'version.h', needed by 'util.o'.  Stop.

Fix the name of the Makefile dependency to fix the build error.

Fixes: https://github.com/linux-msm/qdl/issues/91
Closes: https://github.com/linux-msm/qdl/pull/92
Signed-off-by: Christopher Obbard <christopher.obbard@linaro.org>
2025-02-07 14:18:01 -06:00
Nicolas Dechesne
ad320a1a66 version: set to 'unknown-version' if unable to use git describe
If for any reasons git describe does not work (git not installed, or
not running from a git workspace), set VERSION to unknown-version.

Signed-off-by: Nicolas Dechesne <nicolas.dechesne@oss.qualcomm.com>
2025-01-21 11:11:13 -06:00
Nicolas Dechesne
cc584d4560 Add infrastructure to support version information
In order to implement a proper versioning scheme, let's generate a
version.h file that defines VERSION variable built from git
workspace. The version format will be

v<MAJOR>.<MINOR>-<COMMIT##>-<SHA1>

Where:
* MAJOR and MINOR are from the most recent tag
* COMMIT## is the number of commits since last tag, to ensure
  incremental numbering
* SHA1 is an abbreviated representation of the actual commit SHA.

This requires building from a git workspace, with we are effectively
calling 'git describe' during the build.

We then define print_version() utility function to be used by all
programs.

Ensure that util.c depends on version.h and that we only update
version.h timestamps when the version actually changes to avoid
unnecessary rebuilds.

Signed-off-by: Nicolas Dechesne <nicolas.dechesne@oss.qualcomm.com>
2025-01-21 11:11:13 -06:00
Bjorn Andersson
0e08e852bf ux: Introduce user experience wrappers
Rather than sprinkling the user experience decisions across the
implementation with prints to stdout, stderr, conditional checks for
qdl_debug etc, consolidate these into a single set of ux wrappers.

Transition all callers of printf() and fprintf() to these new wrappers,
without changing the level of content of the printouts.

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
2024-12-20 11:18:34 -06:00
Collin
a1cd535439 qdl: Add support for <read> operations
Being able to read the content of the flash is useful for e.g. making
backups or for testing purposes, add support for a new type of XML
containing <read> tags and execute these operations after
flashing and patching.

[bjorn: Rebased on master, updated commit message, moved read_op_exec after patching]
Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2024-06-10 10:33:05 -05:00
Ricardo Salveti
fac09b2980 Makefile: prefer append on CFLAGS / LDFLAGS
Append allows an external build system to pass custom cflags/ldflags
to the local build system (make).

Useful with Yocto / OE as additional options can be given besides what
is set with a force set in the Makefile.

Signed-off-by: Ricardo Salveti <ricardo@foundries.io>
2024-05-28 10:49:55 -05:00
Bjorn Andersson
37b0d0cf69 usb: Replace USBDEVFS interface with libusb
In order to support selecting board based on serial number the iProduct
field needs to be inspected, with the hand-rolled parsing of the USB
descriptors this becomes cumbersome.

Furthermore the direct use of Linux's USBDEVFS creats an unnecessary
dependency on the host OS being Linux.

It's unclear why libusb wasn't choosen in the first place, perhaps it
relates to the faint memory of 0.1 vs 1.0 packaging issues?

Move to libusb-1.0 in order to resolve these issues, as well as clean up
the code a bit.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2024-05-10 17:57:18 +02:00
Bjorn Andersson
2fd923ec97 qdl: Add ramdump support
Expose the newly introduce Sahara implementation for ramdump support to
the user, by introducing the qdl-ramdump utility.

The -o option can be used to specify the output directory, where files
will be stored.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2024-05-08 18:29:38 +02:00
Bjorn Andersson
5b69b112f5 qdl: Extract USB accessor functions
In preparation for the introduction of a new ramdump utility, extract
out the USB functions.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2024-05-08 18:29:38 +02:00
Bjorn Andersson
a10d2bf57b Makefile: Generate compile_commands.json
Introduce a make target for generating compile_commands.json to feed
clangd and the Language Server Protocol, to gain better editor
integration.

Add the relevant files to .gitignore.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2024-05-08 18:29:38 +02:00
Daniel Gimpelevich
1acf511839 Install ks utility 2023-02-21 04:55:09 +00:00
Jeffrey Hugo
bdcf93b4a3 Add ks utility
ks (short for kickstart) is a utility which uses sahara to load images
from the host to a device.  This is intended for "flashless boot"
devices like the Qualcomm Cloud AI 100 which rely on obtaining the
runtime firmware from the host instead of storing it on device.

While ks uses sahara, like qdl, it is different enough that a separate
utility is justified.  ks does not need USB support, instead opting for
simple open()/read()/write() operations.  ks does not need firehose.
The set of program arguments that ks needs is vastly different than the
set that qdl supports.

This initial implementation of ks defines two arguments.  Both are
required, but the image specifier argument can be specified more than
one.

A sample invocation -

ks -p /dev/mhi0_QAIC_SAHARA -s 1:/opt/qti-aic/firmware/fw1.bin -s 2:/opt/qti-aic/firmware/fw2.bin

In this example, ks is instructed to use the /dev/mhi0_QAIC_SAHARA
device node file as the "port" which the device is using for the sahara
protocol.  /opt/qti-aic/firmware/fw1.bin is mapped to id 1, and
/opt/qti-aic/firmware/fw2.bin is mapped to id 2.  If the device requests
image id 1, ks will attempt to open and read
/opt/qti-aic/firmware/fw1.bin to send to the device.  Note that
/opt/qti-aic/firmware/fw1.bin does not need to exist on the filesystem.
If ks cannot access the file (perhaps because it does not exist), then
the device will determine the next action.  This is useful for setting
up a single command in a udev rule that can handle multiple
configurations, such as an optional DDR training process.

Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
2023-01-31 12:35:20 -06:00
Bjorn Andersson
0fcf944ab5 makefile: Use pkg-config instead of xml2-config
Per user request, use pkg-config instead of xml2-config when generating
cflags and ldflags.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
2021-11-10 09:44:50 -06:00