

Recall that, during the course of your very first lesson, you managed to:
git),Recall, as well, that that last kernel "installation" step will, for any Linux distribution, inevitably consist of the following general steps, however they're accomplished:
vmlinuz-* compressed kernel image and a corresponding initrd-* initial ramdisk image into the /boot directory,/lib/modules, andAll incredibly straightforward, so what else is there to know about this? I'm glad you asked.
(Aside: I won't always be available to immediately address questions people leave in the comments section so I'm going to reiterate -- use the comments section to chat and ask each other questions. Make this interactive. That's part of the learning process.)
Recall that, back in Lesson 1, we cheated a little bit and didn't spend a lot of time actually configuring our new kernel source -- we played it safe and simply used, as a template, an existing config file that came with the initial OS installation.
Once you've done that, though, and you've established that you can build and boot a new kernel based on that, the next obvious step is to invoke one of the kernel configuration targets, say:
$ make menuconfig
and spend some time poking around for obvious reasons -- that's where you'll get a good idea of how many choices you have in building a new kernel. I won't spend much time going over all of the possible choices for kernel feature selection. Again, I'll recommend Greg Kroah-Hartman's excellent book Linux Kernel in a Nutshell. However, I will treat you to one handy feature of the config process.
Occasionally, you'll read advice that says that to build in, for example, the "kexec" feature, you should select the CONFIG_KEXEC config variable, which is terrific if you happen to know where in the murky depths of the configuration menus that variable happens to live.
If you don't though, no problem -- simply start the configuration utility and search for the string by typing:
/kexec [slash, followed by string of interest, then ENTER]
What you get back is a list of every single kernel option containing that text string, and its location in the menu structure. Very handy indeed. Why you would select that particular feature and what you'd do with it -- well, that's the topic for a future lesson. I'm just showing you how the search feature works.
make targets and pre-defined configurationsIn case you hadn't figured it out by now, almost all kernel tree configuration is done through the top-level Makefile by invoking one of its numerous targets, the entire list of which can be displayed with:
$ make help
Perhaps the most useful target for beginners is defconfig (short for "default config") which simply sets your .config to an established set of defaults for your system and architecture. And how can you see these defaults? Simple -- from the top of the kernel source tree, just run:
$ find arch -name "*defconfig"
and you'll see dozens of default config files for all of the kernel's supported architectures. Assuming you're working on an x86-like architecture, you're probably interested only in these:
$ find arch/x86 -name "*defconfig" arch/x86/configs/x86_64_defconfig [64-bit version] arch/x86/configs/i386_defconfig [32-bit version] $
In addition, running make help shows you some other rather odd configuration targets:
... Configuration targets: ... randconfig - New config with random answer to all options defconfig - New config with default answer to all options allmodconfig - New config selecting modules when possible allyesconfig - New config where all options are accepted with yes allnoconfig - New config where all options are answered with no ...
Those targets are certainly a bit unusual, and you might wonder why anyone would configure a kernel so strangely. Actually, those targets have value for stress-testing the build process. It's not enough to verify that the kernel can build for typical configurations; it's good practise to see if those extreme corner cases also build. Feel free to configure your kernel tree with one of them and see if the build actually works.
If you want more output during the kernel and module compilation stage, running make help shows you how to get that and also how to do static code analysis on the source if you're interested in that sort of thing:
... make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build make V=2 [targets] 2 => give reason for rebuild of target ... make C=1 [targets] Check all c source with $CHECK (sparse by default) make C=2 [targets] Force check of all c source with $CHECK
If you're simply playing and want to tidy up before trying another configuration and build, there are three clean-type targets:
$ make help
...
Cleaning targets:
clean - Remove most generated files but keep the config and
enough build support to build external modules
mrproper - Remove all generated files + config + various backup files
distclean - mrproper + remove editor backup and patch files
That last one, distclean, removes every vestige of any previous configuration or build and should take you back to, literally, the pristine, distribution version of the kernel source. That includes even removing your .config file so don't use that target unless you're serious about cleaning your source tree.
Until now, all of your configuration and compilation has been done in the same directory as the kernel source itself, which is fine for most people but, in some cases, it's more convenient to preserve the kernel source untouched and have all the configuration output and compilation results generated in a remote directory. No problem.
From the top of the kernel source tree, you can do something resembling the following:
$ mkdir ../build_dir $ make O=../build_dir menuconfig $ make O=../build_dir $ sudo make O=../build_dir modules_install
and so on, and so on. And what's the benefit?
For one thing, it leaves the source unpolluted by all of those output files, which makes it easier if you want to search the tree using something like grep.
For another, it allows you to work with a directory of kernel source for which you have no write access. Perhaps it's a system directory, or in some other user's home directory. As long as you can cd to the top of the source tree and have read access to all of the source, you can generate all of the output elsewhere.
And, finally, this feature lets you work with multiple configurations and builds simultaneously, since you can simply switch from one output directory to another on the fly, using the same kernel source directory as the basis for all of those builds.
There is only one caution, though. Once you initially select an output directory, you must specify that output directory on every subsequent make invocation, but that should simply be obvious. In fact, the last time I checked, you can't use the remote directory feature if your kernel source tree already shows signs of internal configuration. In short, this feature is meant to be used with a pristine kernel source tree.
Recall from the first lesson that, if you plan on building and installing your own kernels, you should take care that the version strings that they are stamped and installed with don't clash so that they you end up overwriting an earlier kernel that you wanted to keep. You can display the kernel release string of the running kernel with
$ uname -r 2.6.35-crash+ $
And you might remember that you can modify that "extra version" information by simply editing the content at the top of the kernel Makefile before starting a new configuration:
VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 35 EXTRAVERSION = -crash <-- change that part
In fact, there's considerably more to it than that so I'll simply point you at how the configuration and build process generates the release number that will be assigned to the new kernel.
First, there's this incomprehensible excerpt from the Makefile:
# Build the kernel release string # # The KERNELRELEASE value built here is stored in the file # include/config/kernel.release, and is used when executing several # make targets, such as "make install" or "make modules_install." # # The eventual kernel release string consists of the following fields, # shown in a hierarchical format to show how smaller parts are concatenated # to form the larger and final value, with values coming from places like # the Makefile, kernel config options, make command line options and/or # SCM tag information. # # $(KERNELVERSION) # $(VERSION) eg, 2 # $(PATCHLEVEL) eg, 6 # $(SUBLEVEL) eg, 18 # $(EXTRAVERSION) eg, -rc6 # $(localver-full) # $(localver) # localversion* (files without backups, containing '~') # $(CONFIG_LOCALVERSION) (from kernel config setting) # $(LOCALVERSION) (from make command line, if provided) # $(localver-extra) # $(scm-identifier) (unique SCM tag, if one exists) # ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO) # .scmversion (only with CONFIG_LOCALVERSION_AUTO) # + (only without CONFIG_LOCALVERSION_AUTO # and without LOCALVERSION= and # repository is at non-tagged commit) # # For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has # been revised beyond a tagged commit, `+' is appended to the version string # when not overridden by using "make LOCALVERSION=". This indicates that the # kernel is not a vanilla release version and has been modified.
And if that's not confusing enough, I recommend perusing the code in the utility script scripts/setlocalversion to see how even more can be tacked onto the release string that will be used for your new kernel.
However, to make a long story short, if you want to see what release string will be used:
$ make kernelrelease 2.6.35-crash+ $
at which point you can decide if you need to do any adjustment to avoid release string conflicts.
While the final topic for this lesson is somewhat beyond the scope of the course, it's worth seeing at least briefly how you would configure your kernel for building on another architecture.
Take a look at the currently-supported architectures:
$ ls arch alpha blackfin h8300 m32r microblaze parisc score um arm cris ia64 m68k mips powerpc sh x86 avr32 frv Kconfig m68knommu mn10300 s390 sparc xtensa $
and peruse what the configuration process would look like with, for example:
$ make ARCH=blackfin menuconfig
You won't be able to actually build a kernel for any other architecture until you install the appropriate cross-compiler toolchain -- a topic we might very well return to in a future lesson.
We're almost done with establishing the fundamentals we need to start some kernel programming. The last supporting topic we need to cover is the manipulation and examination of loadable kernel modules, which is the topic for the next lesson. And once that's done, starting with lesson four, we'll jump right into writing, compiling and loading our first kernel modules.
And you won't want to miss that.
Possibly, but I want to be careful that I don't pad out the course with material that *some* people would like to see, but that most people wouldn't be interested in and would have no use for.
I'll probably write a short introduction to git for beginners and just make it a free tutorial for anyone, so you get the best of both worlds.
So, Im catching up here and want to subscribe to the course next week as well.
Everything went fine so far except for building the kernel in a seperate directory. (the error was saying something like "no target for make...."). I really thought I had it right though. What could be the cause there? I'm also happy for a (little) reading-advice about makefiles.
Btw. that error also came up a while ago when I tried to build a hello-world-module against some kernel in a seperate directory.
thanks for this so far. I hope to figure that issue out, then I think I'm prepared to dig into it.
greets!
martin
It looks like you have two issues here. First, there's simply building a new kernel in an output directory different from the kernel source directory -- I think that's your first issue.
Just follow the directions above *exactly*. You have to run every make command with the "O=" argument -- it sounds like you failed to do that for the configuration step. I've verified that the instructions given above appear to work.
As for the rest of your question, all that is going to be covered in Lesson 6, which I'm writing at the moment, so you just have to be patient and it will all be explained in time. For now, keep things simple and just build against the kernel tree that corresponds to your running kernel.
thanks for answering! that command did not work for me:
$ make O=../build_dir make
but make O=... did work.
I would have two little questions: Can I review all the warnings that come up during the build afterwards?
And: Is there a comfortable way to remove an installed kernel except for removing the files manually/by a script?
thanks a lot for this!
First, I'm not sure what you're saying about that initial make command. What exactly is the command that worked for you? The one I gave should work just fine, I've used it many times.
Also, the kernel source tree comes with some targets that build a new installable package, such as:
$ make rpm-pkg (for Fedora)
$ make deb-pkg (for Debian/Ubuntu)
so you can install the kernel as a package, and uninstall it later. At least, that's the theory.
We're aware of the time and budget pressures at most companies, normally accompanied by the plaintive cry from management of, "Yes, I know we need training on that topic, but I just can't afford to send my entire team away for three (or four or five) days to get it!" And that's where we come in.
The main focus at Crashcourse is to offer a choice of intense, 1-day, hands-on courses on specific topics in Linux and open source. And given that we already have the laptops for the delivery of that training, the idea is to show up early, set up a classroom, then spend the day teaching exactly the topic you're interested in. No travel time, and no wasted classroom time.
If we don't already have a course that addresses the topic you're interested in, drop us a note and we'll see what we can do -- our content providers can almost certainly put together a course that's precisely what you're after.
While there are a variety of sources for Linux and open source training, we at Crashcourse are taking a slightly different approach. Our philosophy is simple: exactly the training you want, and no wasted time or travel to get it.
A few more ideas
Submitted by shazkhan on Sun, 2010-06-13 01:49.A tutorial or lesson on git with a case study will also help a lot. For instance how will we maintain our own kernel code along with the mainstream and how will we update our code and also submit our code to the mainstream kernel code.
Some work on initrd might also help some of us. Keep up the good work.