Skip to content

system/nxinit: Give the builtin list to the kernel in a protected build. - #3907

Merged
acassis merged 1 commit into
apache:masterfrom
casaroli:nxinit-protected-builtins
Oct 25, 2026
Merged

acassis merged 1 commit into
apache:masterfrom
casaroli:nxinit-protected-builtins

Conversation

@casaroli

Copy link
Copy Markdown
Contributor

Summary

In a protected build the kernel cannot read the list of builtin applications in user space. The binfmt builtin loader uses its own copy of the list, which user space must set with boardctl(BOARDIOC_BUILTINS). NSH starts a builtin with task_spawn() and does not use the loader, so it never needed this. nxinit starts each service with posix_spawnp(), which goes through the loader, so in a protected build every builtin service fails with ENOENT.

esp32s3-devkit:knsh uses nxinit as init and never gets a shell:

Error Starting service 'console': 2

init_main() now gives the list to the kernel first, when CONFIG_BUILD_PROTECTED, CONFIG_BUILTIN and CONFIG_BOARDCTL are set.

Impact

nxinit in protected builds only. Flat and kernel builds do not compile the new code.

Testing

ESP32-S3-DevKitC with an ESP32-S3-WROOM-2-N32R8V (esp32s3-devkit:knsh, protected build, stock defconfig with nxinit as init, plus CONFIG_TESTING_OSTEST), nuttx master:

apps master this PR
boot Error Starting service 'console': 2 in a loop, no shell nxinit starts sh, NSH prompt
ostest (no shell) status 0

tools/checkpatch.sh -c -u -m -g passes.

In a protected build the kernel cannot read the list of builtin
applications in user space: the binfmt builtin loader uses its own
copy, which user space must set with boardctl(BOARDIOC_BUILTINS).  NSH
starts a builtin without the loader, so it never needed this, but
nxinit starts each service with posix_spawnp().  esp32s3-devkit:knsh,
which uses nxinit as init, therefore never got a shell:

  Error Starting service 'console': 2

init_main() now gives the list to the kernel first.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>

@cederom cederom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @casaroli :-)

@JianyuWang0623 @linguini1 @michallenc @FelipeMdeO could you please take a look?

@JianyuWang0623

Copy link
Copy Markdown
Contributor

Thank you @casaroli :-)

@JianyuWang0623 @linguini1 @michallenc @FelipeMdeO could you please take a look?

@cederom @casaroli

LGTM, good catch, thank you!

This reminds me that a set of changes from @anjiahao1 (with a follow-up fix from @yeungao) addresses the same problem on the kernel side: the protected kernel reads the builtin list directly through struct userspace_s, so no userspace call to BOARDIOC_BUILTINS is needed. I've opened a PR for it: apache/nuttx#20964

@FelipeMdeO

Copy link
Copy Markdown
Contributor

Congratulations Casaroli.

@acassis
acassis merged commit d9454d8 into apache:master Oct 25, 2026
34 of 40 checks passed
@JianyuWang0623

Copy link
Copy Markdown
Contributor

@casaroli Thanks again for tracking this down! The NuttX-side fix has now been merged: apache/nuttx#20964. The protected kernel now reads the builtin list directly through struct userspace_s, and BOARDIOC_BUILTINS has been removed.

I had a similar idea earlier (#3821), but with the kernel change in place this PR no longer seems necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants