Saturday 3 December 2016

Kernel Building

Building the kernel
      The kernel build system (termed as kbuild) is bundled along with the kernel sources.
      The kbuild system is based on the GNU make, hence all the commands are given to “make”
      The kernel build procedure is divided into four steps:
      Setting up cross-development environment
      Configuration process
      Building the object files and linking them to make the kernel image
      Building dynamic loadable modules
      Setting up cross-development environment
      As linux supports many architectures, the kbuild procedure should be configured for the architecture for which the kernel image and modules are being built.

Configuration process
      This is the component selection procedure
      The list of what software needs to go to into the kernel and what can be compiled as modules can be specified using this step.
      At the end of this step, kbuild records this information in a set of known files, so that the rest of kbuild is aware of the selected components.
      Component selection objects are normally
     Processor selection
     Board selection
     Driver selection
     Some generic kernel options

Front ends to the configuration procedure
      make config
     This is a complicated way of configuring because this throws the component selection on your terminal and its time consuming
      make menuconfig
     This is the curses-based front end to the kbuild procedure
     This is useful on hosts that do not have accesses to a graphics display
      make xconfig
     Graphical front end
      make oldconfig
     This option allows the build to retain defaults from an existing configuration and prompt only for new changes.

Building the object files and linking them to make the kernel image
      Once component selection is done, the next step to build the kernel image
      The name of kernel image is “vmlinux” and is the output if you just type “make” command.
      Additional post processing steps are needed such as compressing the kernel image, adding bootstrapping code and so on.
      The post processing actually creates the image that can be used on the target

Building dynamically loadable modules
      The command “make modules” will do the job of building the kernel modules.

Understanding the build procedure
      Top-level Makefile
     This makefile in kernel sources is responsible for building both the kernel image and the modules.
     It does so by recursively descending into the subdirectories of the kernel source tree
     The list of subdirectories that need to be entered into depends on the component selection
      Every architecture (the processor port) needs to export a list of components for selection during the configuration process.
     Any processor flavor. If your architecture is defined as ARM, then need to define the ARM flavor
     The hardware board
     Any board specific hardware configuration
     Kernel subsystem components, more or less remain uniform across all architectures
      Each architecture needs to export an architecture-specific Makefile. The list of build information is unique to every architecture
     The subdirectories that need to be visited for building the kernel
     The flags that needs to be passed to various tools
     The post processing steps once the image is built
     These are supplied in the architecture specific Makefile in the arch/$(ARCH) subdirectory

Configuration process
      Every kernel subsection defines the rules for configuration in a separate files, “Kconfig”
      A configuration item is stored as a name=value pair.
      The name of configuration item starts with a CONFIG_ prefix. The rest of the name is the component name defined in the configuration file.
      The following values the configuration variable can have:
     Bool : configuration variable can have value “y” or “n”
     Tristate:  can have “y”, “n” or “m” (for module)
     String: Any ASCII string
     Integer: Any decimal number
      User to prompt for assigning value to this variable else default value is assigned to this variable.
      Dependencies can be created while defining the variable
      Each configuration can have Help text
      The kbuild exports the list of selected components by creating the “.config” file in top directory kernel sources.
      This file contains the list of selected components in name = value format.
      While evaluating a source file as a built candidate, the component value field is used to find out if the component should be built as mofule or directly linked to kernel.
      Lets assume for e.g in drivers/net directory a configuration variable CONFIG_SAMPLE=y
      In drivers/net/Makefile there will be line
            obj-$(CONFIG_SAMPLE)+= sample.o
      When this makefile is encounted, the kbuild will transfer it into
            obj-y=sample.o, because .config file has defined CONFIG_SAMPLE=y
      The kernel build has a rule to build obj-y, hence this file is chosen to be built into the kernel
      Obj-m=sample.o, the rule to build the kernem modules.

Make config
make config
scripts/kconfig/conf arch/i386/Kconfig
*
* Linux Kernel Configuration
*
* Code maturity level options
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [Y/n/?]
Y
*
* General setup
*

Default configuration options
      The kernel contains more than 2000 options, therefore the configuration can be very time consuming, an alternative is “default configuration”
      Every kernel comes with the “default” configuration.
      This configuration is loosely based on the defaults that the kernel maintainer of that architecture feels are the best options to be used. In some cases, it is merely the configuration that is used by the kernel maintainer himself for his personal machines. This is true for the i386 architecture, where the default kernel configuration matches closely what Linus Torvalds uses for his main development machine.
      $ make defconfig
      A huge number of configuration options will scroll quickly by the screen, and a “.config” file will be written out and placed in the kernel directory. The kernel is
      now successfully configured, but it should be customized to your machine in order to make sure it will operate correctly.

Building the kernel
      Now that you have created a kernel configuration that you wish to use, you need to build the kernel.
      $ make
CHK include/linux/version.h
UPD include/linux/version.h
SYMLINK include/asm -> include/asm-i386
SPLIT include/linux/autoconf.h -> include/config/*
CC arch/i386/kernel/asm-offsets.s
GEN include/asm-i386/asm-offsets.h
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/modpost.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/bin2c
CC init/main.o

Building portion of the kernel
      When doing kernel development, sometimes you wish to build only a specific subdirectory or a single file within the whole kernel tree.
      $ make M=drivers/usb/serial
      Source in one place and output in another
      “O” option to make to put all compiled code into the separate output directory
      $make O=`pwd`/output_dir

Building and installing modules
      If you have built any modules and want to use use this method to install a kernel,
      first enter: # make modules_install
      This will install all the modules that you have built and place them in the proper location in the filesystemfor the new kernel to properly find. Modules are placed in the /lib/modules/kernel_version directory, where kernel_version is the kernel version of the new kernel you have just built.
      After the modules have been successfully installed, the main kernel image must be
      installed:
      # make install
This will kick off the following process:
1. The kernel build system will verify that the kernel has been successfully built properly.
2. The build system will install the static kernel portion into the /boot directory and name this executable file based on the kernel version of the built kernel.
3. Any needed initial ramdisk images will be automatically created, using the modules that have just been installed during the modules_install phase.
4. The boot loader program will be properly notified that a new kernel is present, and it will be added to the appropriate menu so the user can select it the next time the machine is booted.
5. After this is finished, the kernel is successfully installed, and you can safely reboot and try out your new kernel image. Note that this installation does not overwrite any older kernel images, so if there is a problem with your new kernel image, the old kernel can be selected at boot time.


No comments:

Post a Comment