Kernel Modification Example Kernel modification involves changing or adding configurations to an existing kernel, adding recipes to the kernel that are needed to support specific hardware features, or even changing the source code itself. This section presents some simple examples that modify the kernel source code, change the kernel configuration, and add a kernel source recipe.
Modifying the Kernel Source Code This example adds some simple QEMU emulator console output at boot time by adding printk statements to the kernel's calibrate.c source code file. Booting the modified image causes the added messages to appear on the emulator's console. For a general flow of the example, see Kernel Modification Workflow earlier in this manual.
Understanding the Files You Need Before you modify the kernel you need to know what Git repositories and file structures you need. Briefly, you need the following: A local Yocto Project files Git repository The poky-extras Git repository placed within the local Yocto Project files Git repository A bare clone of the Linux Yocto kernel that you want to modify A copy of that bare clone in which you make your source modifcations The following illustration summarizes what you need: Here is a brief description of the four areas: Local Yocto Project Files: This Git repository contains all the metadata that supports building images in the Yocto Project build environment. Note that the Git repository in our example also contains the poky-extras Git repository, which contains the kernel metadata specific to building a kernel image. The Local Yocto Project files Git repository also contains the build directory and configuration files that let you control the build. poky-extras: This Git repository contains the meta-kernel-dev layer, which is where you make changes that append to the kernel build recipes. You edit .bbappend files to point the build to your local kernel source files and to define the kernel being built. This Git repository is a gathering place for extensions to the Linux Yocto (or really any) kernel recipes that faciliate the creation and development of kernel features, BSPs or configuration Bare Clone of the Linux Yocto Git Repository: This bare Git repository tracks the upstream Git repository of the Linux Yocto kernel you are changing. As mentioned, when you build the Linux Yocto kernel image you point to this repository so that the build process can locate the locally changed source files. When you modify the kernel image you must work with a bare clone. Copy of the Linux Yocto Kernel Bare Clone: This Git repository contains the actual source files that you modify. Any changes you make to files in this location need to ultimately be pushed to the bare clone using the git push command.
Setting Up the Local Yocto Project Files Git Repository You can get files through tarball extraction or by cloning the poky Git repository. See the bulleted item Yocto Project Release in Getting Setup earlier in this manual for information on how to get these files. This example assumes the name of the Git repository is poky. Once you have the repository set up, you have many development branches from which you can work. From inside the repository you can see the branch names and the tag names used in the Git repository using either of the following two commands: $ cd poky $ git branch -a $ git tag -l For this example, we are going to use the Yocto Project 1.1_M3 Release, which maps to the 1.1_M3 branch in the repository. These commands create a local branch named 1.1_M3 that tracks the remote branch of the same name. $ git checkout -b 1.1_M3 origin/1.1_M3 Branch 1.1_M3 set up to track remote branch 1.1_M3 from origin. Switched to a new branch '1.1_M3'
Setting Up the <filename>poky-extras</filename> Git Repository This example places the poky-extras Git repository inside of poky. See the bulleted item The poky-extras Git Repository in Getting Setup earlier in this manual for information on how to get these files.
Setting Up the Bare Clone and its Copy This example modifies the linux-yocto-2.6.37 kernel. Thus, you need to create a bare clone of that kernel and then make a copy of the bare clone. See the bulleted item Linux Yocto Kernel in Getting Setup earlier in this manual for information on how to do that. The bare clone exists simply as the receiving end of git push commands after you make edits and commits inside the copy of the clone. The copy (linux-yocto-2.6.37 in this example) has to have a local branch created and checked out for your work. The following commands create and checkout the branch: $ cd ~/linux-yocto-2.6.37 $ git checkout -b common-pc-base origin/yocto/standard/common-pc/base Branch common-pc-base set up to track remote branch yocto/standard/common-pc/base from origin. Switched to a new branch 'common-pc-base'
Building and Booting the Default QEMU Kernel Image In this example before we make changes to the kernel image we will build it first and see how it boots inside the QEMU emulator. Because a full build can take hours, you should check two variables in the build directory that is created after you source the oe-init-build-env script. You can find these variables BB_NUMBER_THREADS and PARALLEL_MAKE in the build/conf directory in the local.conf configuration file. By default, these variables are commented out. If your host development system supports multi-core and multi-thread capabilities you can uncomment these statements and set the variables to significantly shorten the full build time. As a guideline, set BB_NUMBER_THREADS to twice the number of cores your machine supports and set PARALLEL_MAKE to one and a half times the number of cores your machine supports. These commands build the default qemux86 image: $ cd ~/poky $ source oe-init-build-env ### Shell environment set up for builds. ### You can now run 'bitbake <target>' Common targets are: core-image-minimal core-image-sato meta-toolchain meta-toolchain-sdk adt-installer meta-ide-support You can also run generated qemu images with a command like 'runqemu qemux86' $ bitbake -k core-image-minimal The source command sets up the build environment, while the following bitbake command starts the build. After the build completes, you can start the QEMU emulator using the resulting image qemux86 as follows: $ runqemu qemux86 As the image boots in the emulator, console messages and status appear across the terminal window. Because the output scrolls by quickly it is difficult to read. To examine the output you can log into the system using the login root with no password. Once you are logged in, you can issue the following command to scroll through the console output: # dmesg | less Take note of the output as you will want to look for your inserted print command output later in the example.
Changing the Source Code and Pushing it to the Bare Clone The file you change in this example is named calibrate.c and is located in the linux-yocto-2.6.37 Git repository in init. For this example simply insert several printk statements at the beginning of the calibrate_delay function. Now let's look at the changes to the source code. Here is the unaltered code at the start of this function: void __cpuinit calibrate_delay(void) { unsigned long ticks, loopbit; int lps_precision = LPS_PREC; static bool printed; if (preset_lpj) { . . . This example uses the following five printk statements just after defining lps_precision: void __cpuinit calibrate_delay(void) { unsigned long ticks, loopbit; int lps_precision = LPS_PREC; printk("*************************************\n"); printk("* *\n"); printk("* HELLO YOCTO KERNEL *\n"); printk("* *\n"); printk("*************************************\n"); static bool printed; if (preset_lpj) { . . . After making and saving your changes, you need to stage them for the push. The following Git commands stage and commit your changes: $ git add calibrate.c $ git commit --signoff Once the source code has been modified you need to use Git to push the changes to the bare clone. If you do not push the changes then the Yocto Project build system will not pick the changed source files. To push the changes do the following: $ git push origin common-pc-base:yocto/standard/common-pc/base For general information on how to push a change using Git, see [WRITER'S NOTE: need the link to the submitting a change section].
Changing Build Parameters for Your Build At this point the source has been changed and pushed. Now you need to define some variables used by the Yocto Project build system to locate your source. You essentially need to identify where to find the kernel recipe and the changed source code. You also need to be sure some basic configurations are in place that identify the type of machine you are building and to help speed up the build should your host support multiple-core and thread capabilities. Do the following to make sure the build parameters are set up for the example. Once you set up these build parameters they should not have to change unless you change the target architecture of the machine you are building or you move the bare clone, copy of the clone, or the poky-extras repository: Build for the Correct Target Architecture - The local.conf in the build directory defines the build's target architecture. By default, MACHINE is set to qemux86, which specifies a 32-bit Intel Architecture target machine suitable for the QEMU emulator. So for this example, MACHINE is correctly configured. Optimize Build Time - Also in the local.conf file are two variables that can speed your build time if your host supports multi-core and multi-thread capabilities: BB_NUMBER_THREADS and PARALLEL_MAKE. If the host system has multiple cores then you can optimize build time by setting BB_NUMBER_THREADS to twice the number of cores and setting PARALLEL_MAKE to one and a half times the number of cores. Identify Your meta-kernel-dev Layer - The BBLAYERS variable in the bblayers.conf found in the poky/build/conf directory needs to have the path to your local meta-kernel-dev layer. By default, the BBLAYERS variable contains paths to meta and meta-yocto in the poky Git repository. Add the path to your meta-kernel-dev location. Here is an example: BBLAYERS = " \ /home/scottrif/poky/meta \ /home/scottrif/poky/meta-yocto \ /home/scottrif/poky/poky-extras/meta-kernel-dev \ " Identify Your Source Files - In the linux-yocto-2.6.37.bbappend file located in the poky-extras/meta-kernel-dev/recipes-kernel/linux directory you need to identify the location of the local source code, which in this example is the bare clone named linux-yocto-2.6.37.git. To do this, set the KSRC_linux_yocto to point to your local linux-yocto-2.6.37.git Git repository by adding the following statement: KSRC_linux_yocto ?= /home/scottrif/linux-yocto-2.6.37.git Specify the Kernel Machine - Also in the linux-yocto-2.6.37.bbappend you need to specify the kernel machine with the following statement: KMACHINE_qemux86 = "yocto/standard/common-pc/base"
Building and Booting the Modified QEMU Kernel Image Next, you need to build the modified image. Do the following: Your environment should be set up since you previously sourced the oe-init-build-env script. If it isn't, source the script again from the poky again. Be sure any old images are cleaned out by running the cleanall BitBake task as follows: $ bitbake -c cleanall linux-yocto Build the kernel image using this command: $ bitbake -k core-image-minimal Next, boot the modified image in the QEMU emulator using this command: $ runqemu qemux86 Log into the machine using root with no password and then use the following shell command to scroll through the console's boot output. # dmesg | less You should see the results of your printk statements as part of the output.