diff --git a/FAQ.md b/FAQ.md index f92ab68a..3a87f243 100644 --- a/FAQ.md +++ b/FAQ.md @@ -14,12 +14,12 @@ Make sure your `jq` is at least v1.5 (some distros have an older v1.4 release). ## Running the image -## Nothing is printed after `Booting the kernel.` +### Nothing is printed after `Booting the kernel.` It's perfectly normal. DSM kernels are built without display support and log everything using serial ports. You will not see any kernel output on the physical screen. As far as we know this isn't something fixable without kernel recompilation. -## Serial0 stops updating after `bootconsole [uart0] disabled` +### Serial0 stops updating after `bootconsole [uart0] disabled` The kernel has two different consoles: earlycon and normal console. This is the moment it switches to the normal console from the "earlycon". For Linux v4 the console is set for Serial2 (3rd serial port), for Linux v3 it is set to Serial1 (2nd serial port). As mfgBIOS is hardcoded to use `ttyS0` we cannot use the first serial port for kernel. @@ -27,7 +27,7 @@ from the "earlycon". For Linux v4 the console is set for Serial2 (3rd serial por There's also some weirdness with swapping serial 0 & 1 making `ttyS1` unavailable on Linux v4. This is fixable, but as of now it's a low priority bug. -## Boot stops at `clocksource: Switched to clocksource tsc` +### Boot stops at `clocksource: Switched to clocksource tsc` Wait, on some systems it may take ~30s to progress. ## Early kernel panic with "No filesystem could mount root" @@ -59,7 +59,7 @@ again. Magically the problem will solve itself. If it doesn't go away make sure to read the log up carefully as you may have e.g. initramfs unpack bug (see below). -## Initramfs cannot be unpacked +### Initramfs cannot be unpacked If during boot you get something like log below: ``` @@ -72,6 +72,25 @@ If you've just added a new platform you just stepped into a [known syno kernels You need to generate CPIO instead of LZMA ramdisks (see [`FOR_DEVS.md`](FOR_DEVS.md) for details) for this OS version. ## Misc +### What's the deal with fake `modprobe`? +Loading kernel modules is complex. However, in short there are two distinct ways for them to load: from userspace or +from kernel space. The latter is kind of misleading since the kernel, after doing some checks, calls /sbin/modprobe to +actually load the module (see `kmod.c`). This path is hardcoded in the kernel. Usually it's a symlink to a kmod utility +which uses userspace syscalls to load the module. + +Here comes the less-intuitive part. RedPill LKM is loaded on the **kernel's request**. It happens because we specify +the `elevator=elevator` boot param. This causes kernel to, very early in the boot process (in fact still being in the +formal init-before-boot stage), request module named `elevator-iosched`. There's nothing special in that name - it can +be anything as long as the userspace and cmdline agree on the name. Our [fake `modprobe`](config/_common/iosched-trampoline.sh) +checks (very loosely) if the requested module is `elevator-iosched` and triggers the standard force-insmod, then deletes +itself. Keep in mind that our "modprobe" isn't actually overriding anything - preboot environment contains no `modprobe` +as it has no concept of depmods (=modprobe would be useless). + +Using I/O scheduler loading method over `insmod`ing it in init allows us to load the LKM much earlier. While by itself +it has advantages of simply being faster, it also carries another **very important** advantage: I/O scheduler, as +mentioned earlier, is loaded **during init stage**. This means we can safely call methods which are marked with `__init` +and potentially removed after init finishes (which is in fact [what prompted that rewrite](https://github.com/RedPill-TTG/redpill-lkm/issues/10)). + ### Why is this written in BASH?! We ask the same question... it was a huge mistake, leading to spaghetti code. But when we realized it was a mistake it was too late to scrap everything and start from scratch. Consider this version an MVP. diff --git a/config/DS3615xs/6.2.4-25556/config.json b/config/DS3615xs/6.2.4-25556/config.json index e5b21717..13d3bc8f 100644 --- a/config/DS3615xs/6.2.4-25556/config.json +++ b/config/DS3615xs/6.2.4-25556/config.json @@ -102,6 +102,7 @@ "compress_rd": true, "ramdisk_copy": { "@@@EXT@@@/rp-lkm/redpill-linux-v3.10.105.ko": "usr/lib/modules/rp.ko", + "@@@COMMON@@@/iosched-trampoline.sh": "sbin/modprobe", "@@@EXT@@@/virtio-3.10.105/virtio.ko": "lib/modules/", "@@@EXT@@@/virtio-3.10.105/virtio_ring.ko": "lib/modules/", "@@@EXT@@@/virtio-3.10.105/virtio_pci.ko": "lib/modules/", diff --git a/config/DS3615xs/7.0-41222/config.json b/config/DS3615xs/7.0-41222/config.json index bb3c1c2d..d57e76bd 100644 --- a/config/DS3615xs/7.0-41222/config.json +++ b/config/DS3615xs/7.0-41222/config.json @@ -101,6 +101,7 @@ "compress_rd": false, "ramdisk_copy": { "@@@EXT@@@/rp-lkm/redpill-linux-v3.10.108.ko": "usr/lib/modules/rp.ko", + "@@@COMMON@@@/iosched-trampoline.sh": "sbin/modprobe", "@@@EXT@@@/virtio-3.10.108/virtio.ko": "lib/modules/", "@@@EXT@@@/virtio-3.10.108/virtio_ring.ko": "lib/modules/", "@@@EXT@@@/virtio-3.10.108/virtio_pci.ko": "lib/modules/", diff --git a/config/DS918+/6.2.4-25556/config.json b/config/DS918+/6.2.4-25556/config.json index 11d26b6b..8c3b5843 100644 --- a/config/DS918+/6.2.4-25556/config.json +++ b/config/DS918+/6.2.4-25556/config.json @@ -91,6 +91,7 @@ "compress_rd": false, "ramdisk_copy": { "@@@EXT@@@/rp-lkm/redpill-linux-v4.4.59+.ko": "usr/lib/modules/rp.ko", + "@@@COMMON@@@/iosched-trampoline.sh": "sbin/modprobe", "@@@EXT@@@/virtio-4.4.59+/virtio.ko": "lib/modules/", "@@@EXT@@@/virtio-4.4.59+/virtio_ring.ko": "lib/modules/", "@@@EXT@@@/virtio-4.4.59+/virtio_pci.ko": "lib/modules/", diff --git a/config/DS918+/7.0-41890/config.json b/config/DS918+/7.0-41890/config.json index b68dbc94..c99e78cb 100644 --- a/config/DS918+/7.0-41890/config.json +++ b/config/DS918+/7.0-41890/config.json @@ -91,6 +91,7 @@ "compress_rd": false, "ramdisk_copy": { "@@@EXT@@@/rp-lkm/redpill-linux-v4.4.180+.ko": "usr/lib/modules/rp.ko", + "@@@COMMON@@@/iosched-trampoline.sh": "sbin/modprobe", "@@@EXT@@@/virtio-4.4.180+/virtio.ko": "lib/modules/", "@@@EXT@@@/virtio-4.4.180+/virtio_ring.ko": "lib/modules/", "@@@EXT@@@/virtio-4.4.180+/virtio_pci.ko": "lib/modules/", diff --git a/config/_common/iosched-trampoline.sh b/config/_common/iosched-trampoline.sh new file mode 100644 index 00000000..69217918 --- /dev/null +++ b/config/_common/iosched-trampoline.sh @@ -0,0 +1,16 @@ +#!/usr/bin/sh +# This script is saved to /sbin/modprobe which is a so called UMH (user-mode-helper) for kmod (kernel/kmod.c) +# The kmod subsystem in the kernel is used to load modules from kernel. We exploit it a bit to load RP as soon as +# possible (which turns out to be via init/main.c => load_default_modules => load_default_elevator_module +# When the kernel is booted with "elevator=elevator" it will attempt to load a module "elevator-iosched"... and the rest +# should be obvious from the code below. DO NOT print anything here (kernel doesn't attach STDOUT) +for arg in "$@" +do + if [ "$arg" = "elevator-iosched" ]; then + insmod /usr/lib/modules/rp.ko + rm /usr/lib/modules/rp.ko + rm /sbin/modprobe + exit 0 + fi +done +exit 1 diff --git a/config/_common/v6/ramdisk-002-init-script.patch b/config/_common/v6/ramdisk-002-init-script.patch index 86b6ae4e..9b783ac5 100644 --- a/config/_common/v6/ramdisk-002-init-script.patch +++ b/config/_common/v6/ramdisk-002-init-script.patch @@ -1,14 +1,5 @@ --- a/linuxrc.syno +++ b/linuxrc.syno -@@ -3,6 +3,8 @@ - - echo "START /linuxrc.syno" - -+insmod /usr/lib/modules/rp.ko && rm /usr/lib/modules/rp.ko -+ - . /etc.defaults/rc.subr - - Mnt="/tmpRoot" @@ -153,6 +155,7 @@ # insert basic USB modules for detect f401/FDT echo "Insert basic USB modules..." diff --git a/config/_common/v7/ramdisk-002-NEW-init-script.patch b/config/_common/v7/ramdisk-002-NEW-init-script.patch index fb25e6dd..358b0b93 100644 --- a/config/_common/v7/ramdisk-002-NEW-init-script.patch +++ b/config/_common/v7/ramdisk-002-NEW-init-script.patch @@ -1,14 +1,5 @@ --- a/linuxrc.syno.impl +++ b/linuxrc.syno.impl -@@ -3,6 +3,8 @@ - - echo "START /linuxrc.syno.impl" - -+insmod /usr/lib/modules/rp.ko && rm /usr/lib/modules/rp.ko -+ - . /etc.defaults/rc.subr - . /usr/syno/share/environments.sh - . /usr/syno/share/util.sh @@ -138,6 +140,7 @@ fi # insert basic USB modules for detect f401/FDT echo "Insert basic USB modules..." diff --git a/config/_common/v7/ramdisk-002-OLD-init-script.patch b/config/_common/v7/ramdisk-002-OLD-init-script.patch index 311388ee..987ce6ae 100644 --- a/config/_common/v7/ramdisk-002-OLD-init-script.patch +++ b/config/_common/v7/ramdisk-002-OLD-init-script.patch @@ -1,14 +1,5 @@ --- a/linuxrc.syno +++ b/linuxrc.syno -@@ -3,6 +3,8 @@ - - echo "START /linuxrc.syno" - -+insmod /usr/lib/modules/rp.ko && rm /usr/lib/modules/rp.ko -+ - . /etc.defaults/rc.subr - . /usr/syno/share/environments.sh - @@ -137,6 +139,7 @@ # insert basic USB modules for detect f401/FDT echo "Insert basic USB modules..."