The easiest way to extend Linux version in Yocto - linux

I'm trying to extend Linux version in my project on a tag from git repository. I manged to pass tag value to Linux-*.bb and looking for the best solution to add it to kernel version so I can see it in /etc/kernel-version file and as an output after typing "uname -r" e.g: 3..11.67-my-tag.
I know that there is something like LINUX_KERNEL_EXTENSION but I didn't mange to make it working.
What is the easiest way to do it and how can I test it without flashing my board?
Thanks,

There is a dedicated configuration option, name CONFIG_LOCALVERSION, which can be found under General Setup -> Local version - append to kernel release. You can add it by simply using bitbake -c menuconfig or directly adding following lines in your kernel configuration file:
CONFIG_LOCALVERSION="+mycustomboard"
CONFIG_LOCALVERSION_AUTO=y
If you need to add your tag value as extension, you have to add these following lines in your kernel recipe:
LOCALVERSION = "+mycustomboard-${LINUX_VERSION_EXTENSION}"
LINUX_VERSION_EXTENSION = "1.2.3"
In that way, uname -r output shall contain +mycustomboard-1.2.3 as you expect.

Related

Manually building a Kernel source from Yocto build

I have a Yocto build for i.mx6 and I want to modify its Kernel. I figured that if I copy Kernel source outside the Yocto project and make my modifications without dealing with patches, I can speed things up significantly. But the thing is, the Kernel source I have to use is already patched and I want to fetch and continue working from there. I will work on the already-patched source files and re-arranging them is a painful process.
For starting point, my patches work fine, and I can get a working image using bitbake fsl-image-multimedia-full command. The Kernel source I want to use is created after this process.
I have tried copying the source under ..../tmp/work-shared/imx6qsabresd/kernel-source. Although make zImage and make modules finished without any trouble, manual building was not successful with an error in a dtsi file (Unable to parse...). Of course, I have checked the file and there was no syntax error.
Also, I checked the kernel source files I copied and it seems that the patches are successfully implemented.
Am I doing something wrong with the patches? With my manual build routine, I can build unpatched kernel source with no errors. I am sure that there are experienced Yocto users here that have their own workarounds to make this process shorter. So, any help is appreciated. Thanks in advance.
You can also edit files in tmp/work-shared/<machine>/kernel-source then compile modified kernel with bitbake -C compile virtual/kernel
My favorite method of doing kernel development in a Yocto project is to create an SDK and build the kernel outside of the Yocto system. This allows more rapid builds because make will only build new changes, whereas a kernel build within Yocto always starts from scratch.
Here are some of my notes on compiling the Linux kernel outside of the Yocto system. The exact paths for this will depend on your exact configuration and software versions. In your case, IMAGE_NAME=fsl-image-multimedia-full
Run bitbake -c populate_sdk ${IMAGE_NAME}. You will get a
self-extracting and self-installing shell script.
Run the shell script (for me it was
tmp/deploy/sdk/${NAME}-glibc-i686-${IMAGE_NAME}-cortexa9hf-neon-toolchain-1.0.0.sh),
and agree to the default SDK location (for me it was
usr/local/oecore-i686).
Source the scripts generated by the install script. I use the
following helper script to load the SDK so I don't have to keep
track of the paths involved. You need to source this in each time
you want to use the SDK.
enable_sdk.sh:
#!/bin/bash
if [[ "$0" = "$BASH_SOURCE" ]]
then
echo "Error: you must source this script."
exit 1
fi
source /usr/local/oecore-i686/environment-setup-corei7-32-${NAME}-linux
source /usr/local/oecore-i686/environment-setup-cortexa9hf-neon-${NAME}-linux-gnueabi
Copy the defconfig file from your Yocto directory to your kernel
directory (checked out somewhere outside of the Yocto tree) as
.config.
Run make oldconfig in your kernel directory so that the Linux
kernel build system picks up the existing .config.
Note: you may have to answer questions about config options that
are not set in the .config file.
Note: running make menuconfig will fail when the SDK is enabled,
because the SDK does not have the ncurses libraries set up
correctly. For this command, run it in a new terminal that has not
enabled the SDK so that it uses the local ncurses-dev packages you
have installed.
Run make -jN to build the kernel.
To run the new kernel, copy the zImage and ${NAME}.dtb files to
your NFS/TFTP share or boot device. I use another script to speed
up the process.
update_kernel.sh:
#!/bin/bash
set -x
sudo cp /path-to-linux-source/arch/arm/boot/dts/${NAME}.dtb /srv/nfs/${DEVICE}/boot/
sudo cp /path-to-linux-source/arch/arm/boot/zImage /srv/nfs/${DEVICE}/boot/
set +x
You can also point Yocto to your local Linux repo in your .bb
file. This is useful for making sure your kernel changes still
build correctly within Yocto.
SRC_URI = "git:///path-to-linux-source/.git/;branch=${KBRANCH};protocol=file"
UPDATE: Over a year later, I realize that I completely missed the question about broken patches. Without more information, I can't be sure what went wrong copying the kernel source from Yocto to an external build. I'd suggest opening a Bitbake devshell for the kernel and doing a diff with the external directory after manually applying patches to see what went wrong, or just copy the source from inside the devshell to your external directory.
https://www.yoctoproject.org/docs/1.4.2/dev-manual/dev-manual.html#platdev-appdev-devshell
When debugging certain commands or even when just editing packages, devshell can be a useful tool. When you invoke devshell, source files are extracted into your working directory and patches are applied.
Since it can't parse it, there seems to be a problem with patch. How do you patch the device tree? Are you patching it in the .bb file?
If so, check your patch for possible syntax errors, it's very easy to overlook the syntax errors in device tree. You can remove the patch and do it manually from bitbake -c devshell <kernel-name>
If not, please try to do it there and check again. Please share results if any of these helps you.

Adding an entry to the Linux Kernel .config file

How can I manually add the line CONFIG_XILINX_FIXED_DEVTREE_ADDR=y to the linux config file? It keeps getting overwritten when I build the kernel
You can build by make CONFIG_XILINX_FIXED_DEVTREE_ADDR=y without adding it into .config. But if you gonna add it to .config, you should use make menuconfig to select it and save it into .config.
If the config variable you're trying to add is new (as in, not in .config at all and not showing up in make menuconfig), then you should add it to the relevant Kconfig file. For instance, if you look at fs/proc/Kconfig, you can see how different proc config options are laid out. Follow their example and add your config variable, its variable type, the default, and its description. Then you should see it in make menuconfig.
Here's an example of a config variable definition in fs/proc/Kconfig:
config PROC_VMCORE
bool "/proc/vmcore support"
depends on PROC_FS && CRASH_DUMP
default y
help
Exports the dump image of crashed kernel in ELF format.

Linux kernel configuration - enabling CONFIGURE_LOCALVERSION_AUTO

I have recently git cloned the kernel of Linus Torvalds. I want to build and install this kernel in my laptop. But because I want to use "kernel-of-the-day" I want to enable CONFIGURE_LOCALVERSION_AUTO option. But how should I enable this option I don't know that. Where to find this option?
Use menuconfig or xconfig, to configure Linux kernel these interfaces are used. Modifying .config file directly is discouraged. Inside your kernel source tree do make menuconfig or make xconfig - use anyone you like. On kernel configuration menu you'll find General Setup Option, inside this option you'll find Automatically append version information to the version string, toggle it to enable/disable.
After you have cloned the Linus repository repository. You would need to either create a fresh .config file in the ./linux folder or copy the existing config file from your /boot and later modify it. Then edit the .config file and set CONFIG_LOCALVERSION_AUTO=y
`cp /boot/config-`uname -r` .config`

How to build libcurl.so with a different target name?

I am using libcurl for my utility and its working very well till now for all Linux platforms. I downloaded, unzipped and simply followed the instructions given without any changes. My product uses the libcurl.so file and is linked dynamically. The .so file is bundled along with our product. Recently there were issues in Suse wherein we found that Libcurl is bundled by default and there was a conflict in installation.
To avoid this issue we tried renaming the libcurl.so into libother_curl.so but it did not work and my binaries still show libcurl.so as a dependency through ldd. I had since learnt that the ELF format of linux shared objects specifies the file name hardcoded as SO file name in the headers.(I could verify the same with objdump -p).
Now my question is what is the simplest way to go? How do I build a libcurl with a different name? My original process involves running configure with the following switches
./configure --without-ssl --disable-ldap --disable-telnet --disable-POP3 --disable-IMAP --disable-RTSP --disable-SMTP --disable-TFTP --disable-dict --disable-gopher --disable-debug --enable-nonblocking --enable-thread --disable-cookies --disable-crypto-auth --disable-ipv6 --disable-proxy --enable-hidden-symbols --without-libidn --without-zlib
Make
Then pick the generated files from /lib/.libs
Are there any Configure Switches available wherein I can specify the target file name? Any specific Makefile I could change?
I tried changing in what I thought could be obvious locations but either could not generate the libs or were generated with the same name.
Any help is much appreciated.
I got the answer from the curl forums(Thanks Dan). Basically we have to use the makefile.am as a starting point to go through a list of files and change the library name "libxxx_curl".
$find . -name Makefile.am |xargs sed -i 's/libcurl(.la)/libxxx_curl\1/g'
$buildconf
$configure
$make
I lot of commercial applications bundle their particular library versions in a non standard path and then tweak environment variable LD_LIBRARY_PATH in a launch script so to avoid conflict. IMHO it is better than trying to change the target name.

How do I configure the Linux kernel within Buildroot?

I'm trying to build a rootfs for an x86 target, which is all simple enough. However I can't figure out how I configure the kernel that buildroot produces. The first run through came up with menuconfig, but it's cached the .config since then and I can't see where to change it.
~650MB of kernel modules don't do good things to an embedded target :P
Is there an easy way to configure the kernel within buildroot? Something like the uclibc-menuconfig target would be perfect.
I always do the following:
configure Linux kernel: make linux-menuconfig
After leaving menuconfig your configuration will be stored in file: output/build/linux-XYZ/.config where XYZ is your kernel version.
After that you can copy file output/build/linux-*XYZ*/.config to board/your_kernel_config/.config
later in Buildroot menuconfig you can under kernel settings configure to use custom kernel config file and enter path: board/your_kernel_config/.config
Do not forget to set also defconfig to i386 in menuconfig:
Kernel —>
[*] Linux Kernel
(i386) Defconfig name
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES
Adds extra configs to your existing one.
E.g., if you are using buildroot as a submodule, the directory tree looks like:
.git/
buildroot/
.gitmodules
kernel-config-frag
E.g. to turn on CONFIG_DEBUG_FS, do:
echo 'CONFIG_DEBUG_FS=y' > kernel-config-frag
and then configure buildroot with:
cd buildroot
make qemu_x86_64_defconfig
echo 'BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES=../kernel-config-frag' >> buildroot/.config
make
This way you can git track just a diff between qemu_x86_64_defconfig and your extra configs.
I believe this uses scripts/kconfig/merge_config.sh form the kernel as mentioned at: How do you non-interactively turn on features in a Linux kernel .config file?
After you change the config fragment, just remember to do:
rm -rf buildroot/output/build/linux-*.*.*/
before the next build.
Minimal runnable example at: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/bb8f4eb79565c9771356c80e0964c8fefc163e11/kernel-config-frag
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
Selects the full .config to be used.
For some reason I have to nuke the kernel's .config for this to take effect? Why when I change BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE and run make linux-reconfigure the kernel .config does not change?
And the answer is:
make linux26-menuconfig
The steps are as follows:
cd buildroot/
make menuconfig
Kernel -> Linux Kernel -> Kernel version

Resources