Linux won't autoload kernel module - embedded-linux

I created a basic kernel module that I plan to use eventually for a timing analysis. I am running a v4.14.149 mainline kernel and am building it with Yocto Zeus running on an i.MX6 target. I can't seem to get it to launch automatically.
Everything compiles fine, and I see my testmodule.ko show up in /lib/modules/4.14.149/extras/ on target. I can load it and unload it just fine with insmod and rmmod so I am pretty sure the module is OK. I also see a testmodule.conf file that contains the module name (testmodule) in /etc/modules-load.d/ but when I boot and do a lsmod I don't see it loaded. I also don't see any output in journalctl that would indicate that it loaded.
I have looked at and tried Yocto: Adding kernel module recipe to image, but it doesn't load on boot and Yocto load kernel module and have added KERNEL_MODULE_AUTOLOAD += "testmodule" in my machine configuration and I also tried it in the module recipe to no avail. I am including the module in my image recipe via IMAGE_INSTALL_append as kernel-module-test.
Here is the recipe for my module:
SUMMARY = "Test kernel module"
LICENSE = "CLOSED"
inherit module
SRC_URI = "file://Makefile \
file://testmodule.c"
S = "${WORKDIR}"
KERNEL_MODULE_AUTOLOAD += "testmodule"
RPROVIDES_${PN} += "kernel-module-test"
The module code at the moment just prints a message (it was a sample from a Yocto book I had) and that is it:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
/*
** Module Init function
*/
static int hello_world_init(void)
{
printk("Markem Kernel Module Inserted Successfully...\n");
return 0;
}
/*
** Module Exit function
*/
static void hello_world_exit(void)
{
printk("Markem Kernel Module Removed Successfully...\n");
}
module_init(hello_world_init);
module_exit(hello_world_exit);
MODULE_LICENSE("Proprietary");
/*
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("A test module.");
MODULE_AUTHOR("Markem-Imaje Corporation");
*/
And lastly the Makefile, which is also based on the Yocto Book sample
obj-m := testmodule.o
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
If you need the recipe for my kernel or my machine conf or anything, I can get those. Everything I have read indicates that having the file in /etc/modules-load.d/ indicates it should load automatically. Is there possibly a kernel configuration I am missing or something?

Related

Yocto Transaction Test, two recipes install the same file

I am adding a custom recipe to my image. It is bases on DBCPPP. This project is built using cmake. My issue only comes to light when I include a new layer meta-swupdate. It seems meta-swupdate alters the kernel in a way that conflicts with dbcppp. My full error is:
Error: Transaction test error:
file /usr/lib/libxml2.so.2.9.10 conflicts between attempted installs of dbcppp-1.0+gitr0+fa8ce17468-r0.cortexa7t2hf_neon and libxml2-2.9.10-r0.cortexa7t2hf_neon
To build and include dbcppp I added the recipe:
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "gitsm://github.com/xR3b0rn/dbcppp.git;protocol=https;branch=master"
PV = "1.0+gitr${SRCPV}"
SRCREV = "${AUTOREV}"
DEPENDS += " boost"
S = "${WORKDIR}/git"
inherit pkgconfig cmake
FILES_${PN} += "/usr/lib/xml2Conf.sh /usr/lib/lib*.so.*"
SOLIBS = ".so"
FILES_SOLIBSDEV = ""
INSANE_SKIP_${PN} += "dev-so"
I have read a few other questions and attempted two solutions by adding a do_install_append step.
Change folder permission level install -d 0755 ${D}/usr/lib
Remove the folder rm -rf ${D}/usr/lib
Neither solution worked. I need both libraries in my application and I unsure how to proceed.
Edit: After some further reading I found a suggestion to delete the tmp, cache, and sstate-chace folders. I did this but I receive the same error.
Edit: My local.conf has PACKAGE_CLASSES ?= 'package_rpm' defined. if I remove this I still get a do_rootfs error, but the error message is not helpful.
Edit: In my recipe for dbcppp I have attempted to remove the file in question. This gives me the same error. Makes no difference.
do_install_append() {
rm -rf /usr/lib/libxml2.so.2.9.10
}

How to debug kernel code without running kernel?

I'm reading some kernel books, I want to debug the spinlock_t usage, and prepared the following demo code:
////////////////////////////
// demo/spinlock.c
////////////////////////////
#include <linux/spinlock.h>
struct obj {
spinlock_t spinlock;
}
int demo0() {
struct obj o;
spin_lock_init(o.spinlock);
}
int main(){
demo0();
}
The Makefile seems like:
######################
# demo/Makefile
######################
demo: spinlock.c
gcc -o spinlock spinlock.c -I../linux-5.6.9/arch/x86/include -I../linux-5.6.9/include
The file tree seems like this
├── demo
└── linux-5.6.9
While meke, it gave me tones of errors (too many, I can't enumerate them here), It seems like that I missed some GCC CFLAGS or others.
How to debug kernel code line by line? Most of Google results are GDB/Qemu debugging within running kernel. Is there any suggestions to debug the kernel code without running the kernel?

libtool: what is the path to my module?

I am creating a module from an autotools+libtool project:
The Makefile.am looks as follows
#the module:
lib_LTLIBRARIES = mmmm.la
mmmm_la_SOURCES = mmmm.c
mmmm_la_LDFLAGS = $(AM_LDFLAGS) -module -shared
Now, I want to write a C test for my module. The test should start loading the shared object mmmm.xx (where .xx is .so or .la)
What path should I give to dlopen() or lt_dlopen() in my C test?: The relative location of my module (compared to the test program) is different depending on whether I do make check, an out of tree make check, or a make installcheck...
I tried with lt_dlopen() hoping that the -dlopen option passed on the test Makefile.am would help autotools to locate the lib when lt_dlopen() is called, but it does not seem to help: lt_dlopen() can open the .la file, indeed, but one still have to tell where that file is located (possibly ommiting the .libs directory)
My test makefile looks like this when testing with the ltdl lib:
#the module test (tests are also installed, hence the "test" prefix)
test_PROGRAMS = tttt
tttt_SOURCES = tttt.c
tttt_LDADD = "-dlopen" mmmm.la
tttt_DEPENDENCIES = mmmm.la
Any good hint?
One way you can deal with that is to set up the LD_LIBRARY_PATH env variable to where your library will be installed.
However, since you need it for the tests I will say export a variable from the configure.ac to the config.h. Thus, any file including the config.h would have a #define your_variable which can be used to set up the path for dlopen.

How to include directories when building Arduino software

I'm making a small Arduino project. The official Arduino IDE is really terrible, so I'm using Netbeans to develop instead. This is my makefile:
OBJDIR = ../build
ARDUINO_DIR = /usr/share/arduino
TARGET = main
MCU = atmega328p
F_CPU = 16000000
ARDUINO_PORT = /dev/ttyACM0
AVRDUDE_ARD_PROGRAMMER = arduino
AVRDUDE_ARD_BAUDRATE = 115200
include /usr/share/arduino/Arduino.mk
I want to use some headers located in /usr/local/include/myproject, so in the source code I add:
#include "myproject/someheader.h"
Now, when I try to compile the project, I get an error saying
fatal error: myproject/someheader.h: No such file or directory
How can I include the /usr/local/include directory when building the project? Normally, I'd add
INC=-I/usr/local/include
But that's not working, I guess I need to add the header files some other way?
Ended up adding a symbolic link from the arduino directory to the location of my library:
ln -s /usr/local/include /usr/share/arduino/libraries/Custom
Then, I added the "Custom" "library" to the arduino makefile, my makefile is now:
OBJDIR = ../build
ARDUINO_DIR = /usr/share/arduino
TARGET = main
MCU = atmega328p
F_CPU = 16000000
ARDUINO_PORT = /dev/ttyACM0
AVRDUDE_ARD_PROGRAMMER = arduino
AVRDUDE_ARD_BAUDRATE = 115200
ARDUINO_LIBS = Custom # <---- !
include /usr/share/arduino/Arduino.mk
The build process seems to obtain my header files now

How to use an own device tree and modified kernel config in Yocto?

I am working to build an own "embeeded linux" with yocto. It is based on the SAMA5D3x-MB + SAMA5D3x-CM(RONETIX) with the SAMA5D35. I have two questions:
1.) changing the device tree
I build an image based on: MACHINE ??= "sama5d3xek"
After the generating process I found two device tree files for the 5D35 in the deploy dir:
zImage--4.1+git0+19291d7be4-r0-sama5d35ek-.dtb
zImage--4.1+git0+19291d7be4-r0-sama5d35ek-revc-.dtb
Because the mainboard is revD I am using zImage--4.1+git0+19291d7be4-r0-sama5d35ek-.dtb.
In this file only can0 and i2c1 are defined.
I like to use can1 and i2c0 as well. For that I think I need to create a own dts file and include it into the kernel build process.
So far I put the dts file at my meta-test recipe. Ideas how to copy/patch it into the kernel?
2.) changing the kernel config
I checked the kernel with
bitbake virtual/kernel -c menuconfig
because I am not using the SAMA5D2 etc. and only the console I deactivated these kernel configs. I saved the new ".config" to "my.config" into the my-recipe dir. I have a similar question like in 1 - How to patch/copy it into the kernel?
I am new to yocto and to kernel hacking. Any idea how to do it?
If you're on a recent Yocto project release, you can make use of recipetool to do most of the legwork on this. You have two options, you can use the existing recipetool commands and a small amount of manual work, or you can use the recipetool plugin in meta-mentor that provides a few kernel-specific commands to do this for you.
Layer setup
First, you'll want to have a layer to store your changes. If you've already created a layer, you can use that, otherwise we can create one and add it to our configuration:
$ yocto-layer create local 1
$ bitbake-layers add-layer meta-local
Option one: Using the recipetool plugin from meta-mentor
Setup
First, clone meta-mentor:
$ git clone https://github.com/MentorEmbedded/meta-mentor
Next, either add meta-mel to your configuration:
$ bitbake-layers add-layer path/to/meta-mentor/meta-mel
Or copy meta-mentor/meta-mel/lib into your own layer:
$ cp -a path/to/meta-mentor/meta-mel/lib meta-local/
Device tree
$ recipetool kernel_add_dts meta-local /path/to/your.dts
Kernel configuration
$ recipetool kernel_add_fragments meta-local /path/to/your.cfg
Or:
$ recipetool kernel_set_defconfig meta-local /path/to/the/defconfig
Option two: Manual
In the below section, clearly in your case, your-machine-name should be sama5d3xek. The '-m your-machine-name' passed to the recipetool commands below makes the changes in the recipe specific to your machine, rather than affecting any machine which uses that recipe. If you know that recipe is only used for your machine, then you could drop that, but it's safest to keep it, as some BSP layers use the same kernel recipe for multiple machines. For example, linux-yocto is used for many.
Device tree
Then, assuming you have a .dts handy you want to use:
$ recipetool appendsrcfile -wm your-machine-name path/to/meta-local virtual/kernel /path/to/your.dts 'arch/${ARCH}/boot/dts/your.dts'
This will create a .bbappend in meta-local and add the .dts to SRC_URI, placing it in the appropriate path in the kernel source tree. The next step is to edit the append it created and add the .dtb for your .dts to the KERNEL_DEVICETREE variable, i.e.:
KERNEL_DEVICETREE += "your.dtb"
If the kernel recipe includes recipes-kernel/linux/linux-dtb.inc, any .dtb files in KERNEL_DEVICETREE will be created from their .dts files by using the kernel's buildsystem. Some kernels do not include linux-dtb.inc, in which case you can do so yourself in the append:
require recipes-kernel/linux/linux-dtb.inc
Kernel configuration
The kernel configuration is slightly more complex, just because how the configuration is done varies slightly between kernel recipes. Some kernel recipes support configuration fragments (which are just a text file with part of a defconfig/.config), whereas others you'd have to override the configuration entirely. The 'linux-yocto' recipe can handle and use fragments, as can a few others.
To see what kernel recipe you're using (the top filename will be the one used):
$ bitbake -e virtual/kernel | grep '^FILE='
If you want to use configuration fragments, you can either manually create a fragment, or generate one:
$ bitbake -c menuconfig virtual/kernel
$ bitbake -c diffconfig virtual/kernel
The 'diffconfig' task will create a fragment with your changes from the menuconfig and print the path to it.
Then you can add it to the kernel (though again, only certain recipes will use it):
$ recipetool appendsrcfile -wWm your-machine-name meta-local virtual/kernel /path/to/your.cfg
To override the entire config, most recipes will obey and use a 'defconfig' source file, so:
$ recipetool appendsrcfile -Wm your-machine-name meta-local virtual/kernel /path/to/the/defconfig
Note: The defconfig is not generated automatic. Replace defconfig with the result of menuconfig('.config').
The devtool can be very handy if you want to generate patches for the linux-yocto kernel. Other kernel might not support devtool.
## create kernel source patch
devtool modify virtual/kernel
# make some changes
cd ~/poky_sdk/workspace/sources/linux-yocto
vi init/calibrate.c
# test before patch
bitbake -C compile virtual/kernel
# create patch
git add .
git commit -m 'some fix'
devtool update-recipe -a ~/meta-mylayer/ linux-yocto
# clean the source
rm -rf workspace/sources/linux-yocto/
see devtool for details
Related to this question, for educational purposes I tried to add a device tree to an x86 architecture (kernel 5.2.20). To enable the device tree compiler, the following additions to the configuration were needed :
CONFIG_COMPILE_TEST=y
CONFIG_OF=y
CONFIG_OF_ALL_DTBS=y
Furthermore, to enable device tree support at runtime, this was additionally needed :
CONFIG_OF_UNITTEST=y
A convenient place to check if your kernel configs are merged without problems is file
kernel-source/.kernel-meta/cfg/merge_config_build.log

Resources