Out-of-Tree Kernel Modules
This topic provides details on how to prepare, build, and load/unload out-of-tree kernel drivers.
Linux kernel modules can be loaded/unloaded in runtime, which allows for smaller core kernel images and more flexibles systems.
Also see Kernel Module Definition .mdef
Set Build Environment
To overcome a current deficiency in the Yocto kernel-dev package, you need to set the module build environment:
cd ./y17-ext/sysroots/armv7a-vfp-neon-poky-linux-gnueabi/usr/src/kernelARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- make scripts
Install Toolchain to Build Kernel Modules
This process involves changing the make configuration before you build the kernel, to do this it is recommended that you install another separate version of the toolchain for this purpose.
Create an install directory and open a Linux shell to ensure the top directory is known like this:
mkdir yocto-installcd yocto-installexport TOPDIR=${PWD}
Then download the appropriate toolchain for your environment from the Legato Downloads page. You can use wget
after you know the filename.
Ensure you have appropriate access to run the toolchain install script:
chmod 755 <toolchain filename>
Start installation:
./poky-swi-ext-glibc-x86_64-meta-toolchain-swi-ext-armv7a-vfp-neon-toolchain-swi-ext-1.7.3.sh
When asked type
, enter this:
Enter the target directory for SDK (default: /opt/swi/y17-ext): ./y17-ext
Then press <ENTER> twice:
- once to confirm the command
- once to answer "Y" to the following question.
Check to ensure the toolchain is in your path:
export PATH=$PATH:${PWD}/y17-ext/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi
It's recommended to add the toolchain path to your ~/
.profile file so it's available every time you log in.
Set Build Environment
To overcome a current deficiency in the Yocto kernel-dev package, you need to set the module build environment:
cd ./y17-ext/sysroots/armv7a-vfp-neon-poky-linux-gnueabi/usr/src/kernelARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- make scripts
Make Kernel Module
First, ensure the kernel module support root directory is known:
export B_KDIR=${PWD}cd $TOPDIR
Next, make an example kernel module directory, and go to it
mkdir kmodulecd kmodule
C File Example
Create a kernel file like this simple ktest_module.c
example:
#include <linux/module.h> /* Needed by all modules */#include <linux/kernel.h> /* Needed for KERN_INFO */#include <linux/init.h> /* Needed for the macros */static int __init ktest_module_init(void){printk(KERN_INFO "Driver version %s\n", VERSION);printk(KERN_INFO "Buona Sera :)\n");return 0;}static void __exit ktest_module_exit(void){printk(KERN_INFO "Ciao!\n");}module_init(ktest_module_init);module_exit(ktest_module_exit);
Makefile Example
Create a makefile
like this simple example:
# Kernel module build command for ARM targets is:# make ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi-## List of object file(s) to be builtobj-m+=ktest_module.o## Point to the directory containing sources for the kernel running on target# system. The kernel directory must have the configuration build step executed,# i.e. it must contain the target system's .config file.## Legato tools contain such a directory, point to it.KBUILD_DIR=/opt/swi/y17-ext/sysroots/armv7a-vfp-neon-poky-linux-gnueabi/usr/src/kernel## Kernel module build dependencyall:make -C $(KBUILD_DIR) M=$(PWD) modules## Kernel module clean dependencyclean:make -C $(KBUILD_DIR) M=$(PWD) clean
Build Kernel
Then add the example kernel module source ktest_module.c
file and its Makefile to kmodule
directory.
You're then ready to build the example kernel module:
make
You should then have a ktest_module.ko
located in kmodule directory.
- Warning
- Ensure the kernel sources version used to compile the module matches the kernel version running on the target.
- Note
- The
y17-ext
directory could be relocated to directory of your choice. If relocated,PATH
andB_KDIR
variables must be changed accordingly.
Load Driver
You can load the driver onto the target device manually or use Legato's mdef File Load.
Manual Load
This section shows how to:
- copy a module to a target
- manually install a module on a target
- remove a module from a target
This is how to use scp
to copy a kernel module (driver) onto the target:
scp ktest_module.ko root@$target_IP:/home/root/ktest_dir
This is how to install a module, and check it installed:
root@swi-mdm9x15:~/ktest_dir# insmod ktest_module.koroot@swi-mdm9x15:~/ktest_dir# lsmod |grep ktestktest_module 648 0 - Live 0xbf0eb000 (PO)
This is how to check the log file:
root@swi-mdm9x15:~/ktest_dir# logread |tail -n 2Nov 10 18:16:30 swi-mdm9x15 user.info kernel: [88600.728022] Driver version 1.0.0Nov 10 18:16:30 swi-mdm9x15 user.info kernel: [88600.728053] Buona Sera :)
This is how to remove the module, and check the log that it was removed:
root@swi-mdm9x15:~/ktest_dir# rmmod ktest_module.koroot@swi-mdm9x15:~/ktest_dir# logread |tail -n 2Nov 10 18:16:30 swi-mdm9x15 user.info kernel: [88600.728053] Buona Sera :)Nov 10 18:19:38 swi-mdm9x15 user.info kernel: [88789.028495] Ciao!root@swi-mdm9x15:~/ktest_dir#
mdef File Load
You can also use Legato's mdef
to load the pre-built kernel module.
Create Kernel Module Definition .mdef hello.mdef
file in any location with this preBuilt
section:
preBuilt: /path/to/kernel/module/ktest_module.ko
Modify $LEGATO_ROOT/system
.sdef (in Legato root dir) to include the kernelModule
path:
kernelModules:{ <path_to_hello.mdef> }
Build and Install
Then build and install Legato on a WP85 module.
If the driver load succeeds, a console log message like this should display:
Jul 14 17:58:28 swi-mdm9x15 user.info Legato: INFO | supervisor[23722]/supervisor T=main | kernelModules.c ModuleGetParams() 119 | Module ktest_module.ko uses no parameters.Jul 14 17:58:28 swi-mdm9x15 user.info Legato: INFO | supervisor[23722]/supervisor T=main | kernelModules.c ModuleInsert() 286 | New kernel module 'ktest_module'Jul 14 17:58:28 swi-mdm9x15 user.info kernel: [244746.908837] Driver version 1.0.0Jul 14 17:58:28 swi-mdm9x15 user.info kernel: [244746.911157] Buona Sera
Then use lsmod
on the target to check that your kernel module is listed (installed).
root@swi-mdm9x15:~# lsmodktest_module 648 0 - Live 0xbf0c0000 (O) <===============ipv6 290588 14 [permanent], Live 0xbf060000usb_storage 41365 0 - Live 0xbf04c000sd_mod 29567 0 - Live 0xbf03f000scsi_mod 133355 2 usb_storage,sd_mod, Live 0xbf00d000unix 29432 659 - Live 0xbf000000