# Linux Kernel Module Cheat

### 7.1. Replace init

To have more control over the system, you can replace BusyBox’s init with your own.

The most direct way to replace `init` with our own is to just use the `init=` command line parameter directly:

    ./run --kernel-cli 'init=/lkmc/count.sh'

This just counts every second forever and does not give you a shell.

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”.

For this reason, we have created a more robust helper method with the `--eval` option:

    ./run --eval 'echo "asdf qwer";insmod hello.ko;./linux/poweroff.out'

It is basically a shortcut for:

    ./run --kernel-cli 'init=/lkmc/eval_base64.sh - lkmc_eval="insmod hello.ko;./linux/poweroff.out"'

Source: rootfs_overlay/lkmc/eval_base64.sh.

This allows quoting and newlines by base64 encoding on host, and decoding on guest, see: Section 17.3.1, “Kernel command line parameters escaping”.

It also automatically chooses between `init=` and `rcinit=` for you, see: Section 7.3, “Path to init”

`--eval` replaces BusyBox' init completely, which makes things more minimal, but also has has the following consequences:

- `/etc/fstab` mounts are not done, notably `/proc` and `/sys`, test it out with:

      ./run --eval 'echo asdf;ls /proc;ls /sys;echo qwer'

- no shell is launched at the end of boot for you to interact with the system. You could explicitly add a `sh` at the end of your commands however:

      ./run --eval 'echo hello;sh'

The best way to overcome those limitations is to use: Section 7.2, “Run command at the end of BusyBox init”

If the script is large, you can add it to a gitignored file and pass that to `--eval` as in:

    echo '
    cd /lkmc
    insmod hello.ko
    ./linux/poweroff.out
    ' > data/gitignore.sh
    ./run --eval "$(cat data/gitignore.sh)"

or add it to a file to the root filesystem guest and rebuild:

    echo '#!/bin/sh
    cd /lkmc
    insmod hello.ko
    ./linux/poweroff.out
    ' > rootfs_overlay/lkmc/gitignore.sh
    chmod +x rootfs_overlay/lkmc/gitignore.sh
    ./build-buildroot
    ./run --kernel-cli 'init=/lkmc/gitignore.sh'

Remember that if your init returns, the kernel will panic, there are just two non-panic possibilities:

- run forever in a loop or long sleep

- `poweroff` the machine

- poweroff.out

- sleep_forever.out

- time_boot.out