For testing purposes, I am using the example recipe provided by yocto to demonstrate how to build kernel modules.
SUMMARY = "Example of how to build an external Linux kernel module"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e"
inherit module
PR = "r0"
PV = "0.1"
SRC_URI = "file://Makefile \
file://hello.c \
file://COPYING \
"
S = "${WORKDIR}"
# The inherit of module.bbclass will automatically name module packages with
# "kernel-module-" prefix as required by the oe-core build environment.
The hello.c file is very simple.
#include <linux/module.h>
int init_module(void)
{
printk("Hello World!\n");
return 0;
}
void cleanup_module(void)
{
printk("Goodbye Cruel World!\n");
}
MODULE_LICENSE("GPL");
Now, I added this module to my image recipe.
SUMMARY = "A console-only image that fully supports the target device \
hardware."
IMAGE_FEATURES += "splash package-management"
IMAGE_INSTALL += "test-mod autoconf automake binutils make busybox"
LICENSE = "MIT"
inherit core-image
When I boot the image, I see the test "hello.ko" in the /lib/modules directory, but when I check dmesg, I don't see the output indicating the kernel module loaded.
When I manually run insmod on hello.ko, I get the output. Also, when I run rmmod, I get the output.
What am I doing wrong? I need this module to auto load on boot.
edit:
Here the output, verifying that the module isn't loaded on boot, but it is a valid module.
/ # dmesg | grep "Hello"
/ # insmod hello.ko
[ 68.503689] Hello World!
/ # rmmod hello.ko
[ 72.702035] Goodbye Cruel World!
You should add your module name to KERNEL_MODULE_AUTOLOAD in your recipe, typically like this:
KERNEL_MODULE_AUTOLOAD += "hello"
This should put your module name into /etc/modules-load.d/modname.conf on the image.
Related
Hello I am trying to create an custom application where I can read and write to the files. I can use it using stdio.h library in C code. How can use this operation while building with yocto. I can create an executable, when the flash the image on my microcontroller built with my application it says there is no input files (Yocto dosnt do file handling)
Do i need to do kernel configuration? (If yes how should i do it)
inherit autotools pkgconfig
inherit meson
PRIORITY = "optional"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://appxyz/"
S = "${WORKDIR}"
B = "${WORKDIR}/build_dir"
MESON_SOURCEPATH = "${S}/appxyz"
do_install() {
install -d ${D}${bindir}
install -d ${D}${libdir}
install -m 0755 ${B}/appxyz ${D}${bindir}
}
FILES_${PN} += "${bindir}/ ${bindir}/appxyz"
This is recipe for my application, appxyz is the executable, how can change it to reading files?
I have to work with RIOT OS and currently I'm testing out how everything
works (or not work).
Info: RIOT OS is a IOT OS which run on mircocontrollers and arms.
I develop under Debian with Eclispe, the develop environment was setup after the GitHub Guide from RIOT. The Guide
The hello world example works for me without problems.
Now I want to load some of the RIOT modules and then I get errors.
That's what I did so far.
I created a new folder for my project, copy the hello-world example and
adjust the makefile.
Then I adjust the riot project properties like in the guide, just for my example.
Created the new symbol and include xml and imported them.
Re-indexed the riot project
Changed the basic hello world code with my example code.
Try to build it....
This is my example main, it doesn't do much, just init a gpio pin.
#include <stdio.h>
#include "periph/gpio.h"
int main(void)
{
gpio_t pin = GPIO(1,22);
gpio_init(pin,GPIO_OUT);
return 0;
}
And this is the makefile for it
# name of your application
APPLICATION = test
# If no BOARD is found in the environment, use this default:
BOARD ?= nucleo-f303
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
FEATURES_REQUIRED = periph_gpio
include $(RIOTBASE)/Makefile.include
By building the project I get following errors:
In english it would be something like:
- the rule for target "path" failed.
- the rule for target "link" failed.
- make: [link] error 2
- make(1): ["path/main.o"] error 1
This is the part in the riot makefile where the error happen.
Its exactly the same in both file (Makefile.include and Makefile.base).
I hope anybody can me explain what I did wrong or where are my mistakes.
EDIT:
The problem was GPIO() was wrong... its called GPIO_PIN() thats cause the error.
I am working on yocto, I want to compile some C files in yocto and install the resulting binary to external filesystem.
Before doing that I tried creating a separate reciepe and compile c code from it.
I am unable to compile it.
I am not sure to understand the question since it is not precise enough.
Including C files in recipe tree
If you want to have the C files in your recipe, having a file tree like this:
recipe-example/example/example_0.1.bb
recipe-example/example/example-0.1/helloworld.c
You can generate this example when you create a new layer using
yocto-layer <your-layer-name>
Your bb file will look like this:
#
# This file was derived from the 'Hello World!' example recipe in the
# Yocto Project Development Manual.
#
SUMMARY = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"
do_compile() {
${CC} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
It will compile the hello world file and install it into /usr/bin on your image.
From a Git repo
You also can compile from a git repository, I advise you to read the manual and examples in your yocto folder. Here is an example here of wiringPi:
DESCRIPTION = "A library to control Raspberry Pi GPIO channels"
HOMEPAGE = "https://projects.drogon.net/raspberry-pi/wiringpi/"
SECTION = "devel/libs"
LICENSE = "LGPLv3+"
LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=e6a600fd5e1d9cbde2d983680233ad02"
# tag 2.29
SRCREV = "d79506694d7ba1c3da865d095238289d6175057d"
S = "${WORKDIR}/git"
SRC_URI = "git://git.drogon.net/wiringPi \
file://0001-Add-initial-cross-compile-support.patch \
file://0001-include-asm-ioctl.h-directly-for-_IOC_SIZEBITS.patch \
"
COMPATIBLE_MACHINE = "raspberrypi"
CFLAGS_prepend = "-I${S}/wiringPi -I${S}/devLib"
EXTRA_OEMAKE += "'INCLUDE_DIR=${D}${includedir}' 'LIB_DIR=${D}${libdir}'"
EXTRA_OEMAKE += "'DESTDIR=${D}/usr' 'PREFIX=""'"
do_compile() {
oe_runmake -C devLib
oe_runmake -C wiringPi
oe_runmake -C gpio 'LDFLAGS=${LDFLAGS} -L${S}/wiringPi -L${S}/devLib'
}
do_install() {
oe_runmake -C devLib install
oe_runmake -C wiringPi install
oe_runmake -C gpio install
}
It is fetching from a git repository, applying patches generated by git, using oe_runmake to compile with the makefiles.
With devtool
It has been asked in a comment on how to add a recipe with devtool.
We will still use wiringPi as an example again. Download it doing
https://github.com/WiringPi/WiringPi
The Makefile is is the folder wiringPi.
You can then do
devtool add <name_of_recipe> <path_to_Makefile_folder>
Take care of the warning from devtool
NOTE: Creating workspace layer in /home/dbensoussan/new_poky/poky/build/workspace
NOTE: Enabling workspace layer in bblayers.conf
NOTE: Using source tree as build directory since that would be the default for this recipe
NOTE: Recipe /home/dbensoussan/new_poky/poky/build/workspace/recipes/project/project.bb has been automatically created; further editing may be required to make it fully functional
This is generating the recipe as follow:
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)
#
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "Unknown"
LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=e6a600fd5e1d9cbde2d983680233ad02"
# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""
# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the
# recipe automatically - you will need to examine the Makefile yourself and ensure
# that the appropriate arguments are passed in.
do_configure () {
# Specify any needed configure commands here
:
}
do_compile () {
# You will almost certainly need to add additional arguments here
oe_runmake
}
do_install () {
# This is a guess; additional arguments may be required
oe_runmake install 'DESTDIR=${D}'
}
You can then edit your recipe to suit your configuration
With externalsrc
It is possible to use a directory present on the filesystem by using externalsrc.
I did not try it myself, nor have I the workspace ready to do, but #71GA in the comment tested the tutorial from the Koan software company https://wiki.koansoftware.com/index.php/Building_Software_from_an_External_Source and it worked. I will copy the content here:
in this case use the externalsrc class - you can inherit this in the original bb recipe or a bbappend:
inherit externalsrc
EXTERNALSRC = "/path/to/sources"
Depending on the type of build (eg, 'inherit module' for out of tree Linux kernel modules) you may or may not need to set EXTERNALSRC_BUILD.
inherit externalsrc
EXTERNALSRC = "/some/path"
EXTERNALSRC_BUILD = "/some/path"
If you're going to use it across a number of recipes you can inherit it globally at the configuration level (perhaps via an inc file that you include/require there):
INHERIT += "externalsrc"
EXTERNALSRC_pn-<recipename> = "/path/to/sources"
Recipe example using an external source for nInvaders package
#
# Recipe example with externalsrc
#
# (C)2019 Marco Cavallini - KOAN - <https://koansoftware.com>
#
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""
inherit externalsrc
EXTERNALSRC = "/home/koan/yocto-qemuarm-sumo/ninvaders-0.1.1"
EXTERNALSRC_BUILD = "${EXTERNALSRC}"
DEPENDS = "ncurses"
EXTRA_OEMAKE = "-e"
do_install() {
install -d ${D}${bindir}
install -m 0755 nInvaders ${D}${bindir}
}
FILES_${PN} = "${bindir}/*"
You can just go to the official documentation to find your answer.
In the chapter 7.3 Writting a New Recipe of the yocto mega-manual, the very first example is exactly is what you need (Single .c File Package (Hello World!)).
According to the D(x) macro defined in pam_macros.h (source code) and used as follows:
D(("Hello PAM World"));
Where is this log located on CentOS7?
Note that I am using as flag debug in my pam.d conf file.
I tried also the following command:
grep -rnw '/var/log/' -e "Hello Pam World"
But with no success.
In the file you link, there are these lines at the top:
/*
* This is for debugging purposes ONLY. DO NOT use on live systems !!!
* You have been warned :-) - CG
*
* to get automated debugging to the log file, it must be created manually.
* _PAM_LOGFILE must exist, mode 666
*/
#ifndef _PAM_LOGFILE
#define _PAM_LOGFILE "/tmp/pam-debug.log"
#endif
So it looks like the output will be directed to /tmp/pam-debug.log, but you have to create it before, and give it full read-write permissions:
$ touch /tmp/pam-debug.log
$ chmod 666 /tmp/pam-debug.log
Looking to the Linux version of this file, it looks like it is written to /var/run/pam-debug.log, but only if it is compiled with PAM_DEBUG.
There a nice comment in configure.ac:
if test x"$enable_debug" = x"yes" ; then
AC_DEFINE([PAM_DEBUG],,
[lots of stuff gets written to /var/run/pam-debug.log])
I have a module running on my Linux machine and can see it using lsmod command. Now I made some changes (added some printk) to this module, recompiled it and got the .ko.
Now I did rmmod to remove this module (some other modules also which are using this module), did insmod xxx.ko and rebooted the system.
Now where do I see the statements added using printk? I tried to see using
dmesg grep | "SPI RW"
But I couldn't find anything. What am I doing wrong here?
Try vim /var/log/messages or open messages in a text editor to verify.
For enabling /var/log/messages, edit file /etc/rsyslog.d/50-default.conf
Change the following paragraph:
...
#
# Some "catch-all" log files.
#
#*.=debug;\
# auth,authpriv.none;\
# news.none;mail.none -/var/log/debug
#*.=info;*.=notice;*.=warn;\
# auth,authpriv.none;\
# cron,daemon.none;\
# mail,news.none -/var/log/messages
....
to the following:
...
#
# Some "catch-all" log files.
#
*.=debug;\
auth,authpriv.none;\
news.none;mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none -/var/log/messages
...
and do restart rsyslog.