Can anyone explain what the target "oldconfig" does exactly in the Linux kernel makefile? I see it referenced in some build documentation but never explained what it does exactly.
It reads the existing .config
file that was used for an old kernel and prompts the user for options in the current kernel source that are not found in the file. This is useful when taking an existing configuration and moving it to a new kernel.
Summary
As mentioned by Ignacio, it updates your .config
for you after you update the kernel source, e.g. with git pull
.
It tries to keep your existing options.
Having a script for that is helpful because:
new options may have been added, or old ones removed
the kernel's Kconfig configuration format has options that: imply one another via select depend on another via depends Those option relationships make manual config resolution even harder.
imply one another via select
depend on another via depends
Let's modify .config manually to understand how it resolves configurations
First generate a default configuration with:
make defconfig
Now edit the generated .config
file manually to emulate a kernel update and run:
make oldconfig
to see what happens. Some conclusions:
Lines of type: # CONFIG_XXX is not set are not mere comments, but actually indicate that the parameter is not set. For example, if we remove the line: # CONFIG_DEBUG_INFO is not set and run make oldconfig, it will ask us: Compile the kernel with debug info (DEBUG_INFO) [N/y/?] (NEW) When it is over, the .config file will be updated. If you change any character of the line, e.g. to # CONFIG_DEBUG_INFO, it does not count. Lines of type: # CONFIG_XXX is not set are always used for the negation of a property, although: CONFIG_XXX=n is also understood as the negation. For example, if you remove # CONFIG_DEBUG_INFO is not set and answer: Compile the kernel with debug info (DEBUG_INFO) [N/y/?] (NEW) with N, then the output file contains: # CONFIG_DEBUG_INFO is not set and not: CONFIG_DEBUG_INFO=n Also, if we manually modify the line to: CONFIG_DEBUG_INFO=n and run make oldconfig, then the line gets modified to: # CONFIG_DEBUG_INFO is not set without oldconfig asking us. Configs whose dependencies are not met, do not appear on the .config. All others do. For example, set: CONFIG_DEBUG_INFO=y and run make oldconfig. It will now ask us for: DEBUG_INFO_REDUCED, DEBUG_INFO_SPLIT, etc. configs. Those properties did not appear on the defconfig before. If we look under lib/Kconfig.debug where they are defined, we see that they depend on DEBUG_INFO: config DEBUG_INFO_REDUCED bool "Reduce debugging information" depends on DEBUG_INFO So when DEBUG_INFO was off, they did not show up at all. Configs which are selected by turned on configs are automatically set without asking the user. For example, if CONFIG_X86=y and we remove the line: CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y and run make oldconfig, the line gets recreated without asking us, unlike DEBUG_INFO. This happens because arch/x86/Kconfig contains: config X86 def_bool y [...] select ARCH_MIGHT_HAVE_PC_PARPORT and select forces that option to be true. See also: https://unix.stackexchange.com/questions/117521/select-vs-depends-in-kernel-kconfig Configs whose constraints are not met are asked for. For example, defconfig had set: CONFIG_64BIT=y CONFIG_RCU_FANOUT=64 If we edit: CONFIG_64BIT=n and run make oldconfig, it will ask us: Tree-based hierarchical RCU fanout value (RCU_FANOUT) [32] (NEW) This is because RCU_FANOUT is defined at init/Kconfig as: config RCU_FANOUT int "Tree-based hierarchical RCU fanout value" range 2 64 if 64BIT range 2 32 if !64BIT Therefore, without 64BIT, the maximum value is 32, but we had 64 set on the .config, which would make it inconsistent.
Bonuses
make olddefconfig
sets every option to their default value without asking interactively. It gets run automatically on make
to ensure that the .config
is consistent in case you've modified it manually like we did. See also: https://serverfault.com/questions/116299/automatically-answer-defaults-when-doing-make-oldconfig-on-a-kernel-tree
make alldefconfig
is like make olddefconfig
, but it also accepts a config fragment to merge. This target is used by the merge_config.sh
script: https://stackoverflow.com/a/39440863/895245
And if you want to automate the .config
modification, that is not too simple: How do you non-interactively turn on features in a Linux kernel .config file?
Before you run make oldconfig
, you need to copy a kernel configuration file from an older kernel into the root directory of the new kernel.
You can find a copy of the old kernel configuration file on a running system at /boot/config-3.11.0
. Alternatively, kernel source code has configs in linux-3.11.0/arch/x86/configs/{i386_defconfig / x86_64_defconfig}
If your kernel source is located at /usr/src/linux
:
cd /usr/src/linux
cp /boot/config-3.9.6-gentoo .config
make oldconfig
Updates an old config with new/changed/removed options.
It's torture. Instead of including a generic conf file, they make you hit return 9000 times to generate one.
yes "" | make oldconfig
From this page:
Make oldconfig takes the .config and runs it through the rules of the Kconfig files and produces a .config which is consistant with the Kconfig rules. If there are CONFIG values which are missing, the make oldconfig will ask for them. If the .config is already consistant with the rules found in Kconfig, then make oldconfig is essentially a no-op. If you were to run make oldconfig, and then run make oldconfig a second time, the second time won't cause any additional changes to be made.
Success story sharing