./run --kernel-cli 'init=/bin/sh' --kernel-cli-after-dash '-c "echo asdf; pwd; ls"'-
diff --git a/index.html b/index.html index 8665852..912d3b6 100644 --- a/index.html +++ b/index.html @@ -7018,14 +7018,6 @@ cr3 = 0xFFFFF0DCDC000
This just counts every second forever and does not give you a shell.
And to pass command line arguments to the program, you can use --kernel-cli-after-dash:
./run --kernel-cli 'init=/bin/sh' --kernel-cli-after-dash '-c "echo asdf; pwd; ls"'-
This method is not very flexible however, as it is hard to reliably pass multiple commands and command line arguments to the init with it, as explained at: Section 7.4, “Init environment”.
Documented at https://www.kernel.org/doc/html/v5.9/admin-guide/kernel-parameters.html:
+Documented at https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html:
-The kernel parses parameters from the kernel command line up to "--"; if it doesn’t recognize a parameter and it doesn’t contain a '.', the parameter gets passed to init: parameters with '=' go into init’s environment, others are passed as command line arguments to init. Everything after "--" is passed as an argument to init.
+The kernel parses parameters from the kernel command line up to "-"; if it doesn’t recognize a parameter and it doesn’t contain a '.', the parameter gets passed to init: parameters with '=' go into init’s environment, others are passed as command line arguments to init. Everything after "-" is passed as an argument to init.
And you can try it out with our userland/linux/init_env_poweroff.c program:
+And you can try it out with:
./run --kernel-cli 'init=/lkmc/linux/init_env_poweroff.out loglevel=8 go_in_env=val1 with_dot.before=val2' \ - --kernel-cli-after-dash 'go_in_arg=val3 with_dot.after=val4 zxcv'+
./run --kernel-cli 'init=/lkmc/linux/init_env_poweroff.out' --kernel-cli-after-dash 'asdf=qwer zxcv'
From the generated QEMU command, we see that the kernel CLI at LKMC 69f5745d3df11d5c741551009df86ea6c61a09cf now contains (or at least would if it weren’t for https://github.com/cirosantilli/linux-kernel-module-cheat/issues/110 oh God), manually indented for readability:
+From the generated QEMU command, we see that the kernel CLI at LKMC 69f5745d3df11d5c741551009df86ea6c61a09cf now contains:
<6>[ 0.000000] Command line: root=/dev/vda nopat console_msg_format=syslog nokaslr norandmaps panic=-1 printk.devkmsg=on printk.time=y rw - init=/lkmc/linux/init_env_poweroff.out loglevel=8 go_in_env=val1 with_dot.before=val2 -- go_in_arg=val3 with_dot.after=val4 zxcv+
init=/lkmc/linux/init_env_poweroff.out console=ttyS0 - lkmc_home=/lkmc asdf=qwer zxcv
<6>[ 2.728992] Run /lkmc/linux/init_env_poweroff.out as init process -<7>[ 2.729587] with arguments: -<7>[ 2.729820] /lkmc/linux/init_env_poweroff.out -<7>[ 2.730085] lkmc_home=/lkmc -<7>[ 2.730259] go_in_arg=val3 -<7>[ 2.730432] with_dot.after=val4 -<7>[ 2.730623] zxcv -<7>[ 2.730767] with environment: -<7>[ 2.730960] HOME=/ -<7>[ 2.731115] TERM=linux -<7>[ 2.731267] go_in_env=val+
args: +/lkmc/linux/init_env_poweroff.out +- +zxcv + +env: +HOME=/ +TERM=linux +lkmc_home=/lkmc +asdf=qwer
Tested as of the Linux kernel v5.7 and possibly earlier, boot also shows the init arguments and environment very clearly when using printk at loglevel=8, which is a great addition:
Source: userland/linux/init_env_poweroff.c.
+As of the Linux kernel v5.7 (possibly earlier, I’ve skipped a few releases), boot also shows the init arguments and environment very clearly, which is a great addition:
<6>[ 2.777265] Run /lkmc/linux/init_env_poweroff.out as init process -<7>[ 2.777729] with arguments: -<7>[ 2.777953] /lkmc/linux/init_env_poweroff.out -<7>[ 2.778212] lkmc_home=/lkmc -<7>[ 2.778391] go_in_arg=val2 -<7>[ 2.778554] zxcv -<7>[ 2.778705] with environment: -<7>[ 2.778901] HOME=/ -<7>[ 2.779065] TERM=linux -<7>[ 2.779223] go_in_env=val1+
<6>[ 0.309984] Run /sbin/init as init process +<7>[ 0.309991] with arguments: +<7>[ 0.309997] /sbin/init +<7>[ 0.310004] nokaslr +<7>[ 0.310010] - +<7>[ 0.310016] with environment: +<7>[ 0.310022] HOME=/ +<7>[ 0.310028] TERM=linux +<7>[ 0.310035] earlyprintk=pl011,0x1c090000 +<7>[ 0.310041] lkmc_home=/lkmc
As we can see, the passing of environment variables to init is a bit wonky:
-init and loglevel didn’t go because they were recognized
go_in_env went because it wasn’t
so things can always break in future kernel releases… The only way to guard from this a bit is to use some unique prefix and hope the kernel never decides to use it. We of course use lkmc_* for our variables.
And it is also impossible to pass environment variables that contain dots in them: our with_dot.before is simply gone. Not a common use case, but still, quite insane.
The arguments are documented in the kernel documentation: https://www.kernel.org/doc/html/v5.9/admin-guide/kernel-parameters.html
+The arguments are documented in the kernel documentation: https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html
When dealing with real boards, extra command line options are provided on some magic bootloader configuration file, e.g.:
@@ -13578,27 +13551,6 @@ echo $?TODO these examples broke in kernel 5.0 and we didn’t notice because they just added a flimsy warning and nothing else:
-Fix with ifdef for kernel 4/5. The error message is:
-seq_file: buggy .next function next [module-name] did not update position index-
Writing trivial read File operations is repetitive and error prone. The seq_file API makes the process much easier for those trivial cases:
Documented at https://www.kernel.org/doc/html/v5.9/admin-guide/kernel-parameters.html:
+Documented at https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html:
-The kernel parses parameters from the kernel command line up to "--"; if it doesn’t recognize a parameter and it doesn’t contain a '.', the parameter gets passed to init: parameters with '=' go into init’s environment, others are passed as command line arguments to init. Everything after "--" is passed as an argument to init.
+The kernel parses parameters from the kernel command line up to "-"; if it doesn’t recognize a parameter and it doesn’t contain a '.', the parameter gets passed to init: parameters with '=' go into init’s environment, others are passed as command line arguments to init. Everything after "-" is passed as an argument to init.
And you can try it out with our userland/linux/init_env_poweroff.c program:
+And you can try it out with:
./run --kernel-cli 'init=/lkmc/linux/init_env_poweroff.out loglevel=8 go_in_env=val1 with_dot.before=val2' \ - --kernel-cli-after-dash 'go_in_arg=val3 with_dot.after=val4 zxcv'+
./run --kernel-cli 'init=/lkmc/linux/init_env_poweroff.out' --kernel-cli-after-dash 'asdf=qwer zxcv'
From the generated QEMU command, we see that the kernel CLI at LKMC 69f5745d3df11d5c741551009df86ea6c61a09cf now contains (or at least would if it weren’t for https://github.com/cirosantilli/linux-kernel-module-cheat/issues/110 oh God), manually indented for readability:
+From the generated QEMU command, we see that the kernel CLI at LKMC 69f5745d3df11d5c741551009df86ea6c61a09cf now contains:
<6>[ 0.000000] Command line: root=/dev/vda nopat console_msg_format=syslog nokaslr norandmaps panic=-1 printk.devkmsg=on printk.time=y rw - init=/lkmc/linux/init_env_poweroff.out loglevel=8 go_in_env=val1 with_dot.before=val2 -- go_in_arg=val3 with_dot.after=val4 zxcv+
init=/lkmc/linux/init_env_poweroff.out console=ttyS0 - lkmc_home=/lkmc asdf=qwer zxcv
<6>[ 2.728992] Run /lkmc/linux/init_env_poweroff.out as init process -<7>[ 2.729587] with arguments: -<7>[ 2.729820] /lkmc/linux/init_env_poweroff.out -<7>[ 2.730085] lkmc_home=/lkmc -<7>[ 2.730259] go_in_arg=val3 -<7>[ 2.730432] with_dot.after=val4 -<7>[ 2.730623] zxcv -<7>[ 2.730767] with environment: -<7>[ 2.730960] HOME=/ -<7>[ 2.731115] TERM=linux -<7>[ 2.731267] go_in_env=val+
args: +/lkmc/linux/init_env_poweroff.out +- +zxcv + +env: +HOME=/ +TERM=linux +lkmc_home=/lkmc +asdf=qwer
Tested as of the Linux kernel v5.7 and possibly earlier, boot also shows the init arguments and environment very clearly when using printk at loglevel=8, which is a great addition:
Source: userland/linux/init_env_poweroff.c.
+As of the Linux kernel v5.7 (possibly earlier, I’ve skipped a few releases), boot also shows the init arguments and environment very clearly, which is a great addition:
<6>[ 2.777265] Run /lkmc/linux/init_env_poweroff.out as init process -<7>[ 2.777729] with arguments: -<7>[ 2.777953] /lkmc/linux/init_env_poweroff.out -<7>[ 2.778212] lkmc_home=/lkmc -<7>[ 2.778391] go_in_arg=val2 -<7>[ 2.778554] zxcv -<7>[ 2.778705] with environment: -<7>[ 2.778901] HOME=/ -<7>[ 2.779065] TERM=linux -<7>[ 2.779223] go_in_env=val1+
<6>[ 0.309984] Run /sbin/init as init process +<7>[ 0.309991] with arguments: +<7>[ 0.309997] /sbin/init +<7>[ 0.310004] nokaslr +<7>[ 0.310010] - +<7>[ 0.310016] with environment: +<7>[ 0.310022] HOME=/ +<7>[ 0.310028] TERM=linux +<7>[ 0.310035] earlyprintk=pl011,0x1c090000 +<7>[ 0.310041] lkmc_home=/lkmc
As we can see, the passing of environment variables to init is a bit wonky:
-init and loglevel didn’t go because they were recognized
go_in_env went because it wasn’t
so things can always break in future kernel releases… The only way to guard from this a bit is to use some unique prefix and hope the kernel never decides to use it. We of course use lkmc_* for our variables.
And it is also impossible to pass environment variables that contain dots in them: our with_dot.before is simply gone. Not a common use case, but still, quite insane.
The arguments are documented in the kernel documentation: https://www.kernel.org/doc/html/v5.9/admin-guide/kernel-parameters.html
+The arguments are documented in the kernel documentation: https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html
When dealing with real boards, extra command line options are provided on some magic bootloader configuration file, e.g.:
diff --git a/replace-init.html b/replace-init.html index cac9ab2..0fb37fa 100644 --- a/replace-init.html +++ b/replace-init.html @@ -473,14 +473,6 @@ pre{ white-space:pre }This just counts every second forever and does not give you a shell.
And to pass command line arguments to the program, you can use --kernel-cli-after-dash:
./run --kernel-cli 'init=/bin/sh' --kernel-cli-after-dash '-c "echo asdf; pwd; ls"'-
This method is not very flexible however, as it is hard to reliably pass multiple commands and command line arguments to the init with it, as explained at: Section 7.4, “Init environment”.
TODO these examples broke in kernel 5.0 and we didn’t notice because they just added a flimsy warning and nothing else:
-Fix with ifdef for kernel 4/5. The error message is:
-seq_file: buggy .next function next [module-name] did not update position index-
Writing trivial read File operations is repetitive and error prone. The seq_file API makes the process much easier for those trivial cases: