Anakin Tung
Anakin Tung

Reputation: 419

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

Recently I start to develop the linux device driver,

I face a problem, when I want to debug with kernel code, and add some printk debug message in the kernel file.

for example, recently I add some printk() and dump_stack() in the __debug_locks_off() which resides in include/linux/debug_locks.h.

Then I do the following steps, which is very time consuming.

make clean
make bzImage
make modules
make modules_install
mkinitrfmfs -o /boot/initrd.img 3.12.6[my kernel version] 
cp arch/x86/boot/bzImage /boot
update-grub 

Then reboot and choose my new kernel version.

I don't know if there are some redundant steps? Any guideline or help will be appreciate.

Upvotes: 0

Views: 849

Answers (3)

Sam Protsenko
Sam Protsenko

Reputation: 14743

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

Upvotes: 2

ensc
ensc

Reputation: 6984

  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

Upvotes: 0

sudipta ranjan
sudipta ranjan

Reputation: 1

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.

Upvotes: 0

Related Questions