|
| 1 | +# DKMS Compatibility Guide |
| 2 | + |
| 3 | +Hyperion Kernel treats DKMS as a first-class citizen. This document explains |
| 4 | +how we guarantee external modules always build and load correctly. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## Why DKMS Breaks (General Causes) |
| 9 | + |
| 10 | +``` |
| 11 | + ┌─────────────────────────────────────────────────┐ |
| 12 | + │ DKMS Failure Root Causes │ |
| 13 | + ├─────────────────────────────────────────────────┤ |
| 14 | + │ 1. Kernel headers not installed │ |
| 15 | + │ 2. /lib/modules/$(uname -r)/build symlink wrong │ |
| 16 | + │ 3. Symbol versioning mismatch (MODVERSIONS) │ |
| 17 | + │ 4. Module not in correct path │ |
| 18 | + │ 5. Module signed but key not trusted │ |
| 19 | + │ 6. CONFIG_MODULE_COMPRESS mismatch │ |
| 20 | + └─────────────────────────────────────────────────┘ |
| 21 | +``` |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## Hyperion Config Settings That Prevent DKMS Failures |
| 26 | + |
| 27 | +### CONFIG_MODULES=y |
| 28 | +Modules are supported. Without this, no external module can ever load. |
| 29 | + |
| 30 | +### CONFIG_MODULE_UNLOAD=y |
| 31 | +Allows modules to be unloaded and reloaded — required for DKMS reinstall |
| 32 | +without a full reboot. |
| 33 | + |
| 34 | +### CONFIG_MODVERSIONS=y |
| 35 | +**The most critical DKMS setting.** |
| 36 | + |
| 37 | +Every exported kernel symbol gets a CRC checksum based on its type signature. |
| 38 | +When a module is loaded, the kernel checks: |
| 39 | +- Module's expected CRC for `symbol_foo` matches kernel's exported CRC |
| 40 | + |
| 41 | +If they don't match: `ERROR: Module was compiled for a different kernel version` |
| 42 | +(clean rejection at load time, **not** a silent panic). |
| 43 | + |
| 44 | +Without this: ABI changes cause silent corruption or random crashes. |
| 45 | + |
| 46 | +### CONFIG_KALLSYMS=y |
| 47 | +Symbol table is built into the kernel. Required for: |
| 48 | +- BPF programs |
| 49 | +- `perf` profiling |
| 50 | +- `crash` utility |
| 51 | +- Some DKMS modules that look up symbols dynamically |
| 52 | + |
| 53 | +### CONFIG_IKHEADERS=y |
| 54 | +**The DKMS fallback.** |
| 55 | + |
| 56 | +Embeds kernel headers as a compressed tarball at `/sys/kernel/kheaders.tar.xz`. |
| 57 | +When `/usr/src/linux-headers-*` is somehow missing or incomplete, DKMS can |
| 58 | +extract headers from this runtime path. |
| 59 | + |
| 60 | +Enabled in `hyperion.config`. Zero cost when not used. |
| 61 | + |
| 62 | +### CONFIG_DEVTMPFS=y + CONFIG_DEVTMPFS_MOUNT=y |
| 63 | +After a DKMS module is loaded, its device nodes must appear in `/dev/`. |
| 64 | +`devtmpfs` makes this automatic — the kernel creates the node as soon as the |
| 65 | +driver calls `device_create()`. |
| 66 | + |
| 67 | +Without this: driver loads, no `/dev/foo` appears, application fails silently. |
| 68 | + |
| 69 | +### CONFIG_MODULE_SIG=n (default) |
| 70 | +Module signing is **disabled by default** so DKMS can sign its own modules |
| 71 | +via its own key infrastructure without fighting the kernel's required-key chain. |
| 72 | + |
| 73 | +To enable for Secure Boot: see [docs/module-signing.md](module-signing.md). |
| 74 | + |
| 75 | +### CONFIG_MODULE_COMPRESS_NONE=y |
| 76 | +Modules are stored uncompressed. DKMS builds `.ko` files and needs to install |
| 77 | +them — compression adds a step that some older DKMS versions mishandle. |
| 78 | + |
| 79 | +--- |
| 80 | + |
| 81 | +## Installing Headers Correctly |
| 82 | + |
| 83 | +```bash |
| 84 | +cd linux-2.2.2 |
| 85 | + |
| 86 | +# Step 1: Install sanitised user-space API headers |
| 87 | +sudo make headers_install INSTALL_HDR_PATH=/usr |
| 88 | + |
| 89 | +# Step 2: Install build headers (what DKMS actually needs) |
| 90 | +sudo make modules_prepare |
| 91 | + |
| 92 | +# Step 3: Copy full headers directory |
| 93 | +KVER="2.2.2-Hyperion-2.2.2" |
| 94 | +sudo mkdir -p /usr/src/linux-headers-${KVER} |
| 95 | + |
| 96 | +# Copy all header files |
| 97 | +sudo cp -a . /usr/src/linux-headers-${KVER}/ |
| 98 | + |
| 99 | +# Step 4: Create the build symlink |
| 100 | +sudo ln -sfn /usr/src/linux-headers-${KVER} \ |
| 101 | + /lib/modules/${KVER}/build |
| 102 | + |
| 103 | +# Step 5: Create the source symlink (some modules need this too) |
| 104 | +sudo ln -sfn /usr/src/linux-headers-${KVER} \ |
| 105 | + /lib/modules/${KVER}/source |
| 106 | + |
| 107 | +# Verify |
| 108 | +ls -la /lib/modules/${KVER}/build |
| 109 | +# → /lib/modules/2.2.2-Hyperion-2.2.2/build -> /usr/src/linux-headers-2.2.2-Hyperion-2.2.2 |
| 110 | +``` |
| 111 | + |
| 112 | +The `install-headers.sh` script does all of this automatically. |
| 113 | + |
| 114 | +--- |
| 115 | + |
| 116 | +## Testing DKMS Compatibility |
| 117 | + |
| 118 | +```bash |
| 119 | +# 1. Check all registered modules |
| 120 | +sudo dkms status |
| 121 | + |
| 122 | +# 2. Force rebuild all modules for current kernel |
| 123 | +sudo dkms autoinstall -k $(uname -r) |
| 124 | + |
| 125 | +# 3. Test specific module |
| 126 | +sudo dkms install nvidia/550.54.14 -k $(uname -r) |
| 127 | + |
| 128 | +# 4. Verbose build to diagnose failures |
| 129 | +sudo dkms build -m v4l2loopback -v 2.2.2 -k $(uname -r) --verbose |
| 130 | + |
| 131 | +# 5. Check module loading |
| 132 | +sudo modprobe v4l2loopback |
| 133 | +lsmod | grep v4l2 |
| 134 | +dmesg | tail -10 |
| 135 | +``` |
| 136 | + |
| 137 | +--- |
| 138 | + |
| 139 | +## Example DKMS Workflows |
| 140 | + |
| 141 | +### NVIDIA Driver |
| 142 | + |
| 143 | +```bash |
| 144 | +# Install NVIDIA DKMS package |
| 145 | +sudo apt install nvidia-dkms-550 # Ubuntu/Debian |
| 146 | +sudo dnf install akmod-nvidia # Fedora (akmods variant) |
| 147 | + |
| 148 | +# Verify |
| 149 | +sudo dkms status | grep nvidia |
| 150 | +# nvidia/550.54.14, 2.2.2-Hyperion-2.2.2, x86_64: installed ✓ |
| 151 | + |
| 152 | +# Load |
| 153 | +sudo modprobe nvidia |
| 154 | +nvidia-smi |
| 155 | +``` |
| 156 | + |
| 157 | +### ZFS on Linux |
| 158 | + |
| 159 | +```bash |
| 160 | +sudo apt install zfs-dkms zfsutils-linux |
| 161 | +sudo dkms status | grep zfs |
| 162 | +sudo modprobe zfs |
| 163 | +zpool status |
| 164 | +``` |
| 165 | + |
| 166 | +### VirtualBox |
| 167 | + |
| 168 | +```bash |
| 169 | +sudo apt install virtualbox-dkms |
| 170 | +sudo dkms status | grep vbox |
| 171 | +sudo modprobe vboxdrv |
| 172 | +VBoxManage --version |
| 173 | +``` |
| 174 | + |
| 175 | +--- |
| 176 | + |
| 177 | +## Symbol Versioning — Deep Dive |
| 178 | + |
| 179 | +When `CONFIG_MODVERSIONS=y`, the kernel build generates `Module.symvers`. |
| 180 | +This file maps every exported symbol to a CRC hash: |
| 181 | + |
| 182 | +``` |
| 183 | +0xa1b2c3d4 put_user_pages_dirty_lock vmlinux EXPORT_SYMBOL |
| 184 | +0xb5c6d7e8 schedule vmlinux EXPORT_SYMBOL |
| 185 | +``` |
| 186 | + |
| 187 | +When a module is built against these headers, it records the expected CRC |
| 188 | +for each symbol it uses. At load time, the kernel compares the recorded CRC |
| 189 | +with the current kernel's CRC. |
| 190 | + |
| 191 | +**Hyperion provides** `Module.symvers` at: |
| 192 | +``` |
| 193 | +/usr/src/linux-headers-2.2.2-Hyperion-2.2.2/Module.symvers |
| 194 | +``` |
| 195 | + |
| 196 | +DKMS automatically uses this file during module builds via: |
| 197 | +```bash |
| 198 | +make -C /lib/modules/$(uname -r)/build M=$(pwd) modules |
| 199 | +``` |
0 commit comments