How to Build Linux Kernels

来源:互联网 发布:人生哲理知乎 编辑:程序博客网 时间:2024/05/03 22:15

Original Page: http://www.cromwell-intl.com/unix/linux-kernel.html

How to Build Linux Kernels


This is a sizeable project,so let's start with an overview of the steps:

  1. Download the kernel source.
    • Understand the kernel versioning system.
    • Verify the digital signature (proving dataintegrity and source identity, at leastwithin a reasonable level of confidence).
  2. Install the kernel source in /usr/src/linux/.
  3. Configure a new kernel build.
    • Start with a useful initial kernelconfiguration file.
    • Go into the build configuration tool andcustomize your new kernel.
  4. Build that new kernel.
    • You can build it the traditional way,as a large collection of files,oryou can build it as a package and plug itinto your configuration management scheme.
  5. Install that new kernel.
  6. Reboot and run your new kernel!

Now that you see where we're going with this,let's get started!

Obtain the kernel source and understand the Linux kernel version numbers

The kernel source itself is available fromkernel.orgvia bothhttpand perhaps more efficiently throughFTP.

You do know how to useanonymous FTP,right?If not, see my how-to guide.

You will need the kernel tar archive file,a rather large file named something like:
linux-release.tar.bz2
and the corresponding very small digital signature file:
linux-release.tar.bz2.sign
where release is either three or fournumbers separated by dots, something like2.6.39or 2.6.39.3.

You need to understand the Linux release numbering scheme.Some kernel releases are three numbers:2.6.X to begeneral, or for example: 2.6.0, 2.6.1, 2.6.2, and so on.The difference between these is that 2.6.(X+1) containsnew features not found in 2.6.X.New device drivers, for recent hardware (maybe a networkinterface based on a new chipset)or for recently added software features (maybe a new networkingprotocol, or a new type of file system).Plus, of course, all the bugs found and fixed in the 2.6.X.The three-number 2.6.X kernel release include new featuresand bug fixes as that last number X increases.

But some kernel releases are three numbers: 2.6.X.Y.These are bug fixesonly — 2.6.X.1 makes asmall bug fix to the 2.6.X kernel,2.6.X.2 fixes a small bug in 2.6.X.1, and so on.The kernel organization has strict rules: these must bebug fixes only (no sneaking new features into thekernel!) and they must besmall (100 lines or lessof C code).The four-number 2.6.X.Y kernel releases are cumulativebug fixes to 2.6.X.

Which version do you need?That depends on your hardware — the latest 2.6.X.Yshould be fine, but you may not really need the very latestif the recent bug fixes were in drivers for hardware youdon't own.

Reason to use a later release — Your hardware includes a super-fast network interface chipsetthat was only supported starting with the 2.6.X release.You need to use at least 2.6.X!

Reason to use an even later release — You know that you need 2.6.X, and let's say it's the laststable major release.But look at the archive, is there a more recent 2.6.X.Ybug-fix release?If you are about to build a kernel, it only makes senseto include the latest tested bug fixes.

Reason notto upgrade to a later release —Your hardware is supported by the 2.6.X kernel you arealready using, and there are no 2.6.X.Y bug fixes thatinvolve drivers that you use.

Make absolutely certainthat you really have the kernel source

You do not want to run some hacker's operating systeminstead of the real kernel!You must verify both the integrity of the data youjust downloaded and the identity of its source.In other words, is itreally the kernel source,and did it really come from the Linux kernelorganization?

So, you need to check the digital signature withGNU Privacy Guard (GnuPG)or similar.

See the digital signature section of my"Just Enough Cryptography" pagefor an explanation of what digital signatures are.

See the page on verifyingdigital signatures to learn how toapply this technology.Verification is vital,but an explanation right here would make this page at leastas much about digital signatures as about building Linuxkernels!Really,go look at that other page,this page will be right here waiting for youwhen you get back....

Install the kernel source

From here forward, I will useoldreleaseandreleaseto stand for, well, whatever your old and new releases will be!You will have to think just a little.

You need to do some steps as root here,so become root with thesu command.

Your distribution or earlier work by yourself or otheradministrators may have already installed kernel sourceunder a directory named/usr/src/linux-oldreleasewith a symbolic link pointing to it.Find out, and if necessary,remove that link:

# cd /usr/src# ls -l# rm linux

Extract the kernel source with the following.You must be in the right directory,/usr/src,and I leave it up to you to figure out where you putthat downloaded archive file.I mean, really, if you can't handle that then youhave no business trying to build a kernel.But my experience tells me that I need to put twocommands here to keep some people from making horriblemesses of things:

# cd /usr/src# tar xvfj /path/to/linux-release.tar.bz2

Recreate the symbolic link, so that other software can becompiled on your system.If you're really curious, software making calls to systemlibraries need to find the include files under/usr/src/linux/include and this will support that.Or just take my word for it, this is important:

# ln -s linux-release linux# ls -l

The tar archive may have created files owned by somerandom UID other than 0, meaningroot.This is not good! Fix it and make sure that everythinghas worked so far:

# chown -R root:root linux-release# ls -laF

You should see something like the following:

total 16drwxr-xr-x    4 root     root         4096 May 28 19:02 ./drwxr-xr-x   15 root     root         4096 May 28 21:28 ../lrwxrwxrwx    1 root     root           17 May 28 19:02 linux -> linux-release@drwxr-xr-x   19 root     root         4096 May 28 19:02 linux-release/drwxr-xr-x   19 root     root         4096 Apr 06 08:29 linux-oldrelease/

Now, just to be safe, let's remove any stale object filesinappropriately cluttering your source tree, so we canbuild a fresh clean kernel:

# cd /usr/src/linux# make clean

Install an initial kernel configuration file

From here on, we will just rely on /usr/src/linuxto be set up and pointing to the new source tree,making the pathnames a little simpler if we need tomention them.However, almost everything should be done in thedirectory/usr/src/linuxand so there is little need to mention full path names!

There are thousands of choices to be made when configuringa kernel build, and if you just dive in and start answeringthem you probably will not get enough of them right toproduce a kernel that boots.

However, you are running some kernel that bootsand runs on your hardware.I would presume that it is probably of an earlier releaseif you are like most people who would read this page,but its configuration would be a good starting point.

The very best solution would be to ask the running kernelhow it is configured.That way you would get the truth.So, try that:

# zcat /proc/config.gz > .config

If that didn't work, maybe your kernel supports this butonly as a loadable module.So, let's try loading that module and asking again:

# modprobe ikconfig# zcat /proc/config.gz > .config

If that worked, great, move on to the next step.If it did not work, you will need to find a configurationfile that your distribution has probably stashed awaysomewhere on the system.Try this while paying attention to the available filename or names.Pick the latest if you have a choice:

# ls /boot# cp /boot/config-release-distro .config

Red Hat has been known to hide the configuration filesin other places:

# ls /usr/src/linux-oldrelease/configs# ls /usr/src/linux-oldrelease/.config

If all else fails:

# find / -name 'config-2*'

Or, worse yet, try the following,where CONFIG_EXPERIMENTAL is a configurationvariable set in the file regardless of architecture.You will probably find that string in other filesso you will need to think a little about what you find.

# find / -type f -exec grep 'CONFIG_EXPERIMENTAL=[yn]' {} /dev/null \;

You need to somehow install something reasonablyrelevant as /usr/src/linux/.config.

Configure a kernel build

Let's say that you would like your new kernel to describeitself as version3.0.X-whateverinstead of plain old3.0.Xwhen someone runs the command
$ uname -r
or
$ uname -a

The trick is to edit the file Makefileand change its opening to the following:

VERSION = 3PATCHLEVEL = 0SUBLEVEL = XEXTRAVERSION = -whatever

Be careful —you must be very conservative in what you put here!The string needs to be fairly shortand contain nothing but letters, numbers, "." and "-".Any other punctuation marks or white space will causehorrible problems later.

If you are doing this with a 2.6.X.Y kernel, theEXTRAVERSION string will have been some.Y (whereY was really a number, of course).So, for this example you would use the following,leavingX and Y aswhatever they already were:

VERSION = 2PATCHLEVEL = 6SUBLEVEL = XEXTRAVERSION = .Y-whatever 

Now you are ready for the fun part!You are finally ready to run the kernel build configurationtool.I say "kernel build configuration"instead of "kernel configuration"because that's what you are doing.You are specifying how to build a kernelas opposed to configuring some pre-existing kernel.

The more friendy interface is started like this:

# make gconfig &

However, that may require some Gnome or GTK packages thatyou haven't installed, and either you haven't set upYUM or urpmi to make installation easyor you just don't want to add those packages.In that case try the following.If that doesn't work either, then it's time to installthose packages....

# make xconfig &

The terminal emulator where you ran that command willhave lots of output, including some error messages aboutsetting kernel variables that were not defined andperhaps about specified settings for kernel variablesthat do not exist.Don't panic!Remember what you did — you started with theconfiguration of an older kernel to build a newer one.The kernel feature set changes from version to version,and so we expect to see these rather mild warning messages.

I believe that it only makes sense to build the kernelconfiguration into the kernel itself.Do this:
Under General Setup select:
  Kernel .config support
and then select:
  Enable access to .config through /proc/config.gz
If you build it into the monolithic kernel (shown as a checkmark in the configuration tool) it will always be there.If you build it as a loadable module then it will only appearwhen the appropriate module is loaded, you will need tofirst do something like this:
# modprobe ikconfig
and then the kernel data structure will appear as/proc/config.gz.I would suggest simply building this into the monolithickernel so the configuration is always available.

Your configuration should be pretty close to what you want,and in many or even most cases it would be reasonableto just save the settings at that point and exit the tool.

However, you probably should explore the kernel configurationjust to learn about how many things the Linux kernel cansupport.

Just try not to do anything terribly silly likedisabling support for your hard drive controller.Unless you really do want a kernel that will not boot...

Save and exit when you have finished exploring.

Build your new kernel

This is much easier than many people expect.Start by seeing the list of available build targets:

# make help | less

There are two main ways of doing this.The traditional method builds a monolithic kernel and ahuge collection of load modules, and a later step easilyputs them all into their proper locations.

However, wouldn't it be better to include your kernel inyour configuration management?That requires building it as a package, which is alsovery easy to do.So:

Traditional build

Start building the monolithic kernel and loadable modules:

# make all

Package build

Let's build both source and binary RPM packages:

# make rpm-pkg

Be patient...

Now go get some coffee.Or a pot of tea.Or maybe lunch.This will take a while.

Install your new kernel

This is much easier than it used to be.It hasn't been difficult for some time, but some peopleare still scared off by criticisms that haven't beenappropriate for ages now.

If you did a traditional build:

# make modules_install# make install

If you built a package:

First, let's see what got built:

# tree ~/rpmbuild/*RPMS

Let's be cautiously confident — our new kernel isalmost certainly going to work!But just in case it doesn't, we don't want to remove ourexisting and functioning kernel.So, we need to simplyinstall the new kernel,leaving the old one in place, as opposed to doing itas an upgrade and removing the old one.Something like this, modified as needed to reflect yourarchitecture and kernel release:

# rpm -ivh /usr/src/whatever/RPMS/arch/kernel-release.arch.rpm

We still need to build and install an "initrd", an initialRAM disk image, and then modify the boot loader.That sounds awfully complicated, and it used to be.Now it's just one long command.

# new-kernel-pkg --mkinitrd --install --make-default --depmod release

Modify the boot loader

Edit the GRUB configuration file, either/boot/grub/menu.lst or grub.conf.If you built the kernel in the traditional way,move the stanza for your new kernel to the top of the listand change the default to 0 (GRUB starts counting at zero).Notice that if you built it as a package, one of the optionsto our new-kernel-pkg command has already madethis the default!Itis going to work, right?

Do comment out any hiddenmenu line that yourdistribution might have installed initially becausethey thought that you shouldn't see what's going on.

default=0timeout=10splashimage=(hd0,0)/grub/splash.xpm.gz## hiddenmenutitle linux-3.0.xx-whatever        root (hd0,0)kernel /vmlinuz-3.0.X-whatever ro root=LABEL=/ quietinitrd /initrd-3.0.X-whatever.imgtitle Mandriva Linux 2.6.33.6-desktoproot (hd0,0)kernel /vmlinuz-2.6.33.6-desktop ro root=LABEL=/ quietinitrd /initrd-2.6.33.6-desktop.img

If you're still using LILO and you don't want to upgrade,then you will need to edit/etc/lilo.conf andmake the appropriate changes before runninglilo -vto recreate the boot block.But seriously, LILO?Today?

If you're doing this on an Alpha,ignore all this about GRUB and LILO and modify/etc/aboot.confand thengo see my page specifically about buildingkernels on Alphasfor some further details.

# aboot default configurations# NOTICE: You have a /boot partition. This means that# all kernel paths are relative to /boot/0:2/vmlinuz-3.0.X-whatever initrd=/initrd-3.0.X-whatever root=/dev/sda4 quiet1:2/vmlinuz-current initrd=/initrd-current root=/dev/sda4 quiet2:2/vmlinuz-previous initrd=/initrd-previous root=/dev/sda4 quiet

Reboot and Enjoy!

You didn't do anything silly like get rid of your functionalold kernel, right?Or configure your boot loader in such a way that it isn'tavailable?Did you??

How Large Are Those Modules?

Pretty large!This command sequence will show that the collection ofnew modules and the resulting initrd file are much largerthan what you installed from Red Hat or CentOS:

# du -sh /lib/modules/*# ls -lh /boot/init* 

Why is there such a big difference in sizes?And, I suspect, in the kernel load time during the initialstages of booting?

The kernel modules were stripped of their symbols.Seethe manual pagefor thestripcommand for what is going on.I have not yet found an easy way to ask the kernel buildprocess to do this for me.

Keeping Track of Your Work!

You should have made the very reasonable choice of askingfor the kernel's configuration, the.config file,to be built into the kernel and made available as/proc/config.gz.That means that all you have to keep track of isyour kernel release and a copy of your.config file,a file of a little over 100 kbytes, about a quarter of thatif compressed withgzip.

Now Let's Explore Your New Kernel!

Click hereto explore Linux kernel details.

原创粉丝点击