Why is make savedefconfig removing entries? - linux

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.

Related

Kernel configuration using bitbake menuconfig in yocto?

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

Linux Kernel makefile process explained

In LinuxSrc/Documentation/admin-guide/README.rst under the section for building the kernel exists these 4 steps, can someone explain what each one does?
Is it similiar to a ./configure, ./make, ./install?
To configure and build the kernel, use:
1.) cd /usr/src/linux-4.X
2.) make O=/home/name/build/kernel menuconfig
3.) make O=/home/name/build/kernel
4.) sudo make O=/home/name/build/kernel modules_install install
1) simple cd - no explanation needed
2) Running make menuconfig starts an ncurses-based text mode kernel configuration tool.
3) make O=/home/name/build/kernel configures and builds the kernel.
4.1) modules_install: This will copy the compiled modules into /lib/modules/-.
4.2) install: This command will copy following files into /boot directory (and might do more depending on the distribution):
Config-, System.map-, Vmlinuz-*
vmlinuz - Is a compressed Linux kernel
system.map - Is a lookup table between symbol names and their addresses in memory for a particular build of a kernel
config - The kernel configuration created by the make menuconfig

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

Driver/module cross compilation

I am trying to cross compile a driver for an arm based board. In the make file the search path for include files is that of the host machine's kernel i.e it points to the linux headers that come with ubuntu.
I also have the kernel source tree of target board present on the host system(i7/ubuntu).
My Question is that which include path is needed for cross compilation (native system's linux headers path or the path to the kernel source tree of board ?
Does same thing applies to all modules including drivers?
Here is a Makefile for an out of tree driver. The architecture, toolchain and kernel dir specified :
ifneq ($(KERNELRELEASE),)
# We were called by kbuild
obj-m += fpgacam.o
else # We were called from command line
KDIR := path/to/your/target/kernel
PWD := $(shell pwd)
CROSS=arm-none-linux-gnueabi-
default:
#echo ' Building Cam drivers for 2.6 kernel.'
#echo ' PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS) modules
install:
./do_install.sh *.ko
endif # End kbuild check
######################### Version independent targets ##########################
clean:
rm -f -r *.o *.ko .*cmd .tmp* core *.i
When make is called from the module directory, the command line path is taken, and make is redirected to the kernel directory build system using make -C. The kernel build system then the different variable passed to it to go back into the module directory with everything setup (include path, toolchain etc ..) to compile a module. This second time through the Makefile, the kbuild path is taken, and the module is built as if it was in-tree.
Compiling with your build-system's headers is spectacularly bad news, and may subtle binary incompatibilities that manifest themselves as seemingly bizarre crashes on the target.
As you've already discovered, the kernel is already hardened against this and will refuse to load modules built against the wrong headers. You'll need to build using the same source tree as the existing kernel - including any patches. You might as well at this point rebuild the entire kernel.
The kernel tree is self-contained, so simply cross-compiling it in place will work. If you're adding a driver it's probably easiest to compile it in-tree.
If you want to build any user-space components, you have two solutions:
Pass the --sysroot=<dir> option to gcc, where <dir> is the system root of your target system
Build gcc and binutils to use as their default sysroot
The latter approach is the one that Angstrom uses, and it save a lot of butt-hurt.
You might want to try using crosstool-ng
It takes care of the majority of the work. You only need to bother about the configuration settings you want to enable for kernel compilation.
Here another reference: link

How can I set up default Makefile flags for all my Linux kernel compilations?

Is there a way that I can set my kernel Makefile flags to always include "-j9"? I often forget to type that flag manually when I recompile a new kernel that I've newly downloaded and configured and so the compile takes longer than it should on my machine. My strategy for updating a kernel is:
Download a new kernel and put it in /usr/src/linux-new
cp /usr/src/linux-old/.config /usr/src/linux-new
make oldconfig
make all modules_install
I'd really like a CONFIG variable or something like that so that this method would automatically transfer the old Makefile flags over to the new directory and then I wouldn't have to remember to pass that pesky -j9 flag myself.
How about putting steps 3 and 4 (or maybe 2, 3, and 4) into a shell script or alias, and executing that instead?
#!/bin/bash
make -j9 oldconfig
make -j9 all modules_install
Name this makeit or something easy to remember.
makeit

Resources