What is the most efficient and elegant way develop/debug linux kernel

不打扰是莪最后的温柔 提交于 2019-11-29 09:00:31

Here is my notes on how to build and run the custom kernel.

Obtaining sources

Linus Torvalds' tree is [1].

It's marked as "mainline" on [2].

To clone it use information from [1]:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

Now go to linux/ dir and checkout on master branch (we need to use most recent changes as starting point for development):

$ cd linux
$ git checkout master

Before actual development don't forget to update your branch:

$ git pull --rebase

Building

Kernel version on my machine:

$ uname -r

3.16.0-4-amd64

To obtain config from the system running on my machine:

$ cp /boot/config-`uname -r` ./.config

To update my config (with default answers) I used next command:

$ make olddefconfig

To disable (to not build) modules which are not loaded in my current system:

$ make localmodconfig

To answer all questions with default answer, I just clicked Enter until finish (just two times actually).

Next I did:

$ make menuconfig

and chose next config options:

CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCALVERSION="-joe"

Setting up ccache and build environment:

$ ccache -C
$ ccache -M 4G
$ export CC="ccache gcc"

Build kernel (using ccache):

$ reset
$ make -j4
$ make -j4 modules

Built kernel image is:

arch/x86_64/boot/bzImage

Installing

Installing modules for your kernel:

$ sudo make modules_install

Installing new kernel:

$ sudo make install

Installed modules reside at /lib/modules/*-joe/kernel/.

Installed kernel files reside at /boot/*joe*:

- config-*joe*
- initrd.img-*joe*
- System.map-*joe*
- vmlinuz-*joe*

update-grub was run as part of make install script, so no need to run it manually.

NOTE: modules_install must be run before install, because install rule is needed for populating initramfs image with modules. Check size of /boot/initrd.img-*joe* file: it must be >= 15 MiB (if it's smaller, chances are modules are not in there).

Start custom built kernel

Usually your custom kernel should have version bigger than your distro kernel, so custom kernel should be run by default. If no, read further.

Reboot, go to GRUB, select next entries:

-> Advanced options for Debian GNU/Linux
  -> Debian GNU/Linux, with Linux 4.0.0-rc7-joe-00061-g3259b12

Make your distro kernel load by default

Since video may not work in your custom kernel (video drivers must be rebuild for this), you may want make distro kernel be loaded by default by GRUB.

For this just edit /etc/default/grub file:

$ sudo vim /etc/default/grub

and change line

GRUB_DEFAULT=0

to

GRUB_DEFAULT="1>3"

where "1>3" means: - go to 2nd line in GRUB, enter - and boot using 4th line.

After this run:

$ sudo update-grub

NOTE: do not edit /boot/grub/grub.cfg file as it's auto-generated and will be replace after each update-grub command.

Removing custom kernel

If you don't need your custom kernel anymore, you may want to remove it. To remove installed kernel, do next.

  1. Remove all files installed to /boot:

    $ sudo rm -f *joe*
    
  2. Remove all modules installed:

    $ sudo rm -rf /lib/modules/*joe*
    
  3. Update GRUB:

    $ sudo update-grub
    

Cleaning up built kernel

If you don't need to do incremental build and want to do clean build instead (e.g. you made checkout to another version), you may want to clean your built files first:

$ make -j4 distclean

Links

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/

[2] https://kernel.org/

[3] http://kernelnewbies.org/FAQ/KernelCompilation

As said earlier,the only step that is redundant and is also time consuming is "make clean" if you are recompiling the kernel. kernel build system uses Makefiles to build which in turn follows incremental build procedure i.e. the build system compares the last recent build time of the source files and their respective object files and if timestamp of a source file happens to be more recent than its object file,then the source file is compiled again else skipped.Where as "make clean" removes all the previous build outputs and make the kernel modules ready to be built from scratch.

  1. use ccache; this speeds up subsequent builds significantly

  2. boot over network; bootloader of embedded devices have usually some tftp download mechanism; for PC you can use PXE boot

  3. place the modules on an NFS root filesystem which gets filled by make modules-install INSTALL_MOD_PATH=$nfs-root

  4. when you work on a single driver only, you can build only this by make -C $kernelsources M=$driverpath

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!