What does "make oldconfig" do exactly in the Linux kernel makefile?
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.
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
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
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 onDEBUG_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, unlikeDEBUG_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 atinit/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 is32
, but we had64
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?
Updates an old config with new/changed/removed options.