Kernel configuration using bitbake menuconfig in yocto? - linux

I am trying to remove some drivers from the yocto kernel using menuconfig like this below..
bitbake -c menuconfig virtual/kernel
after all the configurations i generate the fragment.cfg with.
bitbake -c diffconfig virtual/kernel
Then i make a .bbappend file in recipes-kernel/linux directory and bitbake my image.
Now the problem is that all the configuration which i do is reset to the default everytime for some reason. how can i make the configuration permanent ?

One solution is to create own receipt and override default.
For example, we are using linux-yocto-rt kernel and create own receipt with name linux-yocto-rt and following files:
linux-yocto-rt\linux-yocto-rt_4.9.bb
linux-yocto-rt\linux-yocto-rt\defconfig
defconfig file changes default configuration.
In bb file you should add link to this file like:
SRC_URI += "file://defconfig "
You can always look inside official documentation

Related

Custom compiled kernel not showing updated changes

I have been following
the How Tos/Custom_Kernel (I Need to Build a Custom Kernel) document
at the Wiki to compile my kernel.
I modified the kernel in
~/rpmbuild/BUILD/kernel-4.18.0-305.3.1.el8_4/linux-4.18.0-305.3.1.el8_4
I did make menuconfig and made the below changes.
I had enabled the below two parameters for segment routing.
# CONFIG_IPV6_SEG6_LWTUNNEL is not set
# CONFIG_IPV6_SEG6_HMAC is not set
I then compiled after following all the changes using the below command.
rpmbuild -bb --target=`uname -m` kernel.spec
I noticed when I ran rpmbuild it deleted the folder under BUILD and then config under it automatically changed back the parameters to 'not set'.
The compilation was done successfully but when I installed the kernel on a different host, I can see the kernel was installed but those two parameters still shows 'not set'.
The file under /root/rpmbuild/SOURCES/kernel-4.18.0-x86_64.config has those 2 parameters set.
[root#localhost SOURCES]# cat kernel-4.18.0-x86_64.config | grep SEG6
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_IPV6_SEG6_HMAC=y
I am not sure what piece I am missing here?

How to enable tc command when building a kernel using Yocto recipes

I want to enable tc command that comes in iproute2 on my linux kernel. My kernel is built using yocto and bitbake.
So, I copied the iproute recipes and whole directory from the following link to try --
https://git.yoctoproject.org/cgit.cgi/poky/plain/meta/recipes-connectivity/iproute2
And included in my yocto build. That picked up recipe and built it all well. But I tc command is still not available on the built kernel.
Question:
What am I missing and how to enable tc in the kernel of a linux image built using Yocto recipes?
You shouldn't need to copy the whole recipe, poky should be in your sources directory. So just reference the recipe in your image. You need both iproute2 and iproute2-tc.
IMAGE_INSTALL += "iproute2 \
iproute2-tc"
Additionally you may need to enable some kernel modules that tc make use of, depending on your needs:
CONFIG_NET_SCHED
CONFIG_NET_SCH_CBQ
CONFIG_NET_SCH_HTB
CONFIG_NET_SCH_HFSC
CONFIG_NET_SCH_ATM
CONFIG_NET_SCH_PRIO
CONFIG_NET_SCH_MULTIQ
CONFIG_NET_SCH_RED
CONFIG_NET_SCH_SFQ
CONFIG_NET_SCH_TEQL
CONFIG_NET_SCH_TBF
CONFIG_NET_SCH_GRED
CONFIG_NET_SCH_DSMARK
CONFIG_NET_SCH_NETEM
CONFIG_NET_SCH_INGRESS

Why is make savedefconfig removing entries?

I want to add entries to a vendor-provided defconfig for a Yocto distribution. In order to add the new drivers I want, I usually use the following process in my Linux directory:
$ cp $YOCTO_MYKERNEL/files/defconfig .config
$ make menuconfig
$ # I select some drivers I want to add and save .config file
$ make savedefconfig
$ cp defconfig $YOCTO_MYKERNEL/files/defconfig
The savedefconfig step adds my drivers correctly, but is also removing some important drivers that are vendor-provided:
$ diff -u $YOCTO_MYKERNEL/files/defconfig defconfig
--- $YOCTO_MYKERNEL/files/defconfig
+++ defconfig
## -1,22 +1,11 ##
-CONFIG_FHANDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_CGROUPS=y
CONFIG_BLK_DEV_INITRD=y
-CONFIG_PERF_EVENTS=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
-CONFIG_ARCH_SUNXI=y
CONFIG_SMP=y
CONFIG_NR_CPUS=8
-CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_VFP=y
-CONFIG_NEON=y
[...]
If I understood the savedefconfig step well, it is removing options that are already set by default and thus redundant. However removing all these vendor-provided drivers are causing the newly compiled kernel to not boot at all after uboot.
I even tried only the savedefconfig step without adding any drivers, and vendor drivers are removed and kernel hangs.
Do you have any idea why savedefconfig is removing these entries, and how to make it stop? Currently I have to isolate diff changes by hand and manually add new lines that I am interested in into the Yocto defconfig file.
I have found the reason for all of this: I was calling make savedefconfig without specifying the ARM architecture, thus I think the build system will remove any non-revevant entries like all the SUNXI_* drivers (because they are not used on x86_64).
This call does not mangles important drivers:
make ARCH=arm savedefconfig
In order to not forget to do this step, one can use the Yocto steps instead that will automatically use the relevant architecture:
bitbake -c menuconfig virtual/kernel
bitbake -c savedefconfig virtual/kernel
Bitbake will print the path of the generated defconfig file that you will have to copy over the older one in order to take the changes into account.

building /lib/modules/$(uname -r)/build while compiling a kernel

I am cross-compiling 3.4.0 kernel for an embedded device. Then I would like to install compat-wireless drivers which require /lib/modules/3.4/build directory and sub-files. Could anyone explain how can I build that directory so that when I do INSTALL_MOD_PATH=newmodules make modules_install it would load /lib/modules/$(uname -r)/build directory as well? I would appreciate for a clear explanation.
I am using debian distro. I know I can install the kernel headers by apt-get install linux-headers-$(uname -r), but I doubt it would be a good idea since the kernel sources might not be identical.
Typically /lib/modules/$(uname -r)/build is a soft-link to the directory where performed the build. So the way to do this is to simply do a
make modules_install INSTALL_MOD_PATH=/some/root/
in the build directory of the kernel where /some/root is where you want your cross compile pieces to end up. This will create a link to your kernel build path in /some/root/lib/modules/$(uname -r) ... verify that.
Now when you build the compat_wireless drivers specify the kernel build directory in the Makefile as /some/root using the KLIB_BUILD variable (read the Makefile)
make modules KLIB_BUILD=/some/root/lib/modules/$(uname -r)/build
this should do the trick for you.
EDIT A
In answer to your comment below:
Keep "newmodules" outside the kernel directory it's a bad idea to put it in the kernel directory. so mkdir newmodules somewhere like /home/foo or /tmp or something. This is one of the reasons your build link is screwed up
ALSO .../build is a soft link /to/kernel/build/location it will only copy over as a soft-link. You also need to copy over the actual kernel source / kernel build directory to your microSD, using the same relative location. For example,
Let's say your kernel source is in:
/usr/src/linux-3.5.0/
Your kernel build directory is:
/usr/src/linux-3.5.0-build/
Your newmodules (after following 1.) is in:
/tmp/newmodules/
So under /tmp/newmodules/ you see the modules installed in a tree like:
lib/modules/$(uname -r)/
when you do an ls -al in this directory, you'll see that build is a soft link to:
build -> /usr/src/linux-3.5.0-build/
Now let's say your microSD is mounted under /mnt/microSD
then you need to do the following
mkdir -p /mnt/microSD/usr/src
cp -a /usr/src/linux-3.5.0 /usr/src/linux-3.5.0-build /mnt/microSD/usr/src
cp -a /tmp/newmodules/lib /mnt/microSD/lib
Now you have all the content you need to bring over to your embedded environment. I take it you are doing the compat_wireless build on your target system rather than cross compiling it?
NOTE
If your kernel build is the same as the kernel source then just copy over the kernel source and ignore the linux-3.5.0-build in copy instructions above
This is old, but some people will need this information.
I have spent many hours to figure out where build folder comes from, and why it is just a link when I compile my own kernel. Finally figured it out;
Linux kernel usually just links the build and source folders to the source folder.
But!
Arch linux (probably some other distros too); has a manual script for deleting those links, and adding (filtered) files to build folder.
https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/linux
I've extracted that script to work standalone (in a kernel source tree) here: https://gist.github.com/furkanmustafa/9e73feb64b0b18942047fd7b7e2fd53e

How to recompile just a single kernel module?

Usually kernel source are stored in /usr/src/linux-2.6.x/.
To avoid to recompile the entire kernel if I modify a module's source, how can I recompile just that module?
Switch to the root directory of your source tree and run the following command:
$ make modules SUBDIRS=drivers/the_module_directory
And to install the compiled module:
$ make modules_install SUBDIRS=drivers/the_module_directory
Note: As lunakid mentions, the latter command might not build the module first, so be careful.
since kernel versions 3.x.x and 4.x.x the procedure gets more complicated (but there is a hope, so keep reading):
make distclean if you haven't just cloned a new source but used to build other modules before
create new folder somewhere for the module source (example: extra)
and copy only source files (from the kernel source or somewhere else) related to the module needed to be build into this new folder
copy /boot/config-`uname -r` file (example: /boot/config-4.8.0-46-generic) into kernel source folder file .config and run make oldconfig. if the module belongs to the kernel source, verify if it has been enabled by calling make menuconfig, by searching for the module and applying letter 'M' if necessary
kernel source root Makefile has to be altered with exact version components matching the current running one (you may verify with make kernelversion if it matches exactly the uname -rone)
there is been a strong suggestion to build scripts also before with
make scripts
make prepare and make modules_prepare has to be executed prior to the actual module build
Module.symvers has to be copied from the target system headers folder corresponding running kernel version /usr/src/linux-headers-`uname -r`/Module.symvers (example: /usr/src/linux-headers-3.13.0-117-generic/Module.symvers) into the newly created module source files folder prepared for the module compilation (the one extra in example).
create new Makefile inside module source compilation folder having following line: obj-y += <module_source_file_name>.o or if the source code is complicated, use the guidance from here
only then it's the right time to build module with make -C <kernel source path> M=the_module_directory (example: make -C . M=extra/)
Use command modprobe --dump-modversion <module_name>.ko to verify CRC match between module exporting API and corresponding values in Module.symvers. in case of failure use command modinfo <module_name>.ko instead
verify if kernel.release file content match exactly the one from headers of the current running version. if you'll discover + appended at the end, it means you've been compiling git clonned source and your experimental modifications caused build system to compromise the localversion string by adding + at the end.
if only + has been discovered at the tail of kernel.release stored value and it's a mismatch with the exact name of the target running kernel,
the solution would be following:
commit all your changes, force release tag to shift above your modifications with the git tag -a <tag version> -f command. then rebuild your modules from step 8
You can pass the path to the module name or module directory to make as parameter.
make path/to/the/module/itself.ko
make path/to/the/module/directory/
In case you have edited just code in drivers/net/ethernet/intel/e1000/e1000_main.c file
Build the module.
make scripts prepare modules_prepare
make -C . M=drivers/net/ethernet/intel/e1000
Install the module.
cp drivers/net/ethernet/intel/e1000/e1000.ko /lib/modules/5.1.15/kernel/drivers/net/ethernet/intel/e1000/e1000.ko
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install
https://askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module

Resources