Following up here, I recently learned how to sign a binary using publicly available resources.
WARNING The following can jeopardize your target so be careful.
- Locate and backup the existing firmware. On my rubikpi the DSP firmware files are here: /usr/lib/firmware/updates/qcom/qcs6490:
cdsp.b00 cdsp.b01 cdsp.b02 cdsp.b03 cdsp.b04 cdsp.b05 cdsp.b06
cdsp.b07 cdsp.b08 cdsp.b09 cdsp.b10 cdsp.b11 cdsp.b12 cdsp.b13
cdsp.b14 cdsp.b15 cdsp.mdt
.section .entry, "awx", @progbits
r0 = #0
1:
r0 = add(r0, #1)
memw (##0x88f01000) = r0
jump 1b
Makefile might might contain a rule like this to build:
cdsp.elf: main.S Makefile
hexagon-clang -mv68 main.S -nostartfiles \
-Wl,-Ttext,0x88f00000 \
-Wl,-entry,0x88f00000 \
-o $@
Notice the start address, 0x88f00000. It is critical that you verify this matches with the original cdsp.mdt in the firmware directory, use readelf -h and verify the Entry point address matches.
cdsp.mdt: cdsp.elf
../qtestsign/qtestsign.py -v 6 cdsp cdsp.elf -o cdsp.mdt
At this point you have a program that will increment a value stored at 0x88f01000. Once copied to the target you can use devmem2 to view the memory. Because this program does not respond the way the default firmware does the kernel will disable the DSP after a few seconds, to prevent this you must tweak the host kernel.
Assume you have the kernel sources and are comfortable rebuilding and installing your own kernel, locate qcom_q6v5.c and the function qcom_q6v5_wait_for_start. Just return 0 instead. The change would resemble this:
int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout)
{
/**
* This will allow the remote processor to continue to run.
* Non-standard software may not correctly signal back.
**/
return 0;
int ret;
ret = wait_for_completion_timeout(&q6v5->start_done, timeout);
See: Comparing rubikpi-ai:main...atx0x200:hexagon · rubikpi-ai/linux · GitHub
Once you have control of the DSP you are now free to learn and destabilize your target all you want. Take a look at the documentation: https://docs.qualcomm.com/doc/80-N2040-50/80-N2040-50_REV_AA_Qualcomm_Hexagon_V69_ProgrammerS_Reference_Manual.pdf
Check out chapter 11.9 for the system insns, these are monitor mode system instructions that will be important if you want to really dig into the low-level DSP programming.
Another interesting resource is this: GitHub - qualcomm/hexagon-hypervisor: Hexagon Hypervisor (AKA h2) is a light weight OS / Hypervisor for the Qualcomm Hexagon processor family · GitHub
Building the hypervisor to run on the RubikPi would be a fun and interesting project but will require some finesse.