Linux Kernel Modules
Kernel modules are pieces of code that can be dynamically loaded or removed from the kernel without requiring a system reboot.
We created a simple example module to understand the process. This module merely writes a message to the kernel log when it is loaded and another message when it is unloaded.
To use this module, we create configuration symbols for it and then enable our module:
make -C "$IIO_TREE" menuconfig
After that, we clean up artifacts from previous builds:
cd "$IIO_TREE"
kw build --clean
And we build the image and modules again (this means compiling the source code):
cd "$IIO_TREE"
kw build
We also perform the module installation (which involves moving the modules to the correct location by mounting the VM disk, copying the modules there, and then unmounting):
mkdir "${VM_DIR}/arm64_rootfs"
# mount the VM `rootfs` to the given mount point in read and write mode (this could take a while)
sudo guestmount --rw --add "${VM_DIR}/arm64_img.qcow2" --mount /dev/vda2 "${VM_DIR}/arm64_rootfs"
# install modules to inside the VM
sudo --preserve-env make -C "${IIO_TREE}" INSTALL_MOD_PATH="${VM_DIR}/arm64_rootfs" modules_install
# unmount the VM `rootfs`
sudo guestunmount "${VM_DIR}/arm64_rootfs"
Then we start the VM and use SSH to access it. Inside the VM, we can verify our kernel version:
uname --all
cat /proc/version
And also check information about the installed module:
modinfo simple_mod
We can also check which modules are currently loaded:
lsmodmodprobe -r simple_mod
To load or unload our module, we use:
modprobe simple_mod # loads module of name `simple_mod`
dmesg | tail
modprobe -r simple_mod # unloads module of name `simple_mod`
dmesg | tail
Dependencies between kernel features
To understand the dependencies between modules, we took our initial module and had it export a function. We rebuilt the module and sent it to the VM. Then, we added a second module to call that function and performed all the necessary configurations for it as well. Upon loading this new module, we were able to observe it invoking the function in question
It wasn’t necessary to explicitly ask to load simple_mod if using modprobe. Ehen adding new modules we need to prepare them for inclusion or rebuild the whole kernel to get the modules correctly setup. After the modules have been setup, we can modify modules, build only those that were updated, copy them to the VM, update module dependancies with depmod, then test.
cd "$IIO_TREE"
kw build
kw ssh --send drivers/misc/simple_mod.ko
# inside vm:
cp simple_mod.ko /lib/modules/`uname -r`/kernel/drivers/misc/ # copy to modulos dir (install)
depmod --quick
modprobe simple_mod
modprobe -r simple_mod
dmesg | tail