mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 01:59:07 +00:00
Merge pull request #1765 from rneugeba/kmod
Add support for building custom kernel modules
This commit is contained in:
commit
ba6c210029
@ -36,6 +36,35 @@ In summary, LinuxKit offers a choice of the following kernels:
|
|||||||
- [linuxkit/kernel-fedora](https://hub.docker.com/r/linuxkit/kernel-fedora/): Selected Fedora kernels.
|
- [linuxkit/kernel-fedora](https://hub.docker.com/r/linuxkit/kernel-fedora/): Selected Fedora kernels.
|
||||||
|
|
||||||
|
|
||||||
|
## Compiling kernel modules
|
||||||
|
|
||||||
|
The LinuxKit kernel packages include `kernel-dev.tar` which contains
|
||||||
|
the headers and other files required to compile kernel modules against
|
||||||
|
the specific version of the kernel. Currently, the headers are not
|
||||||
|
included in the initial RAM disk, but it is possible to compile custom
|
||||||
|
modules offline and include then include the modules in the initial
|
||||||
|
RAM disk.
|
||||||
|
|
||||||
|
There is a [example](../tests/kmod), but basically one can use a
|
||||||
|
multi-stage build to compile the kernel modules:
|
||||||
|
```
|
||||||
|
FROM linuxkit/kernel:4.9.x AS ksrc
|
||||||
|
# Extract headers and compile module
|
||||||
|
FROM linuxkit/kernel-compile:1b396c221af673757703258159ddc8539843b02b@sha256:6b32d205bfc6407568324337b707d195d027328dbfec554428ea93e7b0a8299b AS build
|
||||||
|
COPY --from=ksrc /kernel-dev.tar /
|
||||||
|
RUN tar xf kernel-dev.tar
|
||||||
|
|
||||||
|
# copy module source code and compile
|
||||||
|
```
|
||||||
|
|
||||||
|
To use the kernel module, we recommend adding a final stage to the
|
||||||
|
Dockerfile above, which copies the kernel module from the `build`
|
||||||
|
stage and performs a `insmod` as the entry point. You can add this
|
||||||
|
package to the `onboot` section in your YAML
|
||||||
|
file. [kmod.yml](../tests/kmod/kmod.yml) contains an example for the
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
|
||||||
## Working with Linux kernel patches for LinuxKit
|
## Working with Linux kernel patches for LinuxKit
|
||||||
|
|
||||||
We may apply patches to the Linux kernel used in LinuxKit, primarily to
|
We may apply patches to the Linux kernel used in LinuxKit, primarily to
|
||||||
|
@ -53,9 +53,13 @@ RUN DVER=$(basename $(find /tmp/kernel-modules/lib/modules/ -mindepth 1 -maxdept
|
|||||||
dir=/tmp/usr/src/linux-headers-$DVER && \
|
dir=/tmp/usr/src/linux-headers-$DVER && \
|
||||||
mkdir -p $dir && \
|
mkdir -p $dir && \
|
||||||
cp /linux/.config $dir && \
|
cp /linux/.config $dir && \
|
||||||
cd /linux && \
|
cp /linux/Module.symvers $dir && \
|
||||||
cp -a include "$dir" && \
|
find . -path './include/*' -prune -o \
|
||||||
mkdir -p "$dir"/arch/x86 && cp -a arch/x86/include "$dir"/arch/x86/ && \
|
-path './arch/*/include' -prune -o \
|
||||||
|
-path './scripts/*' -prune -o \
|
||||||
|
-type f \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
|
||||||
|
-name '*.lds' -o -name '*.pl' -o -name '*.sh' \) | \
|
||||||
|
tar cf - -T - | (cd $dir; tar xf -) && \
|
||||||
( cd /tmp && tar cf /out/kernel-dev.tar usr/src )
|
( cd /tmp && tar cf /out/kernel-dev.tar usr/src )
|
||||||
|
|
||||||
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /out/kernel-source-info
|
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /out/kernel-source-info
|
||||||
|
21
test/kmod/Dockerfile
Normal file
21
test/kmod/Dockerfile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# This Dockerfile extracts the kernel headers from the kernel image
|
||||||
|
# and then compiles a simple hello world kernel module against them.
|
||||||
|
# In the last stage, it creates a package, which can be used for
|
||||||
|
# testing.
|
||||||
|
|
||||||
|
FROM linuxkit/kernel:4.9.x AS ksrc
|
||||||
|
|
||||||
|
# Extract headers and compile module
|
||||||
|
FROM linuxkit/kernel-compile:1b396c221af673757703258159ddc8539843b02b@sha256:6b32d205bfc6407568324337b707d195d027328dbfec554428ea93e7b0a8299b AS build
|
||||||
|
COPY --from=ksrc /kernel-dev.tar /
|
||||||
|
RUN tar xf kernel-dev.tar
|
||||||
|
|
||||||
|
WORKDIR /kmod
|
||||||
|
COPY ./src/* ./
|
||||||
|
RUN make all
|
||||||
|
|
||||||
|
# Package
|
||||||
|
FROM alpine:3.5
|
||||||
|
COPY --from=build /kmod/hello_world.ko /
|
||||||
|
COPY check.sh /check.sh
|
||||||
|
ENTRYPOINT ["/bin/sh", "/check.sh"]
|
15
test/kmod/check.sh
Executable file
15
test/kmod/check.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
function failed {
|
||||||
|
printf "Kernel module test suite FAILED\n"
|
||||||
|
/sbin/poweroff -f
|
||||||
|
}
|
||||||
|
|
||||||
|
uname -a
|
||||||
|
modinfo hello_world.ko || failed
|
||||||
|
insmod hello_world.ko || failed
|
||||||
|
[ -n "$(dmesg | grep -o 'Hello LinuxKit')" ] || failed
|
||||||
|
rmmod hello_world || failed
|
||||||
|
|
||||||
|
printf "Kernel module test suite PASSED\n"
|
||||||
|
|
||||||
|
/sbin/poweroff -f
|
17
test/kmod/kmod.yml
Normal file
17
test/kmod/kmod.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
kernel:
|
||||||
|
image: "linuxkit/kernel:4.9.x"
|
||||||
|
cmdline: "console=ttyS0"
|
||||||
|
init:
|
||||||
|
- linuxkit/init:63eed9ca7a09d2ce4c0c5e7238ac005fa44f564b
|
||||||
|
- linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
|
||||||
|
- linuxkit/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b
|
||||||
|
onboot:
|
||||||
|
- name: check
|
||||||
|
image: "kmod-test"
|
||||||
|
binds:
|
||||||
|
- /dev:/dev
|
||||||
|
- /lib/modules:/lib/modules
|
||||||
|
capabilities:
|
||||||
|
- all
|
||||||
|
outputs:
|
||||||
|
- format: kernel+initrd
|
10
test/kmod/run_test.sh
Executable file
10
test/kmod/run_test.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# Make sure we have the latest kernel image
|
||||||
|
docker pull linuxkit/kernel:4.9.x
|
||||||
|
# Build a package
|
||||||
|
docker build -t kmod-test .
|
||||||
|
# Build a LinuxKit image with kernel module (and test script)
|
||||||
|
moby build kmod
|
||||||
|
# Run it
|
||||||
|
linuxkit run kmod
|
6
test/kmod/src/Makefile
Normal file
6
test/kmod/src/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
obj-m += hello_world.o
|
||||||
|
KVER=$(shell basename /usr/src/linux-headers-*)
|
||||||
|
all:
|
||||||
|
make -C /usr/src/$(KVER) M=$(PWD) modules
|
||||||
|
clean:
|
||||||
|
make -C /usr/src/$(KVER) M=$(PWD) clean
|
22
test/kmod/src/hello_world.c
Normal file
22
test/kmod/src/hello_world.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* A simple Hello World kernel module
|
||||||
|
*/
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
|
int init_hello(void)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "Hello LinuxKit\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit_hello(void)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "Goodbye LinuxKit.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(init_hello);
|
||||||
|
module_exit(exit_hello);
|
||||||
|
MODULE_AUTHOR("Rolf Neugebauer <rolf.neugebauer@docker.com>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_DESCRIPTION("A simple Hello World kernel module for testing");
|
Loading…
Reference in New Issue
Block a user