Skip to content

system/nxinit: Add NuttX Init ("NxInit") reopened to be integrated on NuttX v13#3504

Merged
acassis merged 14 commits into
apache:masterfrom
acassis:nxinit
May 27, 2026
Merged

system/nxinit: Add NuttX Init ("NxInit") reopened to be integrated on NuttX v13#3504
acassis merged 14 commits into
apache:masterfrom
acassis:nxinit

Conversation

@acassis
Copy link
Copy Markdown
Contributor

@acassis acassis commented May 26, 2026

Summary

Add NuttX Init ("NxInit")

This component (abbreviated as "NxInit") is specifically developed for NuttX and intended for system initialization. While we have adopted the Android Init Language among various syntax options, this is a brand-new implementation—it is not a port or variant of Android Init.

Refer to the implementation of Android Init Language, consists of five broad classes of statements: Actions, Commands, Services, Options, and Imports.

Actions support two types of triggers: event and action. Action triggers also support runtime triggering. Services support lifecycle management, including automatic restart (at specified intervals), and starting/stopping individually or by class. Import supports files or directories, and we may add a static method in the future. The following are some differences:

The Android Init Language treats lines starting with # as comments, while we use a preprocessor to handle comments.
For action commands, we can omit "exec" and directly execute built-in apps or nsh builtins.
Regarding the property service, users can either adapt it by self or directly use the preset NVS-based properties.
Only part of standard action commands and service options are implemented currlently.

To enable system/init:

-CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_ENTRYPOINT="init_main"
+CONFIG_SYSTEM_NXINIT=y

Impact

NuttX will be able to start applications and services without depending NSH and without using the app as NuttX entrypoint directly.

Testing

   [    0.150000] [ 3] [ 0] init_main: == Dump Services ==
   ...
   [    0.160000] [ 3] [ 0] init_main: Service 0x40486aa8 name 'telnet' path 'telnetd'
   [    0.160000] [ 3] [ 0] init_main:   pid: 0
   [    0.160000] [ 3] [ 0] init_main:   arguments:
   [    0.160000] [ 3] [ 0] init_main:       [0] 'service'
   [    0.160000] [ 3] [ 0] init_main:       [1] 'telnet'
   [    0.160000] [ 3] [ 0] init_main:       [2] 'telnetd'
   [    0.160000] [ 3] [ 0] init_main:   classes:
   [    0.160000] [ 3] [ 0] init_main:     'test'
   [    0.170000] [ 3] [ 0] init_main:   restart_period: 3000
   [    0.170000] [ 3] [ 0] init_main:   reboot_on_failure: -1
   [    0.170000] [ 3] [ 0] init_main:   flags:
 > [    0.170000] [ 3] [ 0] init_main:     'oneshot'
   ...
   [    0.370000] [ 3] [ 0] init_main: starting service 'telnet' ...
   [    0.380000] [ 3] [ 0] init_main: service 'telnet' flag 0x2 add 0x4
   [    0.380000] [ 3] [ 0] init_main:   +flag 'running'
   [    0.380000] [ 3] [ 0] init_main: service 'telnet' flag 0x6 add 0x8
   [    0.380000] [ 3] [ 0] init_main:   -flag 'restarting'
   [    0.380000] [ 3] [ 0] init_main: service 'telnet' flag 0x6 add 0x1
   [    0.380000] [ 3] [ 0] init_main:   -flag 'disabled'
   [    0.380000] [ 3] [ 0] init_main: started service 'telnet' pid 9
   ...
   nsh> kill -9 9
   nsh> [    7.350000] [ 3] [ 0] init_main: service 'telnet' flag 0x6 add 0x4
   [    7.350000] [ 3] [ 0] init_main:   -flag 'running'
   [    7.350000] [ 3] [ 0] init_main: service 'telnet' flag 0x2 add 0x80000001
   [    7.350000] [ 3] [ 0] init_main:   +flag 'disabled'
   [    7.350000] [ 3] [ 0] init_main:   +flag 'remove'
   [    7.350000] [ 3] [ 0] init_main: service 'telnet' pid 9 exited status 1
 > [    7.360000] [ 3] [ 0] init_main: removing service 'telnet' ...
``


This component (abbreviated as "NxInit") is specifically developed
for NuttX and intended for system initialization. While we have
adopted the Android Init Language among various syntax options,
this is a brand-new implementation—it is not a port or variant of
Android Init.

Refer to the implementation of Android Init Language, consists of five broad
classes of statements: Actions, Commands, Services, Options, and Imports.

Actions support two types of triggers: event and action. Action triggers also
support runtime triggering. Services support lifecycle management, including
automatic restart (at specified intervals), and starting/stopping
individually or by class. Import supports files or directories, and we may
add a static method in the future. The following are some differences:
  1. The Android Init Language treats lines starting with `#` as comments,
     while we use a preprocessor to handle comments.
  2. For action commands, we can omit "exec" and directly execute
     built-in apps or nsh builtins.
  3. Regarding the property service, users can either adapt it by self or
     directly use the preset NVS-based properties.
  4. Only part of standard action commands and service options are
     implemented currlently.

To enable system/nxinit:
  ```diff
  -CONFIG_INIT_ENTRYPOINT="nsh_main"
  +CONFIG_INIT_ENTRYPOINT="init_main"
  +CONFIG_SYSTEM_NXINIT=y
  ```

For format and additional details, refer to:
  https://android.googlesource.com/platform/system/core/+/
  master/init/README.md

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Usage:
  class_start <classname>
  class_stop <classname>

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Enable CONFIG_SYSTEM_SYSTEM to support nsh builtins, which depends on nsh.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
If the command of an action takes too long (greater than
CONFIG_SYSTEM_NXINIT_ACTION_WARN_SLOW milliseconds, 50 ms by default),
a warning log will be output for analysis and debugging.

For example:

  a. sleep 1
       [    0.340000] [ 3] [ 0] init_main: executing NSH command 'sleep 1'
       [    1.360000] [ 3] [ 0] init_main: NSH command 'sleep 1' exited 0
     > [    1.360000] [ 3] [ 0] init_main: command 'sleep' took 1020 ms

  b. hello (add sleep(1) to examples/hello)

       [    1.390000] [ 3] [ 0] init_main: executed command 'hello' pid 14
       [    1.390000] [ 3] [ 0] init_main: waiting 'hello' pid 14
       Hello, World!!
     > [    2.400000] [ 3] [ 0] init_main: command 'hello' pid 14 took 1010 ms
       [    2.400000] [ 3] [ 0] init_main: command 'hello' pid 14 exited status 0

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Add support for the oneshot option to the service.

Test
  - RC
      service telnet telnetd
          class test
    >     oneshot
          restart_period 3000
  - Runtime
      [    0.150000] [ 3] [ 0] init_main: == Dump Services ==
      ...
      [    0.160000] [ 3] [ 0] init_main: Service 0x40486aa8 name 'telnet' path 'telnetd'
      [    0.160000] [ 3] [ 0] init_main:   pid: 0
      [    0.160000] [ 3] [ 0] init_main:   arguments:
      [    0.160000] [ 3] [ 0] init_main:       [0] 'service'
      [    0.160000] [ 3] [ 0] init_main:       [1] 'telnet'
      [    0.160000] [ 3] [ 0] init_main:       [2] 'telnetd'
      [    0.160000] [ 3] [ 0] init_main:   classes:
      [    0.160000] [ 3] [ 0] init_main:     'test'
      [    0.170000] [ 3] [ 0] init_main:   restart_period: 3000
      [    0.170000] [ 3] [ 0] init_main:   reboot_on_failure: -1
      [    0.170000] [ 3] [ 0] init_main:   flags:
    > [    0.170000] [ 3] [ 0] init_main:     'oneshot'
      ...
      [    0.370000] [ 3] [ 0] init_main: starting service 'telnet' ...
      [    0.380000] [ 3] [ 0] init_main: service 'telnet' flag 0x2 add 0x4
      [    0.380000] [ 3] [ 0] init_main:   +flag 'running'
      [    0.380000] [ 3] [ 0] init_main: service 'telnet' flag 0x6 add 0x8
      [    0.380000] [ 3] [ 0] init_main:   -flag 'restarting'
      [    0.380000] [ 3] [ 0] init_main: service 'telnet' flag 0x6 add 0x1
      [    0.380000] [ 3] [ 0] init_main:   -flag 'disabled'
      [    0.380000] [ 3] [ 0] init_main: started service 'telnet' pid 9
      ...
      nsh> kill -9 9
      nsh> [    7.350000] [ 3] [ 0] init_main: service 'telnet' flag 0x6 add 0x4
      [    7.350000] [ 3] [ 0] init_main:   -flag 'running'
      [    7.350000] [ 3] [ 0] init_main: service 'telnet' flag 0x2 add 0x80000001
      [    7.350000] [ 3] [ 0] init_main:   +flag 'disabled'
      [    7.350000] [ 3] [ 0] init_main:   +flag 'remove'
      [    7.350000] [ 3] [ 0] init_main: service 'telnet' pid 9 exited status 1
    > [    7.360000] [ 3] [ 0] init_main: removing service 'telnet' ...

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Format: exec_start <service>

Start the specified service and pause the processing of any additional
initialization commands until the service completes its execution. This
command operates similarly to the `exec` command; the key difference is
that it utilizes an existing service definition rather than requiring
the `exec` argument vector.

This feature is particularly intended for use with the `reboot_on_failure`
built-in command to perform all types of essential checks during system boot.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Add support for the reboot_on_failure option to the service.

When the execution of a command within a certain action fails (returning
a non-zero status code), NxInit will continue to execute subsequent commands or
actions and will not proactively terminate the startup process. To implement
the functionality of "terminating the startup process after a command
execution fails", there are two methods:
a. Execute conditional statements (if/then/else/fi) via exec command,
   but this depends on sh:
   ```
   on init
       exec -- set +e; \
               mount -t fatfs /dev/data /data ; \
               if [ $? -ne 0 ] ; \
               then \
                 echo "failed" ; \
                 reboot ; \
               else \
                 echo "succeed" ; \
               fi;
   ```
b. Via service's oneshot + reboot_on_failure:
   /* Although the example uses sh, it does not depend on it and can be
    * replaced with any other Builtin Apps.
    */
   ```
   on init
       exec_start mkdir_tmp
       ls /tmp

   service mkdir_tmp sh -c "mkdir /tmp"
       reboot_on_failure 0
       oneshot
   ```

Test
  - RC
      service console sh
          class core
          override
    >     reboot_on_failure 0
          restart_period 10000
  - Runtime
      [    0.150000] [ 3] [ 0] init_main: == Dump Services ==
      ...
      [    0.170000] [ 3] [ 0] init_main: Service 0x40486ea0 name 'console' path 'sh'
      [    0.170000] [ 3] [ 0] init_main:   pid: 0
      [    0.170000] [ 3] [ 0] init_main:   arguments:
      [    0.170000] [ 3] [ 0] init_main:       [0] 'service'
      [    0.170000] [ 3] [ 0] init_main:       [1] 'console'
      [    0.170000] [ 3] [ 0] init_main:       [2] 'sh'
      [    0.170000] [ 3] [ 0] init_main:   classes:
      [    0.170000] [ 3] [ 0] init_main:     'core'
      [    0.170000] [ 3] [ 0] init_main:   restart_period: 10000
    > [    0.170000] [ 3] [ 0] init_main:   reboot_on_failure: 0
      [    0.170000] [ 3] [ 0] init_main:   flags:
      [    0.170000] [ 3] [ 0] init_main:     'override'
      ...
      [    0.380000] [ 3] [ 0] init_main: started service 'console' pid 4
      ...
      nsh> kill -9 4
      [    8.060000] [ 3] [ 0] init_main: service 'console' flag 0x20000004 add 0x4
      [    8.060000] [ 3] [ 0] init_main:   -flag 'running'
      [    8.060000] [ 3] [ 0] init_main: service 'console' flag 0x20000000 add 0x8
      [    8.060000] [ 3] [ 0] init_main:   +flag 'restarting'
    > [    8.060000] [ 3] [ 0] init_main: Error reboot on failure of service 'console' reason 0

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
@acassis
Copy link
Copy Markdown
Contributor Author

acassis commented May 26, 2026

@simbit18 @lupyuen any idea what is this label error:

 label
Unhandled error: ReferenceError: keywords is not defined

Copy link
Copy Markdown
Contributor

@linguini1 linguini1 left a comment

Choose a reason for hiding this comment

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

I don't see anything really wrong with this, just some small comments.

Very excited for this in NuttX!

Comment thread system/nxinit/Kconfig Outdated
Comment thread system/nxinit/Kconfig Outdated
Comment thread system/nxinit/service.h Outdated
Comment thread system/nxinit/service.c Outdated
Comment thread system/nxinit/init.h Outdated
Comment thread system/nxinit/init.h
Comment thread system/nxinit/init.h
Comment thread system/nxinit/init.c Outdated
Comment thread system/nxinit/init.c
@linguini1
Copy link
Copy Markdown
Contributor

Also would be good to test on a couple devices!

This comments to be visible to the users

Signed-off-by: Alan C. Assis <acassis@gmail.com>
@xiaoxiang781216
Copy link
Copy Markdown
Contributor

I would suggest that you don't copy nxinit because:

  1. It is still in the active development
  2. This old copy contain many bugs and lack many improvements

@acassis
Copy link
Copy Markdown
Contributor Author

acassis commented May 27, 2026

I would suggest that you don't copy nxinit because:

1. It is still in the active development

2. This old copy contain many bugs and lack many improvements

Hi @xiaoxiang781216 thank you for the warning, maybe you can share the existing fixes.

We could submit it as EXPERIMENTAL, this way more people will start to test it and will help to improve it. This way is better then developing in entirely on closed doors. Is it possible?

acassis added 4 commits May 27, 2026 10:01
This an issue where a variable was declared as name[0]

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Avoid fixing the max 99 class cmds directly in the code.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Make it clear it is a userspace log.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Since boardctl(BOARDIOC_INIT, 0) was removed from all boards, it is
not right to use it here.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
@xiaoxiang781216
Copy link
Copy Markdown
Contributor

xiaoxiang781216 commented May 27, 2026

I would suggest that you don't copy nxinit because:

1. It is still in the active development

2. This old copy contain many bugs and lack many improvements

Hi @xiaoxiang781216 thank you for the warning, maybe you can share the existing fixes.

We could submit it as EXPERIMENTAL, this way more people will start to test it and will help to improve it. This way is better then developing in entirely on closed doors. Is it possible?

it's better to download from openvela repo just like other 3rd party active project.

@acassis
Copy link
Copy Markdown
Contributor Author

acassis commented May 27, 2026

I would suggest that you don't copy nxinit because:

1. It is still in the active development

2. This old copy contain many bugs and lack many improvements

Hi @xiaoxiang781216 thank you for the warning, maybe you can share the existing fixes.
We could submit it as EXPERIMENTAL, this way more people will start to test it and will help to improve it. This way is better then developing in entirely on closed doors. Is it possible?

it's better to download from openvela repo just like other 3rd party active project.

No, the idea is to make NXInit an integral part of NuttX, but a 3rd party.

So, I will change it to EXPERIMENTAL for now.

acassis added 2 commits May 27, 2026 11:01
Add the final event option to the Kconfig

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Since NXInit still under development, it is better to change it to
EXPERIMENTAL.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Copy link
Copy Markdown
Contributor

@linguini1 linguini1 left a comment

Choose a reason for hiding this comment

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

For visibility, marking that init.rc path should be made configurable in the next patches

@acassis acassis merged commit c28e61f into apache:master May 27, 2026
41 checks passed
@cederom
Copy link
Copy Markdown
Contributor

cederom commented May 27, 2026

Ah just came back to the lab, but +1 from me, lets move forward making small steps, thank you @acassis :-)

@linguini1 linguini1 mentioned this pull request May 28, 2026
1 task
lupyuen added a commit to lupyuen260528/nuttx-apps that referenced this pull request May 28, 2026
PR apache#3504 introduced a typo in nxinit/Kconfig: `--help--`. This PR changes it to `---help---` to fix this build error:
```
$ tools/configure.sh rv-virt:nsh
apps/system/nxinit/Kconfig:81: syntax error
apps/system/nxinit/Kconfig:80: unknown option "--help--"
```
https://github.com/lupyuen/nuttx-riscv64/actions/runs/26546602390/job/78199683651#step:5:162

Signed-off-by: Lup Yuen Lee <luppy@appkaki.com>
@lupyuen
Copy link
Copy Markdown
Member

lupyuen commented May 28, 2026

There's a typo in nxinit/Kconfig: --help-- should be ---help---. The fix is here:

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.

7 participants