This is a LinuxChix course page. This and the other courses pages are yet to be ported to the new LinuxChix website. Please feel free to browse the course in the meantime.

We appreciate your patience.

LinuxChix(tm)

Kernel Hacking Lesson #3: Compile Your Kernel

At this point, you have your kernel source, and you've run one of the configuration programs and (very important) saved your new configuration file. Don't laugh - I've done this many times.

First, build the kernel:

On an x86:

   # make -j<number of jobs> bzImage

On a PPC:

   # make -j<number of jobs> zImage

Where <number of jobs> is two times the number of cpus in your system. So if you have a single cpu Pentium III, you'd do:

   # make -j2 bzImage

What the -j argument tells the make program is to run that many jobs (commands in the Makefile) at once. make knows which jobs can be run at the same time and which jobs need to wait for other jobs to finish before they can run. Kernel compilation jobs spend enough time waiting for I/O (for example, reading the source file from disk) that running two of the jobs per processor results in the shortest compilation time. NOTE: If you get a compile error, run make with only one job so that it's easy to see where the error occurred. Otherwise, the error message will be hidden in the output from the other make jobs.

If you have enabled modules, you'll need to compile them with the command:

   # make modules

If you are planning on loading these modules on the same machine they are compiled on, then run the automatic module install command. But FIRST - save your old modules!

   # mv /lib/modules/`uname -r` /lib/modules/`uname r`.bak
   # make modules_install

This will put all the modules in subdirectories of the /lib/modules/<version> directory. You can find out what <version> is by looking in include/linux/version.h.

Recompiling the kernel

So, now you've compiled the kernel once. Now you want to change part of the kernel and recompile it. What do you need to do?

In most cases, simply running make -j2 bzImage (or whatever your kernel compile command is) again will do the trick. If you've altered a module's source file, then just do make modules and make modules_install (if appropriate).

Sometimes, you'll change things so much that make can't figure out how to recompile the files correctly. make clean will remove all the object and kernel object files (ending in .o and .ko) and a few other things. make mrproper will do everything make clean does, plus remove your config file, the dependency files, and everything else that make config creates. Be sure to save your config file in another file before running make mrproper. Afterwards, copy the config file back to .config and start over, beginning at make menuconfig. A make mrproper will often fix strange kernel crashes that make no sense and strange compilation errors that make no sense.

Here are some tips for recompilation when you are working on just one or two files. Say you are changing the file drivers/char/foo.c and you are having trouble getting it to compile at all. You can just type (from the drivers/char/ directory) make -C path/to/kernel/src SUBDIRS=$PWD modules and make will immediately attempt to compile the modules in that directory, instead of descending through all the subdirectories in order and looking for files that need recompilation. If drivers/char/foo.c is a module, you can then insmod the drivers/char/foo.ko file when it actually does compile, without going through the full-blown make modules command. If drivers/char/foo.c is not a module, you'll then have to run make -j2 bzImage to link it with all the other parts of the kernel.

The && construct in bash is very useful for kernel compilation. The bash command line:

   # thing1 && thing2

Says, "Do thing1, and if it doesn't return an error, do thing2." This is useful for doing something only if a compile command succeeds.

When I'm working on a module, I often use the following command:

   # rmmod foo.ko && make -C path/to/kernel/src SUBDIRS=$PWD modules \
     && insmod foo.ko

This says, "Remove the module foo.ko, and if that succeeds, compile the modules in drivers/char/, and if that succeeds, load the kernel module object file." That way, if I get a compile error, it doesn't load the old module file and it's obvious that I need to fix my code.

Don't let yourself get too frustrated! If you just can't figure out what's going on, try the make mrproper command. If you still can't figure it out, post your question on grrls-only. It's good to try to figure things out by yourself, but it's not good if it makes you give up trying at all.

© LinuxChix 2000-2006 unless otherwise specified Hosting provided by Intel and OSU Open Source Lab.