Skip to content

Stub support for fwrite, fremove, fclose_fd, fopen_with_env_fd - #21

Draft
z3ntu wants to merge 9 commits into
linux-msm:mainfrom
z3ntu:apps_std_fwrite
Draft

z3ntu wants to merge 9 commits into
linux-msm:mainfrom
z3ntu:apps_std_fwrite

Conversation

@z3ntu

@z3ntu z3ntu commented Mar 20, 2026 •

Copy link
Copy Markdown

Initial feedback welcome, the first commits can be applied in my opinion (see #22), not sure how we want to do the later commits.

For fopen_with_env_fd (or the fopen_fd function that I haven't implemented) I'm honestly not sure what the fd should be or would be used for. It's the same data type as the "fd" for the other functions (e.g. fread) but seems for a different purpose? Not quite sure, but the ADSP is happy enough getting random stub data there.

Also in general, not sure how to handle a mutable version of hexagonrpc, I know rmtfs has a similar issue but there it keeps a copy of the original file in-memory or something, but it's obviously more difficult for a whole file system. Maybe copy the read-only version from /usr/share/qcom to /var/lib/hexagonrpc/ and modify it there only, depending on what's requested?

Log on Milos (Fairphone (Gen. 6)), initializing the sensors far enough to work with iio-sensor-proxy:
output.txt

Fixes #19

This is good to print for completeness, and can be useful when extending
fopen to not just allow read operations.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Make sure that the message is useful and doesn't just print a hex number
like "1f050100".

"Unexpected buffer count for method 31: 1f050100 (in: 5 vs 2, out: 1 vs 1)"
is a much more descriptive and helpful error.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
EditorConfig is a file format and collection of text editor plugins for
maintaining consistent coding styles between different editors and IDEs.

Add a config for hexagonrpc with the preferred indentation style, and
some other settings.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
@z3ntu
z3ntu force-pushed the apps_std_fwrite branch from d98488b to 9f98797 Compare March 20, 2026 16:11
@flamingradian

Copy link
Copy Markdown
Collaborator

For fopen_with_env_fd (or the fopen_fd function that I haven't implemented) I'm honestly not sure what the fd should be or would be used for. It's the same data type as the "fd" for the other functions (e.g. fread) but seems for a different purpose? Not quite sure, but the ADSP is happy enough getting random stub data there.

I think it's just the same function with a different data type for the file descriptor, where it's int fd for some functions and others have a apps_std_FILE sin.

Also in general, not sure how to handle a mutable version of hexagonrpc, I know rmtfs has a similar issue but there it keeps a copy of the original file in-memory or something, but it's obviously more difficult for a whole file system. Maybe copy the read-only version from /usr/share/qcom to /var/lib/hexagonrpc/ and modify it there only, depending on what's requested?

I don't even see the use case for writing to any backing files and persistently storing them, beyond offloading the JSON config-to-registry conversions.

@z3ntu

z3ntu commented Mar 24, 2026

Copy link
Copy Markdown
Author

Where do you suggest we store the files temporarily then? Just in RAM, in /tmp, or some other way?

@lumag

lumag commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Where do you suggest we store the files temporarily then? Just in RAM, in /tmp, or some other way?

I'd say, /var/hexagon-dsp or something similar.

@z3ntu

z3ntu commented Mar 25, 2026

Copy link
Copy Markdown
Author

Do you have an idea how to resolve the situation that we probably want to continue to have the read-only /usr/share/qcom/ but still letting hexagonrpcd delete files? Do we just overlay /var/hexagon-dsp/ on top of /usr/share/qcom/ and not support deleting files that are provided as part of /usr/share/qcom/? So only files hexagonrpcd has created it can delete again? For the start I think that would be a decent solution.

Open file read-only:

  1. Check /var/hexagon-dsp/$file
  2. If not exists, check /usr/share/qcom/$file

Open file read-write:

  1. Check /var/hexagon-dsp/$file
  2. If not exists, copy from /usr/share/qcom/$file to /var/hexagon-dsp/$file, open that one.

Delete file:

  1. Delete /var/hexagon-dsp/$file if exists. If that doesn't exist, return an error (it may exist in /usr/share/qcom/$file but we just pretend that one doesn't exist for delete use case)

If we wanted to support deleting a file that's originally provided in /usr/share/qcom/ we may either needed to keep track of deleted files so we can pretend they've been deleted. Or we copy the entire /usr/share/qcom/ to /var/hexagon-dsp/ and only work on that, that way we could delete files in that view

giodotblue added a commit to giodotblue/distribution that referenced this pull request May 15, 2026
NOTE: This package is using the tree from this PR: linux-msm/hexagonrpc#21
Without this PR (by @z3ntu), newer Snapdragon chips won't work (as there are missing calls)

This package comes with the hexagonrpcd service which works alongside libssc

Both this service and the data files in /usr/share/qcom are required for the Qualcomm SSC sensors to work.

Signed-off-by: Gianni Spadoni <me@gio.blue>
giodotblue added a commit to giodotblue/distribution that referenced this pull request May 17, 2026
NOTE: This package is using the tree from this PR: linux-msm/hexagonrpc#21
Without this PR (by @z3ntu), newer Snapdragon chips won't work (as there are missing calls)

This package comes with the hexagonrpcd service which works alongside libssc

Both this service and the data files in /usr/share/qcom are required for the Qualcomm SSC sensors to work.

Signed-off-by: Gianni Spadoni <me@gio.blue>
giodotblue added a commit to giodotblue/distribution that referenced this pull request May 22, 2026
NOTE: This package is using the tree from this PR: linux-msm/hexagonrpc#21
Without this PR (by @z3ntu), newer Snapdragon chips won't work (as there are missing calls)

This package comes with the hexagonrpcd service which works alongside libssc

Both this service and the data files in /usr/share/qcom are required for the Qualcomm SSC sensors to work.

Signed-off-by: Gianni Spadoni <me@gio.blue>
giodotblue added a commit to giodotblue/distribution that referenced this pull request May 26, 2026
NOTE: This package is using the tree from this PR: linux-msm/hexagonrpc#21
Without this PR (by @z3ntu), newer Snapdragon chips won't work (as there are missing calls)

This package comes with the hexagonrpcd service which works alongside libssc

Both this service and the data files in /usr/share/qcom are required for the Qualcomm SSC sensors to work.

Signed-off-by: Gianni Spadoni <me@gio.blue>
giodotblue added a commit to giodotblue/distribution that referenced this pull request May 26, 2026
NOTE: This package is using the tree from this PR: linux-msm/hexagonrpc#21
Without this PR (by @z3ntu), newer Snapdragon chips won't work (as there are missing calls)

This package comes with the hexagonrpcd service which works alongside libssc

Both this service and the data files in /usr/share/qcom are required for the Qualcomm SSC sensors to work.

Signed-off-by: Gianni Spadoni <me@gio.blue>
@z3ntu

z3ntu commented May 27, 2026

Copy link
Copy Markdown
Author

@lumag ping, since we were talking about this :)

@lumag

lumag commented May 27, 2026

Copy link
Copy Markdown
Contributor

@z3ntu Okay. My rough guess:
I don't think that the firmware is going to write to or unlink the files that we currently have in /usr/share/qcom. If it does, just error out and return -ENOPERM and SCREAM to the logs about it (note: sensors registry file might be different here). For everything else, I think, just open the file at /var/hexagonrpcd. Let's first establish the case of the DSP doing something weird to the rootfs files.

@psacal

psacal commented Jun 3, 2026

Copy link
Copy Markdown

Confirmation from SC8280XP (Windows firmware)

I can confirm the method 5 signature (1, 1, 2, 0) on a different
platform — SC8280XP (Huawei MateBook E Go 2023), Windows-compiled
qcslpi8280.mbn.

DSP writes through method 5

My DSP writes "version=1" (9 bytes, not "version=3") through method
5, plus the same "DIR" marker. The stub should probably match both
version prefixes — different firmware revisions write different values.

Two config files control whether method 5 is triggered

This might explain why the issue hasn't surfaced on Android devices:

  • sns_reg.conf: Text-format (407 bytes, version=1) from Windows
    DriverStore → DSP initializes normally, never calls method 5.
    Sensors work with empty registry.

  • sns_reg.conf: JSON-format (2423 bytes) from Windows DriverData
    runtime copy → DSP enters an abnormal init path, repeatedly calls
    method 5, and also generates oversized messages.

  • sns_reg_version: If this file doesn't exist at startup, DSP
    calls method 5 to create it. On Android devices this file is
    pre-populated in the persist partition, so DSP never enters the write
    path. On Windows-firmware devices migrated to Linux, it's absent.

On our platform, using the correct text-format sns_reg.conf +
manually placing sns_reg_version + empty registry avoids all method 5
calls and sensors work immediately. But that's a workaround — the stub
approach in this PR is the right fix.

Sequence when method 5 is NULL (upstream)

stat(sns_reg_version) → ENOENT
  → method 5 fwrite("version=1") → NULL handler → AEE_EUNSUPPORTED
  → method 5 fwrite(temp.json)   → NULL handler → AEE_EUNSUPPORTED
  → retry loop → Broken pipe → DSP crash

Test results with stub fwrite

With a stub analogous to this PR (accept "version=1" and "DIR"
through method 5), all three sensors pass:

  • Light: TCS3701, ~408 lux
  • Accelerometer: T1000, Z≈9.78
  • Gyroscope: T1000, ~0.01 rad/s

Tested with libssc + ssc-bridge → uinput evdev.

Thanks for working on this!

@Drakulix

Copy link
Copy Markdown

The fwrite and fremove implementations from this branch are also enough to get hexagonrpcd working on the Ayaneo Pocket S2 - a SM8650 device - to expose the built-in accelerometer. The current release of hexagonrpcd instead leads to a DSP crash.

@flamingradian

Copy link
Copy Markdown
Collaborator

After !13, the format for method definitions will change. In hexagonrpcd/interface/apps_std.h, the method definitions are declared separately.

In hexagonrpcd/interface/apps_std.c, the arguments are specified by specifying the type instead of specifying the total count:
interface-conversion-example.c

(I would have put the example inline in a click-to-open if I could)

@z3ntu

z3ntu commented Aug 18, 2026 •

Copy link
Copy Markdown
Author

(correct link: #13)

Just a sidenote, I don't think I'll be able to work on this in the coming month for example, there's too many other things pending for me to do that have higher priority. But I'd definitely be happy to continue working on this, to get this to a state that can be merged.

FadyAckad added a commit to FadyAckad/hexagonrpc that referenced this pull request Sep 19, 2026
Implement the apps_std methods the sensor framework's registry initialisation calls (ids as in quic/fastrpc inc/apps_std.h: fopen 0, fwrite 5, fsync 23, fremove 24, ftrunc 32, frename 33; ids above 30 travel in the first primitive word), open w/a/+ modes read-write, and let fopen_with_env open an absolute name whatever search variable the DSP names. Refusing the first write (fremove, then fopen of the DIR marker for writing) made the X1E80100 firmware assert in sns_registry_sensor.c and take the whole ADSP down. Unlike the stubs proposed in pull request 21, the writes reach the files, so what the framework persists (its parsed registry, calibration) is there at the next start.

Link: linux-msm#19

Link: linux-msm#21
FadyAckad added a commit to FadyAckad/hexagonrpc that referenced this pull request Sep 19, 2026
…rsist exists

The framework writes /persist/sensors/registry/fstempfile and renames it into /persist/sensors/registry/registry, and it looks for sns_reg_version and parsed_file_list.csv next to the registry directory (it creates sns_reg_version through that temporary file when the file is missing). With DIR/sensors/persist/ present that directory backs the whole of /persist/sensors/registry, its registry/ subdirectory being the registry; without it the tree is as before.

Link: linux-msm#19

Link: linux-msm#21
FadyAckad added a commit to FadyAckad/hexagonrpc that referenced this pull request Sep 21, 2026
Implement the apps_std methods the sensor framework's registry initialisation calls (ids as in quic/fastrpc inc/apps_std.h: fopen 0, fwrite 5, fsync 23, fremove 24, ftrunc 32, frename 33; ids above 30 travel in the first primitive word), open w/a/+ modes read-write, and let fopen_with_env open an absolute name whatever search variable the DSP names. Refusing the first write (fremove, then fopen of the DIR marker for writing) made the X1E80100 firmware assert in sns_registry_sensor.c and take the whole ADSP down. Unlike the stubs proposed in pull request 21, the writes reach the files, so what the framework persists (its parsed registry, calibration) is there at the next start.

Link: linux-msm#19

Link: linux-msm#21
FadyAckad added a commit to FadyAckad/hexagonrpc that referenced this pull request Sep 21, 2026
…rsist exists

The framework writes /persist/sensors/registry/fstempfile and renames it into /persist/sensors/registry/registry, and it looks for sns_reg_version and parsed_file_list.csv next to the registry directory (it creates sns_reg_version through that temporary file when the file is missing). With DIR/sensors/persist/ present that directory backs the whole of /persist/sensors/registry, its registry/ subdirectory being the registry; without it the tree is as before.

Link: linux-msm#19

Link: linux-msm#21
FadyAckad added a commit to FadyAckad/hexagonrpc that referenced this pull request Sep 21, 2026
Implement the apps_std methods the sensor framework's registry initialisation calls (ids as in quic/fastrpc inc/apps_std.h: fopen 0, fwrite 5, fsync 23, fremove 24, ftrunc 32, frename 33; ids above 30 travel in the first primitive word), open w/a/+ modes read-write, and let fopen_with_env open an absolute name whatever search variable the DSP names. Refusing the first write (fremove, then fopen of the DIR marker for writing) made the X1E80100 firmware assert in sns_registry_sensor.c and take the whole ADSP down. Unlike the stubs proposed in pull request 21, the writes reach the files, so what the framework persists (its parsed registry, calibration) is there at the next start.

Link: linux-msm#19
Link: linux-msm#21
Signed-off-by: Fady <me@fadyackad.dev>
FadyAckad added a commit to FadyAckad/hexagonrpc that referenced this pull request Sep 21, 2026
…rsist exists

The framework writes /persist/sensors/registry/fstempfile and renames it into /persist/sensors/registry/registry, and it looks for sns_reg_version and parsed_file_list.csv next to the registry directory (it creates sns_reg_version through that temporary file when the file is missing). With DIR/sensors/persist/ present that directory backs the whole of /persist/sensors/registry, its registry/ subdirectory being the registry; without it the tree is as before.

Link: linux-msm#19
Link: linux-msm#21
Signed-off-by: Fady <me@fadyackad.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support opening files for writing

6 participants