boards/sim,qemu: switch all nsh defconfigs to nxinit entrypoint - #19984
boards/sim,qemu: switch all nsh defconfigs to nxinit entrypoint#19984JianyuWang0623 wants to merge 3 commits into
Conversation
98c3f7d to
edfdb17
Compare
|
6caf831 to
3b78f74
Compare
4edfa97 to
842c568
Compare
842c568 to
2b6eaa2
Compare
2b6eaa2 to
0b0c010
Compare
Switch every sim/sim/sim defconfig whose init entry point was nsh_main
(81 configs) to nxinit (init_main). nsh now runs as a "console sh"
service started by init.rc instead of being the top-level init task.
Each switched defconfig only gains the nxinit-essential keys (minimal
delta, regenerated so no unrelated options leak in):
- CONFIG_INIT_ENTRYPOINT="init_main"
- CONFIG_SYSTEM_NXINIT=y plus its Kconfig deps that were not already set:
CONFIG_EXPERIMENTAL, CONFIG_LIBC_EXECFUNCS, CONFIG_SCHED_CHILD_STATUS
(which depends on CONFIG_SCHED_HAVE_PARENT)
- CONFIG_ETC_ROMFS=y / CONFIG_FS_ROMFS=y to ship init.rc via ROMFS
No stack-size overrides are added: INIT_STACKSIZE and SYSTEM_NSH_STACKSIZE
keep their Kconfig defaults (DEFAULT_TASK_STACKSIZE).
Five configs (dynconns, module, module32, sotest, sotest32) had
CONFIG_BINFMT_DISABLE=y, which blocks CONFIG_LIBC_EXECFUNCS and thus
CONFIG_SYSTEM_NXINIT. Since nxinit spawns services via exec(), binfmt is
re-enabled in those five. They also enable CONFIG_LIBC_ENVPATH but did
not ship a /bin, so nxinit's posix_spawnp("sh") resolved via PATH and
failed with ENOENT ("Error Starting service 'console': 2"). Add
CONFIG_FS_BINFS=y and CONFIG_PATH_INITIAL="/bin" to those five so the
builtin apps are visible under /bin and the console service starts,
matching the working sim:nsh config.
citest additionally needed CONFIG_ETC_ROMFSDEVNO=1 (matching the 53
other sim configs that already set it to avoid the same collision):
sim_registerblockdevice() (arch/sim/src/sim/sim_blockdevice.c, called
from up_initialize() before any application task starts) unconditionally
registers a FAT ramdisk at /dev/ram0 whenever CONFIG_FS_FAT is set, and
citest is one of the few switched configs with CONFIG_FS_FAT=y that had
never overridden CONFIG_ETC_ROMFSDEVNO away from its Kconfig default of
0. With nxinit, romdisk_register() for /etc's ROMFS at that same minor
number then fails with -EEXIST and nxinit aborts with "Error Opening
/etc/init.d/init.rc" since it treats a missing init.rc as fatal;
nsh_main() silently tolerated the identical failure before this switch
(logs "init: open failed: 2" and continues to the nsh prompt), so the
/etc mount had actually never worked for citest even pre-nxinit.
Add boards/sim/sim/sim/src/etc/init.d/init.rc (registers a "console sh"
service guarded by CONFIG_SYSTEM_NSH; "on init" starts it), shipped via
ROMFS in the Make build (RCSRCS) and CMake (nuttx_add_romfs()), both gated
on CONFIG_ETC_ROMFS && CONFIG_SYSTEM_NXINIT so non-nxinit configs are
unaffected.
Switching to nxinit means nsh_main()/nsh_initialize() (which used to run
/etc/init.d/rc.sysinit and rcS to mount /tmp and /data) no longer runs on
the 46 sim configs that already had CONFIG_ETC_ROMFS=y on master, so
those mounts would otherwise be lost. /bin (binfs) and /proc (procfs) are
unaffected: sim_bringup() (called from board_late_initialize(), before
any entrypoint task starts, independent of nsh_main/init_main) already
mounts them unconditionally on master, and this PR does not touch that
file. init.rc's "on init" action reproduces the rest of rc.sysinit's
mounts (tmpfs, or the FAT-backed /tmp ramdisk via mkrd + mkfatfs + mount
for boards without CONFIG_FS_TMPFS) plus the hostfs /data mount that
used to live in rcS, inlining them directly instead of spawning the
standalone rcsysinit/rcS scripts through a "service ... oneshot"
indirection. nxinit has no builtin mount/mkrd/mkfatfs yet, so each of
these commands still resolves through its posix_spawnp() sh fallback;
that limitation is unchanged by this PR and is left for a follow-up
(either a native mount() call in sim_bringup() for the fixed-path
mounts, or a builtin in nxinit). The 6 configs that also enable
CONFIG_FS_FAT get an explicit CONFIG_ETC_FATDEVNO=2 so this ramdisk does
not collide with /etc's romdisk.
Now that every sim nsh_main + CONFIG_ETC_ROMFS config has switched to
nxinit, boards/sim/sim/sim/src/etc/init.d/rcS and rc.sysinit are dead
code: no remaining sim config calls nsh_initialize() (the only caller of
those scripts), so remove both files outright and drop them from
boards/sim/sim/sim/src/CMakeLists.txt and Makefile's ROMFS RCSRCS list
(init.rc is shipped instead, as above, only when CONFIG_SYSTEM_NXINIT=y).
The remaining ROMFS-enabled sim configs whose entrypoint isn't nsh_main
(nxlines/nxwm/toybox) never executed rcS/rc.sysinit either (their
entrypoint never calls nsh_initialize()), so they lose nothing but a few
unused bytes from their ROMFS image; sim:nxlines was rebuilt to confirm
it still links and boots with an empty etc/init.d/.
init.rc also uses <nuttx/macro.h>'s CONCATENATE() instead of a local
CONCAT_()/CONCAT() pair, matching existing NuttX convention instead of
duplicating a macro the tree already provides.
sim:windows and sim:windows64 are excluded and stay on nsh_main: they
build under MSVC in CI, and CONFIG_SYSTEM_NXINIT pulls in
apps/system/nxinit/action.c, which fails to compile under MSVC because
list_peek_head_type() (include/nuttx/list.h) uses a GCC
statement-expression the MSVC C compiler does not support; separately,
CONFIG_ETC_ROMFS routes them through nuttx_add_romfs()'s POSIX-shell
genromfs/xxd/sed custom build step, which cmd.exe cannot parse either.
Both are pre-existing MSVC gaps in nxinit/the ROMFS CMake helper, not
something this defconfig-only PR should fix, so these two configs are
left on nsh_main.
Testing (sim, host gcc): sim:nsh boots into nxinit with nsh spawned as
its service (init task = init_main, sh = its child), and now shows the
same five mount points as master (/bin /data /etc /proc /tmp), matching
the pre-switch nsh_main baseline; /data round-trips a write to the host
filesystem. The five binfmt configs reach an interactive nsh prompt
(help/uname work) instead of failing to start the console; e.g.
sim:module:
BEFORE fix: Error Starting service 'console': 2
AFTER fix: nsh> help / nsh> uname -a (console up)
init.rc's inlined FAT/tmpfs mount was verified by preprocessing it with
cpp under both CONFIG_FS_FAT and CONFIG_FS_TMPFS: the expansion matches
rc.sysinit's mount sequence (CONCATENATE() resolves to /dev/ram2, etc.).
sim:citest specifically verified with gdb: before the ETC_ROMFSDEVNO fix,
register_blockdriver("/dev/ram0") is called twice (once by
sim_registerblockdevice() from up_initialize(), once by nx_romfsetc());
the second call returns -EEXIST and nxinit aborts. After setting
CONFIG_ETC_ROMFSDEVNO=1, sim:citest boots cleanly into nxinit (ps shows
init_main waiting on its child sh, matching sim:nsh), and the compiled
ROMFS image contains only init.rc. sim:nxlines, a non-nxinit
CONFIG_ETC_ROMFS config, was rebuilt to confirm it still links and boots
with the now-empty etc/init.d/ (rcS/rc.sysinit removed).
Assisted-by: opencode-agent/claude-sonnet-5
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Switch every qemu-armv8a defconfig whose init entry point was nsh_main (20 configs) to nxinit (init_main). nsh now runs as a "console sh" service started by init.rc instead of being the top-level init task. Each switched defconfig only gains the nxinit-essential keys (minimal delta): - CONFIG_INIT_ENTRYPOINT="init_main" - CONFIG_SYSTEM_NXINIT=y plus its Kconfig deps not already set: CONFIG_EXPERIMENTAL, CONFIG_LIBC_EXECFUNCS, CONFIG_SCHED_CHILD_STATUS (depends on CONFIG_SCHED_HAVE_PARENT) - CONFIG_ETC_ROMFS=y / CONFIG_FS_ROMFS=y to ship init.rc via ROMFS No stack-size overrides: INIT_STACKSIZE/SYSTEM_NSH_STACKSIZE keep their Kconfig defaults (DEFAULT_TASK_STACKSIZE, already 8192 on this board). Add boards/arm64/qemu/qemu-armv8a/src/etc/init.d/init.rc, shipped via ROMFS in the Make build (RCSRCS) and CMake (nuttx_add_romfs()), gated on CONFIG_ETC_ROMFS && CONFIG_SYSTEM_NXINIT. Omitting this ROMFS plumbing causes a link-time "undefined reference to romfs_img". Testing: qemu-armv8a:nsh (and nsh_smp with -smp 4) boot into nxinit with nsh spawned as its service (init task = init_main, sh = its child), confirmed via qemu-system-aarch64 in an earlier run of this series. The removed explicit 8192 stack sizes equal this board's DEFAULT_TASK_STACKSIZE, so runtime behavior is unchanged. Note: current apache/master fails to build locally this round (empty -Wstack-usage=, missing libfdt.h) independent of this change. Assisted-by: opencode-agent/claude-opus-4-8 Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Switch every qemu-armv7a defconfig whose init entry point was nsh_main (6 configs: full, gdbstub, nsh, rpproxy, rpserver, smp) to nxinit (init_main). nsh now runs as a "console sh" service started by init.rc instead of being the top-level init task. Each switched defconfig only gains the nxinit-essential keys (minimal delta): - CONFIG_INIT_ENTRYPOINT="init_main" - CONFIG_SYSTEM_NXINIT=y plus its Kconfig deps not already set: CONFIG_EXPERIMENTAL, CONFIG_LIBC_EXECFUNCS, CONFIG_SCHED_CHILD_STATUS (depends on CONFIG_SCHED_HAVE_PARENT) - CONFIG_ETC_ROMFS=y / CONFIG_FS_ROMFS=y to ship init.rc via ROMFS No stack-size overrides: INIT_STACKSIZE/SYSTEM_NSH_STACKSIZE keep their Kconfig defaults. Add boards/arm/qemu/qemu-armv7a/src/etc/init.d/init.rc, shipped via ROMFS in the Make build (RCSRCS) and CMake (nuttx_add_romfs()), gated on CONFIG_ETC_ROMFS && CONFIG_SYSTEM_NXINIT. Testing: qemu-armv7a:nsh (and smp with -smp 4) boot into nxinit with nsh spawned as its service (init task = init_main, sh = its child), confirmed via qemu-system-arm in an earlier run of this series. Note: current apache/master fails to build qemu-armv7a locally this round (missing arm_timer.h) independent of this change. Assisted-by: opencode-agent/claude-opus-4-8 Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
0b0c010 to
4f38002
Compare
|
The requirements:
- ["CONFIG_DEBUG_SYMBOLS", True]
- ["CONFIG_SYSTEM_NSH", True]
- ["CONFIG_INIT_ENTRYPOINT", "nsh_main"]
Fix: apache/nuttx-ntfc-testing#6 drops the obsolete Why it's safe to drop: the Note: apache/nuttx-ntfc-testing#6 is open and marked ready for review; a full NTFC run under |
|
@xiaoxiang781216 nuttx/.github/workflows/build.yml Line 365 in 7609a72 |
|
The |
Summary
Switch every defconfig whose init entry point was
nsh_mainon the threelocally verifiable boards — sim (80), qemu-armv8a (18), qemu-armv7a (6),
104 defconfigs total — to nxinit (
init_main), matching the esp32p4/esp32s3boards' existing nxinit configs. With nxinit,
nshno longer is init; itruns as a
console shservice started byinit.rc.Split into three commits, one per board:
boards/sim: switch all nsh defconfigs to nxinit entrypointboards/arm64/qemu-armv8a: switch all nsh defconfigs to nxinit entrypointboards/arm/qemu-armv7a: switch all nsh defconfigs to nxinit entrypointPer defconfig (regenerated with
make savedefconfig):CONFIG_INIT_ENTRYPOINT="init_main"CONFIG_SYSTEM_NXINIT=yplus its Kconfig deps:CONFIG_EXPERIMENTAL,CONFIG_LIBC_EXECFUNCS,CONFIG_SCHED_CHILD_STATUS(which depends on
CONFIG_SCHED_HAVE_PARENT)CONFIG_ETC_ROMFS=y/CONFIG_FS_ROMFS=yto shipinit.rcvia ROMFSEach board gains an
src/etc/init.d/init.rc(registers aconsole shservice guarded by
CONFIG_SYSTEM_NSH;on initstarts it), shipped throughROMFS in both the Make build (
RCSRCS) and CMake (nuttx_add_romfs()), bothgated on
CONFIG_ETC_ROMFS && CONFIG_SYSTEM_NXINITso non-nxinit configs areunaffected. Omitting this ROMFS plumbing causes a link-time
undefined reference to romfs_img.Five sim configs (
dynconns,module,module32,sotest,sotest32)had
CONFIG_BINFMT_DISABLE=y, which blocksCONFIG_LIBC_EXECFUNCSand thusCONFIG_SYSTEM_NXINIT. Since nxinit spawns services viaexec(), binfmt isre-enabled in those five; they still build cleanly.
Impact
sim,qemu-armv7a, andqemu-armv8aboards' defconfigsplus each board's
src/{Makefile,CMakeLists.txt}and newinit.rc. Nocommon code, no other boards, no NSH behavior change:
nshstill owns theinteractive console, now as an nxinit service rather than as init itself.
CONFIG_ETC_ROMFS && CONFIG_SYSTEM_NXINIT;existing non-nxinit builds of these boards are byte-for-byte unchanged.
CONFIG_SYSTEM_NXINITcurrentlydepends on EXPERIMENTAL.Testing
Verified against
apache/master(before =nsh_main) vs this branch(after =
init_main), building each config and, where a config reaches aninteractive
nsh>prompt, capturingps. Toolchains: host gcc (sim),aarch64-none-elf+qemu-system-aarch64(armv8a),arm-none-eabi+qemu-system-arm(armv7a); SMP configs booted with-smp 4.Runtime
ps(before/after) — init task changes fromnsh_maintoinit_main, andnsh(sh) is spawned as its child service:psbefore/after confirmed for the 55 configs that reach an interactive nshprompt (sim: 41, qemu: 14). Configs that don't drop to an nsh prompt
(app-entrypoint like nx/foc/can, remoteproc rpproxy/rpserver pairs, graphics,
gdbstub waiting for a debugger) were build-verified instead; those are not
ps-observable by design.Build note: 18 configs (sim: adb, alsa, bastest, duktape, login, lua, minmea,
mnemofs, nand, nimble, posix_spawn, romfs, rust, smartfs, windows;
qemu-armv8a: nsh_fiq, nsh_gicv2; qemu-armv7a: full) fail to build in my local
environment due to missing external dependencies (clang, lua headers,
third-party libs). These fail identically on unmodified
apache/master, i.e.they are pre-existing environment limitations unrelated to this change and
build fine in upstream CI.