Linux kernel: Difference between revisions
imported>Mic92 fix captilization |
imported>Artturin Restructure |
||
Line 97: | Line 97: | ||
{{bc|note: keeping build directory '/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0'}} | {{bc|note: keeping build directory '/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0'}} | ||
by opening {{ic|/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0/.attr-0}}. | by opening {{ic|/tmp/nix-build-linux-config-4.19.0-mptcp_v0.94.1.drv-0/.attr-0}}. | ||
== make menuconfig == | == make menuconfig == | ||
Line 226: | Line 156: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
== | == Out-of-tree kernel modules == | ||
=== Packaging | === Packaging out-of-tree kernel modules === | ||
There are a couple of steps that you will most likely need to do a couple of things. Here is an annotated example: | There are a couple of steps that you will most likely need to do a couple of things. Here is an annotated example: | ||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
Line 272: | Line 202: | ||
5. Lastly it is required to give the kernel build system the right location where to install the kernel module. This is done by setting <code>INSTALL_MOD_PATH</code> to <code>$out</code> Otherwise an error like <code>mkdir: cannot create directory '/lib': Permission denied</code> is generated. | 5. Lastly it is required to give the kernel build system the right location where to install the kernel module. This is done by setting <code>INSTALL_MOD_PATH</code> to <code>$out</code> Otherwise an error like <code>mkdir: cannot create directory '/lib': Permission denied</code> is generated. | ||
== Developing out-of-tree kernel modules == | |||
See also: {{manual:nixos|sec=#sec-linux-config-developing-modules|chapter=12.2. Developing kernel modules}} | |||
If you work on an out-of-tree kernel module the workflow could look as follow: | |||
<syntaxHighlight lang="C"> | |||
#include <linux/module.h> | |||
#define MODULE_NAME "hello" | |||
static int __init hello_init(void) | |||
{ | |||
printk(KERN_INFO "hello world!\n"); | |||
return 0; | |||
} | |||
static void __exit hello_cleanup(void) { | |||
printk(KERN_INFO "bye world!\n"); | |||
} | |||
module_init(hello_init); | |||
module_exit(hello_cleanup); | |||
</syntaxHighlight> | |||
<syntaxHighlight lang="Make"> | |||
obj-m += hello.o | |||
</syntaxHighlight> | |||
<syntaxHighlight lang="console> | |||
$ nix-shell '<nixpkgs>' -A linux.dev | |||
$ make -C $(nix-build -E '(import <nixpkgs> {}).linux.dev' --no-out-link)/lib/modules/*/build M=$(pwd) modules | |||
$ insmod ./hello.ko | |||
$ dmesg | grep hello | |||
[ 82.027229] hello world! | |||
</syntaxHighlight> | |||
== Loading out-of-tree kernel modules == | |||
As far as I understand, if you developed a kernel module, you should end up with having some <code>.ko</code> files inside a subfolder inside <code>$out/lib/modules/${kernel.modDirVersion}</code>. Now, if you want to make your module loadable inside the kernel by <code>modprobe</code>, you should do: | |||
<syntaxHighlight lang=nix> | |||
boot.extraModulePackages = [ yourmodulename ]; | |||
</syntaxHighlight> | |||
Then, the user can load it using: | |||
<syntaxHighlight lang=console> | |||
$ sudo modprobe yourmodulename | |||
</syntaxHighlight> | |||
or unload it using | |||
<syntaxHighlight lang=console> | |||
$ sudo modprobe -r yourmodulename | |||
</syntaxHighlight> | |||
However, if you want to autoload your module at startup in stage 2, you need to do: | |||
<syntaxHighlight lang=nix> | |||
boot.kernelModules = [ "yourmodulename" ]; | |||
</syntaxHighlight> | |||
and the module will be automatically loaded after a reboot. If you want instead to load it at stage 1 (before the root is even mounted), you need to add it to <code>boot.initrd.availableKernelModules</code> and <code>boot.initrd.kernelModules</code>. | |||
Note that if you don't reboot, you can still load manually the module using <code>modprobe yourmodulename></code>, and to automatically enable a module during configuration switch/reboot, you can put <code>modprobe yourmodulename || true</code> inside the script of a systemctl service (it is for example what does wireguard). | |||
Finally, if you want to define some options by default (used when you load manually a module using <code>modprobe</code>, or when the system boots), you can specify them in: | |||
<syntaxHighlight lang=nix> | |||
boot.extraModprobeConfig = '' | |||
options yourmodulename optionA=valueA optionB=valueB | |||
''; | |||
</syntaxHighlight> | |||
== See also == | == See also == |