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}}.
== Developing 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>
== Load modules in the kernel ==
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>


== make menuconfig ==
== make menuconfig ==
Line 226: Line 156:
</syntaxHighlight>
</syntaxHighlight>


== Packaging ==
== Out-of-tree kernel modules ==
=== Packaging an out-of-tree kernel module ===
=== 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 ==