Skip to content

Commit

Permalink
Convert LKM loading to I/O scheduler with trampoline
Browse files Browse the repository at this point in the history
  • Loading branch information
ttg-public committed Jan 1, 1970
1 parent a44ab47 commit 5a91059
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 31 deletions.
27 changes: 23 additions & 4 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ 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.

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"
Expand Down Expand Up @@ -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:

```
Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions config/DS3615xs/6.2.4-25556/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/",
Expand Down
1 change: 1 addition & 0 deletions config/DS3615xs/7.0-41222/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/",
Expand Down
1 change: 1 addition & 0 deletions config/DS918+/6.2.4-25556/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/",
Expand Down
1 change: 1 addition & 0 deletions config/DS918+/7.0-41890/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/",
Expand Down
16 changes: 16 additions & 0 deletions config/_common/iosched-trampoline.sh
Original file line number Diff line number Diff line change
@@ -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
9 changes: 0 additions & 9 deletions config/_common/v6/ramdisk-002-init-script.patch
Original file line number Diff line number Diff line change
@@ -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..."
Expand Down
9 changes: 0 additions & 9 deletions config/_common/v7/ramdisk-002-NEW-init-script.patch
Original file line number Diff line number Diff line change
@@ -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..."
Expand Down
9 changes: 0 additions & 9 deletions config/_common/v7/ramdisk-002-OLD-init-script.patch
Original file line number Diff line number Diff line change
@@ -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..."
Expand Down

0 comments on commit 5a91059

Please sign in to comment.