Kernel Configuration

Overview

Kernel configuration is a little complicated in Chromium OS. There are a number of different kernels based on architecture (x86, ARM) variants (generic, exynos) and platforms (Seaboard, Mario). We want to split the config into a sort of hierarchy so that the common options are shared between the variants (click to enlarge):

Shown here are 6 flavours, three for ARM and three for Intel (it is not clear why flavours is spelt the British way). Two of the variants are not actually distinct - these are are shown with arrows and are symlinks in the directory. In this case chromeos-arm just points to chromiumos-arm and they are the same.

Conversions

We need to be able to do the following:

  • create a .config file for a particular flavour - this is done simply by concatenating the three levels for a particular flavour. For example we create the tegra2 flavour by concatenating base.config, armel/common.config and armel/chromeos-tegra2.flavour.config. This .config file is suitable for configuring the kernel.
  • split a .config into its constituent parts. This is a little more complicated and has to be done for all flavours at once. Given a .config file for each flavour we can look for items which are common to all flavours - these can be put into the family config. We also look for everything common within each architecture - these are put into the architecture files like config.common.arm. The splitconfig script does this.

Scripts

Scripts to deal with the kernel configuration (in sys-kernel/chromeos-kernel or sys-kernel/chromeos-kernel-next) are in the chromeos/scripts directory:

$ ls chromeos/scripts/
compat_wireless_config  kernelconfig  prepareconfig  splitconfig

kernelconfig

This script deals with each separate flavour in turn, performing the selected operations. It starts by building the config for each flavour, does the operations, and afterwards it splits the flavour configs back into the proper hierarchy.  It supports three operations

  • oldconfig - does a 'make oldconfig' on each config
  • editconfig - does a 'make menuconfig' on each config
  • genconfig - like oldconfig, but it leaves the generated full config files lying around afterwards in the CONFIGS directory

There is a bit of a problem with kernelconfig. If you want to change a kernel option which is common to all flavours, for example, then you must change it once for each flavour using 'kernelconfig editconfig'. At the moment this is 6 times! If you miss one, then the result may be no change which can be very confusing. See below for another approach.

prepareconfig

This is used to prepare the config for a particular flavour. It assembles the default config for the flavour, then embeds CONFIG_VERSION_SIGNATURE in the config file, which is a string like 'Ubuntu ${release}-${revision}-${flavour}' where release and revision are obtained from the changelog and the flavour is passed in on the command line.

This is useful when starting development on a board and you want to build in-tree:

./chromeos/scripts/prepareconfig chromeos-tegra2
export ARCH=arm
export CROSS_COMPILE=armv7a-cros-linux-gnueabi-
make oldconfig    #(to pick up new options, if any)
make
...

This script is used in the emerge. An example resulting string is 'Ubuntu 2.6.32-0.1-chromeos-tegra2'.

splitconfig

This takes all config.* files in the currect directory and works out the common options in each. It writes these to config.common, then generates new config.* files (overwriting the original ones) with these common options removed. As a side effect, all config options will be in sorted order.

This script is used by kernelconfig to extract the common options for an architecture, then again on a second level to extract the common options for Chromium OS.

Using the kernelconfig script

The kernel config is split into several config files - generic, chrome-specific, architecture-specific and board specific. Automatic tools split and combine these configs.

If you want to edit the configuration for a particular board etc. then you need to do something like:

$ cd .../src/third_party/kernel-next
$ ./chromeos/scripts/kernelconfig editconfig

This will run 'make menuconfig' for each part of the config. At the time of writing (Oct-10) this is:

  • x86_64/chromeos-intel-pineview.flavour.config
  • i386/chromeos-intel-menlow.flavour.config
  • i386/chromeos-pinetrail-i386.flavour.config
  • i386/chromiumos-i386.flavour.config
  • armel/chromeos-arm.flavour.config
  • armel/chromeos-tegra2.flavour.config
  • armel/chromiumos-arm.flavour.config

You need to figure out which part your config options appear in, and then make the changes when that config comes up. When it says 'press a key', you have to press <enter>.

Make a change to the config 

Run editconfig to modify each config appropriately using menuconfig and then regenerate the splitconfigs. The editconfig script will run "make menuconfig" on each flavor config. Please make appropriate changes for each menuconfig run and the script will generate the correct splitconfig.

cd /path/to/kernel
chromeos/scripts/kernelconfig editconfig # regenerate splitconfig

Alternative Method to Edit Config

Maybe this will work for you:

  • Look for the kernel config option you want to edit
../kernel-next$ grep -rs CONFIG_NETWORK_FILESYSTEMS chromeos/config/
chromeos/config/base.config:# CONFIG_NETWORK_FILESYSTEMS is not set
  • Now edit that file chromeos/config/base.config to change the config like this:
# CONFIG_NETPOLL_TRAP is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NETWORK_SECMARK=y
# CONFIG_NET_9P is not set
  • Now run this to recreate all the configs based on your changes
../kernel-next$ chromeos/scripts/kernelconfig oldconfig
  • If you are asked questions, press return to accept the default. If needed you can change it by editing the file on your next run around this method.
  • Rinse and repeat

Comparing in-tree config to split config

This might not be useful, but:

# get full flavour config sorted, without leading #
FLAVOUR=chromeos-tegra2 cat chromeos/config/base.config \
  chromeos/config/armel/common.config \
  chromeos/config/armel/$FLAVOUR.flavour.config | \
  grep CONFIG_ | sed "s/.*CONFIG/CONFIG/" | sort -u >1.emerge

# purify .config in the same way
cat .config | grep CONFIG_ | sed "s/.*CONFIG/CONFIG/" | sort >2.config

# compare
diff 1.emerge 2.config

Manual Building

Here is how to build the kernel yourself manually, from within the chroot.

Make sure you have done something like:

export B="tegra2_seaboard"
export ARCH=arm
export CROSS_COMPILE=armv7a-cros-linux-gnueabi-

# indicate that you are making kernel changes
cros_workon start --board=$B sys-kernel/chromeos-kernel-next

As you probably know, the cros_workon start tells the build system to use your local source install of the official source. Then set up the config:

# set up the .config file
./chromeos/scripts/prepareconfig chromeos-tegra2
make oldconfig

# edit config
make menuconfig
# (make your changes)

Now, after you make a kernel change, you can simply type make as normal:

# build the kernel and modules
make

# or maybe: build the uImage on an 8 core machine
make -j10 uImage

# or both!
make && make uImage

Generate a new splitconfig after adding new Kconfig options

Run oldconfig to regenerate the splitconfigs. The oldconfig script will run "make oldconfig" on each flavor config. Please answer appropriately when prompted by oldconfig.  /path/to/kernel may be <something>/src/third_party/kernel/files, but this may change.

cd /path/to/kernel
chromeos/scripts/kernelconfig oldconfig # regenerate splitconfig

Adding a new config

Copy the new config to the appropriate place in the chromeos/config and then run oldconfig

cd /path/to/kernel
cp config.flavour.chromeos-new .config
make ARCH=${ARCH} oldconfig
cp .config chromeos/config/<arch>/<flavour>.flavour.config
chromeos/scripts/kernelconfig oldconfig # regenerate splitconfig

How can I find the list of flavour configs

cd /path/to/kernel
find chromeos/config -name \*.flavour.config

How to regenerate and validate splitconfigs from single config

cd /path/to/kernel
cp <single config> chromeos/config/<arch>/<flavour>.flavour.config
chromeos/scripts/kernelconfig oldconfig
chromeos/scripts/prepareconfig <flavour>
make ARCH=${ARCH} oldconfig
diff .config <single config>
Comments