Creating a Custom Linux Kernel in Debian GNU/Linux
The most current version of this document can be found at
http://users.wowway.com/~zlinuxman/Kernel.htm.
Contents
Disclaimer
Maintenance Log
Introduction
Step 1: Update Your sources.list File
Step 2: Update the List of Available Packages
Step 3: Apply Pending Updates
Step 4: Install the Kernel Source Package
Step 5: Unpack the Kernel Sources
Step 6: Install kernel-package
Step 7: Patch the Kernel
Step 8: Configure the Kernel
Step 9: Create the Kernel Image Package
Step 10: Customize the Kernel Installation Environment
Customizing the Lenny (5.0) Environment
Changing Boot Loaders
Customizing the Squeeze (6.0) Environment
Customizing the Wheezy (7.0) Environment
Step 11: Install the Kernel Image Package
Step 12: Shutdown and Reboot
Step 13: Clean Up
Step 13a: Clean Up (Part Two)
Step 14: Maintenance
Alternatives
A Specific Example
Another Specific Example
Conclusion
Disclaimer
This is not an official Debian site.
The author is not a member of the Debian kernel team.
This is not an official Linux kernel site.
This document details the author's experiences
and recommendations in
building a custom Linux kernel under Debian GNU/Linux.
All opinions expressed are those of the author and do not necessarily
represent the opinions or the official positions
of Debian, the Linux kernel organization,
or any other organization or individual.
This information is presented in the hope that it will be useful,
but without any warranty or guarantee of any kind.
This information is presented free of charge, free of support,
free of service, and free of liability.
Take this information
with as many grains of salt as you think it's worth;
and use it, if you
choose to do so, entirely at your own risk.
The author hereby explicitly
places this material in the public domain.
All trademarks, registered
trademarks, service marks, etc. are the property of their respective
owners.
Maintenance Log
-
2013-01-29 Added release
numbers to the release code names in several places (but not everywhere)
to give those not familiar with recent Debian release code names some
idea of the correspondence between release code names and release
numbers.
Minor editorial changes.
-
2012-12-08 Minor
editorial changes.
-
2012-12-02 Minor
editorial changes.
-
2012-11-23 More information
added concerning real-time preemptable kernels in Wheezy.
Corrected some errors.
Minor editorial changes.
-
2012-08-04 Minor
editorial changes.
-
2012-08-01 Added
information about real-time preemptable kernels.
Minor editorial changes.
-
2012-04-12 Minor
editorial changes.
-
2012-03-30 More detail
added for kernel version naming conventions due to changes
made in Wheezy.
Minor editorial changes.
-
2012-03-18 Announced
kernel-package version 12.036+nmu2 and the bug fixes
it contains.
Minor editorial changes.
-
2012-01-11 Added information
about managing multiple releases in /etc/apt/sources.list.
Minor editorial changes.
-
2011-11-07 Minor editorial changes.
-
2011-10-27 Revised
information on Debian bug report 599931.
Minor editorial changes.
-
2011-10-01 Revised
recommended procedure for temporarily disabling the udisks
daemon.
Minor editorial changes.
-
2011-09-30 Corrected some
typos.
Clarified the difference between an environment variable and a
make variable.
Added information about the linux-source package.
Minor editorial changes.
-
2011-09-29 Added information
about "make localmodconfig" and
"make localyesconfig".
Added information about the "getconf" command, the
CONFIG_DEBUG_INFO kernel configuration option,
and the INSTALL_MOD_STRIP make variable.
Added information about analogous options between make-kpkg
and "make deb-pkg".
Added more information about using pristine kernel source
tarballs as an alternative to
official Debian kernel source packages.
Minor editorial changes.
-
2011-08-13 Documented a
patch needed for kernel-package version 12.036+nmu1
when used with Linux Version 3 kernel sources.
Documented environment variable CONCURRENCY_LEVEL.
Provided more information about environment variables in general.
Minor editorial changes.
-
2011-07-23 Removed references to
the "zz-bootloader" and "bootloader" hook scripts.
Published revised zy-symlinks hook scripts which support both
compressed and uncompressed kernels (debug kernels).
Minor editorial changes.
-
2011-07-19 Added more information
about the udisks daemon and ways to get around it.
Reworked the section on cross-building
initial RAM file system image files.
Minor editorial changes.
-
2011-07-13 Added a sample patch
and a sample patch procedure.
Minor editorial changes.
-
2011-06-24 More differences
between Wheezy and Squeeze documented in step 10.
Tightened up the rules for when to use the "clean" and "modules_clean"
targets.
Minor editorial changes.
-
2011-05-25 Revised information
about "make deb-pkg" with respect to kernel headers
packages and C library development packages.
Recommended using lspci to determine Nvidia chipset instead of the nv
X driver (which has been removed from the distribution in Wheezy).
Minor editorial changes.
-
2011-04-04 Revised
information about adding a user to a new group and when that
change takes effect.
Added information about the udisks daemon and how it can
interfere with CD usage by apt and aptitude.
Minor editorial changes.
-
2011-03-04 New level set
for Squeeze stable release.
Introduction
Most of the time, the stock kernel images
obtained from Debian are adequate.
But occasionally one may need to create a custom kernel image in order to
take advantage of some special feature or solve a particular
problem.
Or you may want to create a custom kernel in order to create a
"lean and mean" kernel: one which is as small as possible and contains
only the code necessary to do the function assigned to this
machine.
(This is often done in embedded systems.)
I assume that you already know why you need or want to build a custom
kernel.
The purpose of this document is to show you how.
Most of my examples are from the i386 architecture,
but the techniques are applicable to all architectures.
I had a roommate in college who had spent four years in the Navy.
He told me that in the Navy there are three ways to do everything:
the right way, the wrong way, and the Navy way!
Well, kernel building in Debian is like that too.
Although there are similarities to other distributions,
Debian definitely has its own way of building kernels.
Information that you may find on distribution-independent Linux
sites or sites from non-Debian-based distributions
that talk about building a custom kernel are not likely
to be very useful in Debian.
Debian wants everything, including the kernel itself,
to go through its package management system.
As a result, kernel building in Debian is quite different from
other non-Debian-based distributions.
I have found that the documentation for kernel building in Debian
is spread out over several different sources.
Some of these documents are out of date.
Furthermore, there are a number of small but important steps
that are often left out.
This write-up is an attempt to document the procedure in detail.
In addition, this document shows how a custom kernel
fits in with the overall lifecycle
of upgrading and maintaining a Debian system.
If you're going to be running a custom kernel on an on-going basis,
you need to know how to integrate the custom kernel with Debian
maintenance procedures.
I am assuming that you have never downloaded or configured a
kernel source package on your system before and that you want
to create a custom kernel image package of the same kernel
release as the stock kernel that you are currently running.
I'll be using kernel 2.6.32 from the Squeeze (6.0) release and the i386
architecture in most of my examples, but as I said earlier
the techniques are applicable to all releases and architectures.
In previous versions of this document I recommended doing
everything as root, including steps which could (and probably should)
be performed as a non-root user.
This recommendation was made for simplicity's sake, not
for philosophical reasons.
As far as I can tell, all the bugs related to building a kernel
as the root user which have plagued kernel builders in the past
have been fixed.
I've been building kernels as root for years, and have never had
a problem.
Nevertheless, bowing to pressure from the lords of kerneldom,
I have now decided to make a distinction in this document
between steps which must be performed as root and steps
which can (and probably should) be performed as a non-root user.
If you're going to follow the procedures recommended in this
document, your non-root user account must be enrolled in the "src"
group.
For example,
# adduser steve src
Make sure you do that before you start, and verify (by means of
the "groups" command) that your non-root user account actually
has the "src" group listed in the output of the "groups" command
before you attempt to perform any of these steps using that
account.
It used to be that
once root enrolled a user in a new group, all instances
of that user had to logout before a new login of that user
would actually
have the privileges of that group.
This included the graphical desktop environment, if that user
logged into the graphical desktop.
In rare cases, such as hung processes, etc.,
one had to reboot after enrolling the non-root user in
a new group before the output of the groups command issued by
that user would show the new group as one of its groups.
However, with newer systems, this no longer appears to be
the case.
It now appears that any session which existed prior to the new
group being added will not have
the privileges of the new group,
but any new login session created after the privilege
has been granted appears to have the privileges of the
new group.
I'm not sure exactly when that change was made; so you'll
have to follow one procedure or the other, depending on the
age of your system.
The bottom line: do whatever it takes to get the output of the
"groups" command issued by the non-root user to show the new group
in its list of groups.
Also, make sure that the directory /usr/src is owned by user
root and by group src, and that the group has read and write
privileges on the directory.
Execute privileges on the directory should be granted to all users
(user, group, and other).
Also, make sure that the "set-group-ID" file mode
bit is set for the directory.
This can be checked by issuing "ls -ld /usr/src".
The "s" flag will show in the output.
For example:
$ ls -ld /usr/src
drwxrwsr-x 3 root src 4096 Aug 24 13:52 /usr/src
The lower-case letter "s" in the seventh position of the file attributes
indicates that the "set-group-ID" file mode
bit is set for the directory and that the group also
has the execute privilege on the directory.
(An upper-case "S" in this position would indicate that the
"set-group-ID" file mode bit is set for the
directory, but that the execute privilege for the group is missing.)
This used to be the default, but on a recent install of Squeeze (6.0)
I've seen this change.
If it is not set, set it using the following command:
# chmod g+s /usr/src
(Any changes to the privileges on the /usr/src directory must
be done by root.)
Once you select a non-root user account for kernel-building
purposes, you must use that same userid for all non-root steps.
Step 1: Update Your sources.list File
Do this step as root.
The retrieval of packages in Debian is
controlled by a file called /etc/apt/sources.list.
If you installed Debian
from a CD-ROM, chances are that only the first CD
is listed in the sources.list file.
If you have a complete set of CDs, but only the first one
is listed, you need to update this file.
However, adding CDs to sources.list
cannot be accomplished via a text editor.
Other files in other places must
be updated too in order for a CD entry in sources.list to work.
To add new CDs to the sources.list file, use the following command:
apt-cdrom add
You will need to issue this command once for every CD in your set
that is not already listed in sources.list.
If you have several "disk 1" CDs in your
set, don't scan the alternate ones.
For example, Lenny (5.0) ships with 3 "disk 1"
CDs: one for a GNOME-based desktop environment,
one for a KDE-based desktop environment,
and one for an XFCE-based desktop environment.
If you installed from the GNOME version of disk 1,
it is the one listed in your sources.list file.
Don't scan the other two "disk 1" CDs
with apt-cdrom.
Each time you run apt-cdrom, it will
prompt you to insert a CD and press Enter.
After you do this, it will mount the CD, scan the CD
looking for package information,
then umount the CD.
It will then update /etc/apt/sources.list.
When the command completes, remove the CD from the CD
drive.
apt-cdrom is also used
if you have installed from DVDs or Blu-ray disks.
(Of course, there will be far fewer DVDs or
Blu-ray disks in a complete set
than there are for a complete set of CDs, since a DVD or
Blu-ray disk holds
much more data per disk.)
When running a graphical desktop environment, such as GNOME,
the udisks daemon may give you trouble.
The udisks daemon tries to auto-mount any data CD inserted
in the CD drive while it is running and interferes with
CD mounting and unmounting by apt-cdrom.
(Later, it will also interfere with CD mounting and unmounting
by apt-get or aptitude.)
If you are having this problem, you need to disable auto-mounting
in some way.
One way to do this is to shutdown and reboot, do not login to the
graphical desktop at all, and do your system administration
from a text console.
(udisks-daemon is not normally
running in this environment.)
Another possibility is to temporarily disable polling while
you're doing your work.
In one terminal session, issue
udisks --inhibit-polling /dev/sr0
(I am assuming here that /dev/sr0 is the block special file name
of your CD drive, or a symbolic link to the block special file
name of your CD drive.
If not, substitute the appropriate device name.)
Then, switch to another terminal session and do your work.
When finished, including removal of the last CD from the CD drive,
switch back to the terminal session running udisks
and type ^C (Ctrl+C) to cancel the udisks command.
If you don't have any mountable media sources listed in
/etc/apt/sources.list, and you don't plan to add any
with apt-cdrom,
you don't need to worry about this problem.
If you have access to the internet, you should also include an internet
server in sources.list.
This is true even if you installed Debian from CDs.
You should also make sure that the updates and security sites
are present as well.
(The updates site should only be used if you are running the
stable release.
This takes the place of the old "volatile" site.)
If you didn't have access to the internet during
installation, the installer may have included such entries,
but commented them out.
If you have
access to the internet now, but you didn't during installation, uncomment
these entries.
This will allow you to install the most recent version of a package,
if there is a newer version than the one on the CD.
Packages in the stable release are not
normally updated during the life of the
release except to fix bugs involving
security vulnerabilities or to replace data that is highly volatile in
nature.
An example is the virus signature data for an
anti-virus software package.
Occasionally some "safe" fixes are also introduced.
These are important fixes which have been well tested
and are extremely unlikely to cause any
forward compatibility issues.
(Well, that's the theory anyway.)
These fixes are introduced from time to time as
"stable point releases."
You might also want to add entries for the "non-free" and
"contrib" sections of the archive, in addition to the "main" section.
Official CDs contain only the "main" section.
With the exception of the security site, which must use
HTTP, you have a choice, for most of the Debian mirrors,
whether to use HTTP or FTP as the file transfer protocol.
Be careful though some of the
mirrors use a different path name for HTTP and FTP.
For a full list of Debian mirrors, see
http://www.debian.org/mirror/list.
Choose the mirror nearest to you or which gives you the
shortest latency or the highest data transfer rate.
Make sure you choose a mirror which supports the file
transfer method you want to use and specify the correct path
for that type of file transfer.
Also, make sure that you choose a mirror that mirrors your
machine architecture.
(Not all mirrors mirror all architectures!)
For more information, see the man page for sources.list(5)
and the above-mentioned web page which lists all the mirrors.
For all sources except CDs, DVDs, and Blu-ray disks,
the sources.list file can and should be edited
by a text editor.
Make sure that the internet sources are listed after the
CD/DVD/Blu-ray sources,
and make sure that the security source is listed last.
Here is a sample sources.list file for a system running
the current stable release, Squeeze (6.0):
.
. (possible CD/DVD/Blu-ray entries added by apt-cdrom)
.
deb ftp://carroll.aset.psu.edu/pub/linux/distributions/debian squeeze main non-free contrib
deb-src ftp://carroll.aset.psu.edu/pub/linux/distributions/debian squeeze main non-free contrib
deb ftp://carroll.aset.psu.edu/pub/linux/distributions/debian squeeze-updates main non-free contrib
deb-src ftp://carroll.aset.psu.edu/pub/linux/distributions/debian squeeze-updates main non-free contrib
deb http://security.debian.org squeeze/updates main non-free contrib
deb-src http://security.debian.org squeeze/updates main non-free contrib
The "deb" entries specify a server for binary packages and
the "deb-src"
entries specify a server for source packages.
Penn State's Debian mirror site has been selected
for both package types, using the FTP protocol.
Only packages from the Squeeze distribution will be
selected, but the "non-free" and "contrib"
sections have been added to the standard "main" section.
squeeze-updates has been added also.
This takes the place of what used to be called the "volatile"
site.
The standard Debian security server has been
added at the end, using the HTTP protocol.
Note: always use a release code name, such
as squeeze, wheezy, etc., rather than a status, such as stable, testing,
etc., in /etc/apt/sources.list.
The reason for this is that nasty things will happen when a new
release comes out if you code a status.
For example, suppose you used "stable" in your /etc/apt/sources.list file
back when Lenny (5.0) was the stable release.
The result will be an attempted release upgrade from Lenny (5.0)
to Squeeze (6.0)
at the next "aptitude update" /
"aptitude full-upgrade" sequence following
Squeeze (6.0) becoming the stable release.
That is not the proper way to do a release upgrade.
See the Debian "release notes" for the release to which you wish
to migrate
for the proper way to do a release upgrade.
Sometimes you may need to define multiple releases in your sources.list
file.
For example, you are running the testing release; but you need
at least one package from unstable (or maybe even experimental).
In particular, if you need or want to fetch kernel source code that
is newer than the newest source code available in your current release,
you will need to define multiple releases in sources.list.
Here is a sample sources.list file for a system which is running
the current testing release (Wheezy) but that also needs one
or more packages from the unstable release (Sid) or experimental:
.
. (possible CD/DVD/Blu-ray entries added by apt-cdrom)
.
deb ftp://carroll.aset.psu.edu/pub/linux/distributions/debian wheezy main non-free contrib
deb-src ftp://carroll.aset.psu.edu/pub/linux/distributions/debian wheezy main non-free contrib
deb ftp://carroll.aset.psu.edu/pub/linux/distributions/debian sid main non-free contrib
deb-src ftp://carroll.aset.psu.edu/pub/linux/distributions/debian sid main non-free contrib
deb ftp://carroll.aset.psu.edu/pub/linux/distributions/debian experimental main non-free contrib
deb-src ftp://carroll.aset.psu.edu/pub/linux/distributions/debian experimental main non-free contrib
deb http://security.debian.org wheezy/updates main non-free contrib
deb-src http://security.debian.org wheezy/updates main non-free contrib
Once again note that status names (testing, unstable, etc.) are not used:
release code names (wheezy, sid, etc.) are used instead.
Also note that the updates site (wheezy-updates) is not used,
since Wheezy (7.0) is not yet the stable release.
The security site for Wheezy is present, since security updates are provided
for the testing release, but not for Sid or experimental, since no security
updates are provided for these releases.
Also note that the "non-free" and
"contrib" sections of the archive
have been added to the standard "main" section for all defined
repositories.
When mixing releases in the same system, it is important to define
the default release.
You do this in /etc/apt/apt.conf.
Put a line such as the following in the above-named file:
APT::Default-Release "wheezy";
This will cause apt-get or aptitude to give priority
to the wheezy release.
A package which exists in wheezy and also in another defined release, such
as sid or experimental, will be fetched from wheezy, even if a newer
version of the package exists in another release, unless (1) an alternate
release is explicitly requested as the target release (-t option)
in the command or (2) a newer
version of the package than is available in the default release is needed
to satisfy a package dependency relationship or (3) the currently
installed version of a package is already newer than the updated version
of the package in the default release.
Note: synaptic does not understand or honor
this definition of a default release.
In synaptic you set the default release with
Settings -> Preferences, click on the Distribution tab,
select the radio button next to "Prefer versions from:", then select
your default release from the drop-down menu.
I'd avoid using synaptic if I were you.
My advice, for what it's worth, is to
stick with apt-get or aptitude to do all your installs
and upgrades.
Step 2: Update the List of Available Packages
Do this step as root.
Once the sources.list file has been
updated, you need to update the package
management system's list of available packages.
I used to recommend "dselect update" to do this,
for various reasons; but I don't anymore.
dselect is obsolete and it's time to learn how to get
along without it.
One of the reasons I no longer recommend "dselect update"
is that it seems
to cause "apt-cache show <package-name>"
to "see double" for some packages.
In other words, the information about the package is listed twice.
I now recommend "aptitude update" for this purpose.
"apt-get update" works too.
Step 3: Apply Pending Updates
Do this step as root.
After updating the list of available packages, as outlined above,
you should apply all the pending updates that have accumulated since
you last applied updates (or since installation, if
you have never applied updates).
To do this, enter the following command:
aptitude full-upgrade
Note: whenever you apply updates, as per above,
and you have more than one kernel image package installed,
watch the console output carefully to see if an initial RAM file
system image file gets rebuilt; and if it does, check to see if the
initial RAM file system image file that got rebuilt is the one that
corresponds to your running kernel.
This is especially important if you are using MODULES=dep in
/etc/initramfs-tools/initramfs.conf
or /etc/initramfs-tools/conf.d/driver-policy.
Normally, the initial RAM file system image file that gets rebuilt under
these circumstances is the one which sorts highest in the ASCII
collating sequence for all the currently-installed kernels that
have an initial RAM file system image file.
In any case, the one it picks to rebuild is not necessarily the
one which corresponds to your running kernel; and that can cause
problems.
As an example, suppose that you have two kernels installed:
2.6.32-3-686 and 2.6.32-5-686.
You have a traditional IDE hard disk.
You have "MODULES=dep" specified in
/etc/initramfs-tools/conf.d/driver-policy.
You are currently running the 2.6.32-3-686 kernel.
You run "aptitude full-upgrade", which causes
"update-initramfs -u" (without the "-k" option)
to be run.
The initial RAM file system image file for the 2.6.32-5 kernel
will likely be re-built while you are running the 2.6.32-3 kernel.
This is known as "cross-building" an initial RAM file system image file,
and it should be avoided if you are using MODULES=dep.
Since these two kernels use different drivers for your IDE hard disk,
chances are that the 2.6.32-5 kernel will no longer boot!
If you apply maintenance and it causes the initial RAM file
system image file for your running kernel
to be re-built, shutdown and boot the other installed
kernel images in turn and rebuild their initial RAM file
system image files with
update-initramfs -uk $(uname -r)
Continue the process until all the initial RAM file system image files
have been rebuilt while running the corresponding kernel.
If the maintenance causes a cross-build
of an initial RAM file system image file,
and you are using MODULES=dep; first rebuild the correct
initial RAM file system image file
(i.e. the initial RAM file system image file for your running kernel)
by issuing
update-initramfs -uk $(uname -r)
Then change MODULES=dep to MODULES=most, cross-build the same
initial RAM file system image file again that was
cross-built the first time, then shutdown and boot that kernel.
After the reboot, change MODULES=most back to MODULES=dep and
rebuild the initial RAM file system image file
for that kernel again.
If there are any other installed kernels besides these two,
shutdown and boot
each of the remaining kernels in turn, rebuilding their initial
RAM file system image files while the corresponding kernel is running.
In any case, whenever an initial RAM file system image file is rebuilt as
the result of applying updates, and you have more than one kernel image
package installed, you must take care to rebuild all of the remaining
initial RAM file system image files manually.
The exact procedure to use will depend on the circumstances.
If you are installing a new kernel and you are using MODULES=dep,
it is safest to use MODULES=most
initially, then re-build with MODULES=dep after you are running
that kernel.
The Debian maintenance system is supposed to be smart enough
to know when an initial RAM file system image needs to be rebuilt
and to do so automatically.
However, there have been times, when running
"aptitude full-upgrade" or "aptitude safe-upgrade",
that I have seen packages serviced that I was fairly sure were in the
initial RAM file system; but the initial RAM file system image did not
get automatically rebuilt.
This is especially true on non-i386 architectures.
Lately I have gotten into the habit of manually rebuilding
the initial RAM file system image file
after applying maintenance just in case.
(Unless, of course, it was rebuilt automatically during
the application of maintenance.)
I think this is a good idea.
It never hurts to rebuild the initial RAM file system image file,
and it might help.
Note: I personally like to use the
--purge-unused option with aptitude anytime the
possibility exists of a package getting removed.
This includes using the full-upgrade argument.
This keeps the database of installed packages cleaner and saves
disk space.
Read the man page for aptitude(8) and decide if this option
is for you.
If you decide it is for you, you can make it the default option
by setting
Aptitude::Purge-Unused "true";
in /etc/apt/apt.conf.
I recommend that you subscribe to three mailing lists
if you are running the current stable release.
They will tell you when updates are made.
The first is the debian-security-announce
mailing list.
This informs you of security-related updates.
The second is the debian-stable-announce mailing list.
This informs you of updates to volatile packages, such
as a new virus signature file for an anti-virus software package
or new time zone data due to changes to time zones or Daylight
Saving Time observance practices.
The third is the debian-announce mailing list, which will
inform you of new stable point releases.
When you get one of these announcements,
wait a day or two for the updates to propagate to all mirrors,
including the one you use, then
update the list of packages again
with "aptitude update".
Then use
aptitude full-upgrade
to install the updates.
If you are running the testing release or the unstable release,
you should perform this procedure regularly,
since updates are not generally announced.
When you are finished installing package updates, use
aptitude clean
to delete the package files (.deb files) from the package cache
(/var/cache/apt/archives).
Once the packages have been installed, you don't
need the package files themselves anymore.
This will save disk space.
Once the updates have been installed, it is a good idea
to shutdown and reboot.
This is especially true if the kernel has been serviced.
Note:
only package files downloaded from the internet end up in the
package cache.
Package files read from CD-ROM, DVD,
or Blu-ray disks
are not staged to the
package cache but are processed directly from the mountable media.
Note:
if you are running the testing or unstable releases,
"aptitude full-upgrade" can sometimes cause problems.
Different components that have dependencies on each other are often
worked on by different developers and are not necessarily updated
at the same time.
There are various techniques available to work around these
problems, such as postponing updates,
using "aptitude safe-upgrade",
manually installing or removing certain packages, etc.
A full discussion of these maintenance techniques is beyond the
scope of this document.
Step 4: Install the Kernel Source Package
Do this step as root.
Once you have updated the list of available packages with
"aptitude update" or "apt-get update",
you will be able to install any package which is
available in any release defined in the /etc/apt/sources.list file.
Normally, you will want to install the kernel source code for the
stock kernel that you are currently running.
If you don't know what kernel you're currently running, you can find out by
issuing the command:
uname -r
Use aptitude to list the available source packages that you can install.
For example,
aptitude --disable-columns search linux-source
Packages with a status of "p" or "r" are not installed.
To install the package, use aptitude.
For example,
aptitude install linux-source-2.6.32
This will install the kernel source code.
(Although it is kernel source, it is classified as a "binary"
package in the Debian packaging system; therefore, you must
be root to install it.)
You can obtain kernel source code packages from other places,
such as pristine kernel source tarballs from kernel.org or
one of its mirrors;
but I recommend using official Debian kernel source packages
whenever possible
because they contain all of the Debian-specific modifications.
Another advantage to using a Debian package is that you will
automatically get the package dependencies, such as bzip2.
However, under certain circumstances, you may need to download
the very latest pristine kernel source code, such as when testing
a fix written by the kernel people for a problem you reported.
When manually downloading a pristine kernel source tarball,
do so as the non-root user and download to directory /usr/src.
If you have out-of-kernel-source-tree kernel module source
packages to install, do that at this time also.
(If you don't know what an out-of-kernel-source-tree kernel module
source package is, you probably don't need one;
so don't worry about it at this point.)
Once these commands have completed, enter
aptitude clean
to delete the package files (.deb files) from the package cache.
A kernel source package file is huge;
so this is important to save disk space.
(Obviously, you don't need to issue "aptitude clean"
if you only downloaded a pristine kernel source tarball
from kernel.org or one of its mirrors.
You also don't need to to issue "aptitude clean"
if all the installed packages came from
CD-ROM, DVD, or Blu-ray disks.)
Step 5: Unpack the Kernel Sources
Do this step as a non-root user.
Use the same userid for all non-root steps.
The non-root user must be a member of group "src".
So what did
"aptitude install linux-source-2.6.32"
just do?
If everything worked correctly, you should now have a file in the
/usr/src directory that starts out as
"linux-source" and ends in ".tar.bz2".
It is at
this point that some people make a mistake.
They create a directory in
/usr/src called linux-source-2.6.32,
move the kernel source tar file to that
directory, then unpack the tar file from there.
Don't do that.
If you do,
you will end up with two levels of directory called
linux-source-2.6.32.
Instead, change directories to /usr/src and unpack the
kernel sources right where they are.
For example:
cd /usr/src
tar -xjf linux-source-2.6.32.tar.bz2
The "x" switch of tar indicates that the "extract"
function will be used.
The "j" switch tells tar to filter the archive through bunzip2 to
decompress the archive first,
before tar itself processes the file.
And finally, the "f" switch specifies that input is to be read
from a file specified on the command line, instead of standard input.
The above "tar" command will create a directory
under the current directory
(/usr/src) called linux-source-2.6.32.
All the kernel source code and
associated files will be unpacked
to this directory and its subdirectories.
Strictly speaking,
one is not supposed to erase a file belonging to an installed
package.
But once the archive has been unpacked, there's really no use in
keeping it around.
I recommend getting rid of it.
This saves some more disk space.
I suppose the "right" way
to do it would be to purge the package;
but then you won't
get updates for it, which you want.
So my approach is to simply delete the tar file once it
has been unpacked.
Another advantage to deleting the tar file
once it has been unpacked is that it is easier
to tell when an "aptitude full-upgrade" command has
resulted in an updated source package being installed.
If you make a habit of deleting the tar file after unpacking it,
then if you discover a tar file in the /usr/src directory,
you will know that an updated source package has been installed.
(And therefore, you need to rebuild your custom kernel.)
rm linux-source-2.6.32.tar.bz2
Note: when issuing the above "rm" command as a non-root
user, you may be prompted as to whether or not you want to erase a
write-protected file.
That's due to the fact that the file is owned by user root
and group root, and
your id is not root and you're not enrolled in group root either.
Go ahead and respond with a "y".
The rm command will still succeed because group src has write privileges
to the directory /usr/src, and your id is a member of group src.
Recent official Debian Linux kernel source packages for Wheezy
now also install another file in /usr/src besides the source tarball.
For example, package linux-source-3.2 now installs
files linux-source-3.2.tar.bz2 and
linux-patch-3.2-rt.patch.bz2.
The first file is the standard source tarball; the second is a compressed patch
file which you can apply to the kernel source if you want your custom
kernel to be capable of real-time preemption.
I suspect that this patch file will eventually be incorporated
into the mainstream kernel source code, but for now it is
a separate patch file.
If you want to incorporate the patch file into your kernel source,
then issue the following sequence of commands after unpacking
your kernel source code:
cd /usr/src
bunzip2 linux-patch-3.2-rt.patch.bz2
cd linux-source-3.2
patch -p1 <../linux-patch-3.2-rt.patch
cd ..
rm linux-patch-3.2-rt.patch
The bunzip2 command will create the file linux-patch-3.2-rt.patch
and will also erase the source file,
linux-patch-3.2-rt.patch.bz2.
(If you do not wish to apply the patch, simply erase the compressed
patch file instead).
If you have installed out-of-kernel-source-tree kernel module source
packages, their tar files will also be present in /usr/src.
Unpack them also in a similar manner and then delete the tar files
once they have been successfully unpacked.
These tar files will be extracted to a directory under /usr/src/modules.
Step 6: Install kernel-package
Do this step as root.
If you have not already done so, install the
"kernel-package" package.
You can check to see if it is already installed
by using
dpkg-query -l kernel-package|grep ii
If it is not already installed, install it.
aptitude install kernel-package
Read the README file for kernel-package.
zless /usr/share/doc/kernel-package/README.gz
Determine what additional packages you may need,
assuming that you are going
to use "make menuconfig".
Since there are a number of
different kernel configuration methods
(config, menuconfig, xconfig, etc.),
and since kernel-package doesn't know which
one you plan to use, it does not
mark anything as a prerequisite unless it is a prerequisite for all
configuration methods.
Also, depending on how the kernel is configured, additional packages
may be needed to compile the kernel
and build a kernel image package.
kernel-package does not make these packages a dependency
either, since they aren't always required.
Finally, some packages are required only for some architectures, and
these are not dependencies of kernel-package either.
At the time of this writing, the following packages
will be required for the menuconfig method under Debian Squeeze:
gcc (This is actually a dependency package which brings in the real one)
libc6-dev
libncurses5-dev
binutils
make
module-init-tools (or kmod in Wheezy and newer releases)
mawk | gawk (one or the other, you don't need both)
gzip
coreutils
grep
zlib1g-dev (if CONFIG_LGUEST is set)
fakeroot (if building the kernel as a non-root user)
(Note: bin86 used to be required to compile the kernel
for the i386 architecture, but as of kernel releases 2.4.x and later,
bin86 is no longer required.)
Many of these packages will already be installed.
To check to see if these packages are installed,
use dpkg-query.
For example:
dpkg-query -l gcc|grep ii
Install those packages which you need
with "aptitude install".
For example:
aptitude install libncurses5-dev zlib1g-dev
aptitude clean
There may also be some packages needed to install the
kernel image package once it has been built.
For example, you may need
initramfs-tools to build the
initial RAM file system image file
during kernel image package installation.
(But it should be installed already.)
At this point I recommend
that you edit the kernel-package config file
(/etc/kernel-pkg.conf) and
change the "maintainer" and "email" tags to
your own name and e-mail address.
If you are using kernel-package version 12.036+nmu1
with a Linux version 3 kernel source package, there is a patch to
kernel-package itself that you will need to apply,
especially if CONFIG_LGUEST is set in the kernel config file
or you need to build doc or headers packages.
The patch is available here.
To apply the patch, issue the following sequence of commands:
cd /usr/share/kernel-package
... (download the patch file to the current directory)
patch -p1 <linuxv3.diff
This is an unofficial patch: it is not provided by or endorsed by the
upstream author or the Debian package maintainer.
Also please note that
kernel-package version 12.036+nmu1 and earlier releases
are not compatible with "make" version
3.82; so don't install "make" version 3.82 or later.
These problems are fixed in version 12.036+nmu2.
However, if your kernel source code is version 3.3.x or later,
even kernel-package version 12.036+nmu2 will need
a patch, particularly if CONFIG_LGUEST is set.
The patch is available in the problem log for
Debian Bug Report 663474.
Version 12.036+nmu3 fixes this problem: no patch is required.
Step 7: Patch the Kernel
Do this step as a non-root user.
Use the same userid for all non-root steps.
The non-root user must be a member of group "src".
At this point, apply any patches to the kernel
source code that are needed or desired for your custom kernel.
If you have any patches to apply to out-of-kernel-source-tree
kernel module source packages, apply them at this time as well.
As an example, here is a patch that I am currently running on my custom
kernel:
edid_strict.diff.
This patch allows monitors with invalid EDID check sums or EDID version
numbers, but which otherwise have usable EDID data in them,
to be used with Linux, despite the failure to strictly comply
with the EDID standard.
(It only works with KMS-based drivers.)
In particular, it allows my Future Power 17DB77 CRT monitor to
be used at 1024x768 resolution with an 85 Hz vertical refresh rate
(non-interlaced).
Without this patch, a 60Hz vertical refresh rate
(non-interlaced) was the best I could get out of it.
Even then, I got errors written to /var/log/syslog
about every 10 seconds,
which will fill up the hard drive eventually, if the system stays up
long enough.
With the patch, I get error messages written to /var/log/syslog
during boot; but ongoing error messages every ten seconds disappears.
Here's how to use the patch.
Download the patch to a file in the /usr/src directory.
Give it a meaningful name.
I called it edid_strict.diff on my system.
Now make a symbolic link to the patch in the home directory of your Linux
source code.
For example,
cd /usr/src
.
. (download patch to edid_strict.diff)
.
cd linux-source-2.6.32
ln -s ../edid_strict.diff edid_strict.diff
Do not move (mv) the patch to the Linux source code
directory.
Make a symbolic link to it.
The reason for this will become apparent when we get to the
maintenance section.
Now apply the patch:
patch -p1 <edid_strict.diff
Now create a file in /etc/modprobe.d called local.conf.
(You'll have to create this file as root.)
Put the following line in it:
options drm edid_strict=0
Save the file and exit the editor.
I hope that someday this patch, or something similar to it,
will be incorporated into the official kernel;
but in the mean time, you can add this support yourself by patching
the kernel source code and building a custom kernel.
Step 8: Configure the Kernel
Do this step as a non-root user.
Use the same userid for all non-root steps.
The non-root user must be a member of group "src".
First, change directories to the home directory for
the source code.
cd /usr/src/linux-source-2.6.32
Now, initialize the .config file based on the configuration file
used by the stock Debian kernel.
cp /boot/config-2.6.32-5-686 .config
This means that if you make no changes,
your custom kernel will be configured
exactly like the stock Debian kernel.
Obviously, adjust the name of the config file to copy based on
your architecture and kernel release.
The file you need will start with "config" and will
have your kernel version name in it.
Note: this assumes that you have
installed the kernel source code for one of the stock kernels
that is currently installed.
I don't recommend that you migrate to a new kernel
release this way.
Don't use a config file from one kernel release as the
basis for customization of a different kernel release
(unless the kernel source is newer than the config file
and you follow-up with "make oldconfig").
If you can't get
a copy of a stock kernel config file for the same release as your source
code, and you can't, or don't want to, run "make oldconfig",
then don't initialize the .config file at all.
Also, if you're using a recent Wheezy kernel source code package
and you have applied the patches for real-time preemption,
make sure that the config file you copy is from a stock kernel
that has "-rt" in its package name.
If it's not, then you will need to run "make oldconfig"
afterwards to add the options for preemtable kernels.
Similarly, if you're using a recent Wheezy kernel source code package
and you have not applied the patches for real-time preemption,
make sure that the config file you copy is from a stock kernel
that does not have "-rt" in its package name.
If it does, I'm not sure if "make oldconfig" can fix the
problem in this case.
"make oldconfig" was designed to upgrade an older config
file to a newer kernel, not downgrade a newer config file to an older kernel.
Now it's time to configure the kernel:
make menuconfig
After some preliminaries, an ncurses-based full-screen application
will be launched that allows you to configure the kernel.
I assume that you know what to do here.
(Obviously this is going to require that you are using a full-screen
terminal.
Don't try this on a pure line-mode device, such as a teletype machine
or something analogous to it.
On systems which do not have a full-screen console, such as s390/s390x,
login via a remote ssh client to perform this step.)
Note: In the process of configuring your kernel,
make sure that you leave
CONFIG_BLK_DEV_INITRD set to Y, which is the default.
This is listed under
"General Setup" as "Initial RAM file system and RAM disk
(initramfs/initrd) support".
You're probably going to need that.
I'll have more to say about
that later.
Note: Newer kernel config files contain
some settings that you should
not use.
These include CONFIG_LOCALVERSION (Local version - append to
kernel release) and CONFIG_LOCALVERSION_AUTO (Automatically append
version information to the version string).
These are found under "General Setup".
make-kpkg has its own way
of specifying this information.
I'll have more to say about that later.
Note: even if you do not plan to change
the kernel configuration file copied
from the /boot directory at all,
you must still run "make menuconfig".
make-kpkg relies on certain files
that are created when you run
"make menuconfig".
If you don't wish to change anything,
immediately select "Exit" when the initial screen
is displayed.
It used to be a real pain to create a
"lean and mean" custom kernel: one which only contains
the function necessary to execute on your specific machine.
It can easily take all day to customize the kernel configuration
to get everything you need but nothing that you don't need,
and it is easy to leave something out that you need but don't
realize that you need.
However, starting with kernel version 2.6.32, a new kernel
configuration option is available called
"make localmodconfig".
Initialize the .config file, either by copying it from the stock
kernel config file in /boot or by running
"make menuconfig" with no previous .config file,
then run the preceding command.
It runs "lsmod" to find all the modules loaded on the currently
running system.
It will then read all the Makefiles to map which CONFIG enables
which module.
It will then read the Kconfig files to find the dependencies and selects
that may be needed to support a CONFIG.
Finally, it reads the .config file and removes any module ("=m")
that is not needed to enable the currently loaded modules.
With this tool, you can strip the .config file of all drivers
which are not useful in your machine, and it will take much
less time to build the kernel.
80% compile time reduction seems to be typical.
Of course, before you run this, you should plug in and turn on
all peripheral equipment that you plan to use with this machine
but which is not always connected.
For example, if you have an external USB CD-ROM drive that is not
always attached, be sure it is connected and active at the time
you run "make localmodconfig".
Otherwise, you may not have support
in your kernel for this device.
You can then run "make menuconfig" afterwards to
fine tune the configuration file created by
"make localmodconfig".
There is also a "make localyesconfig" command which
will try to build the needed support directly into the kernel,
if it can,
instead of having the support in a module.
Of course there is a down side to building a "lean and mean" kernel:
if you subsequently reconfigure your system, such as changing video
cards, network adapters, sound cards, etc., there will likely be no
support in your previously-built kernel for the new hardware.
This is a trade-off you will have to weigh and decide what's most
important to you.
Unless you specifically intend to debug the kernel, I recommend
that you set CONFIG_DEBUG_INFO to N (i.e. leave it unset).
(This option is under "Kernel Hacking" and is listed as
"Compile the kernel with debug info".)
Setting this option makes the kernel and modules
much larger and provides
no benefit under ordinary operating conditions.
Setting it to N (i.e. leaving it unset) greatly reduces the size
of the kernel and its modules.
If you build your kernel with make-kpkg,
make-kpkg somewhat
mitigates the damage of having CONFIG_DEBUG_INFO
set by setting make variable INSTALL_MOD_STRIP to 1 before
invoking the modules_install step.
If you really need the debugging symbols for the modules,
add the kernel_debug target to the end of the make-kpkg
command.
This will produce a separate package which contains the debugging
symbols.
If you are using "make deb-pkg", you can manually
pass the INSTALL_MOD_STRIP=1 make variable to
"make deb-pkg" if you want; but "make deb-pkg"
has no ability to create a separate package with the debugging
symbols in it.
Step 9: Create the Kernel Image Package
Do this step as a non-root user.
Use the same userid for all non-root steps.
The non-root user must be a member of group "src".
This step will compile the kernel source
code and create a Debian binary package file for the custom kernel.
But before I get to
the specific commands, I need to discuss naming conventions.
This is critically important.
I need to talk about the difference between the kernel
version name and the kernel revision name.
Both the kernel version name and the kernel
revision name become part of the package file name
(.deb file) that gets created.
However, when the package file gets installed, the kernel revision
name does not become part of the package name.
It also does not become part of the kernel image file name or the
initial RAM file system image file name that gets created in
the /boot directory.
Similarly, the directory in which the kernel modules
get installed (/lib/modules/...) does
not contain the kernel revision name either.
Since you want to retain your existing kernel image file,
initial RAM file system image file,
and kernel modules unaltered as a backout,
you must make the kernel version name
different from the stock kernel version name in some way.
This is accomplished by means of the
"--append-to-version" flag
of make-kpkg.
I usually include the word "custom" in the name to distinguish it
from the stock kernel of the same version.
In this example, the stock kernel has an
"--append-to-version" value
of "-5-686".
(In other words, "uname -r" reports
"2.6.32-5-686".
The version proper is "2.6.32" and the
"--append-to-version" value
is "-5-686".)
My first cut at a custom kernel would probably have
an "--append-to-version"
value of "-5custom01-686".
For subsequent custom versions of the same kernel
I would probably use "-5custom02-686",
"-5custom03-686", etc.
On the other hand, I would keep the kernel revision exactly the same
as the stock kernel.
That way, I know exactly which stock kernel revision it
corresponds to.
For example, at the time of this writing,
the current "--revision" value
is "2.6.32-46", which corresponds to Debian
stable point release 6.0.6.
I obtain this value from the "version" reported by
"aptitude show linux-source-2.6.32" or
"aptitude show linux-image-2.6.32-5-686".
If the kernel source package and the stock
kernel image package are in sync, their "versions"
will match.
In case of a discrepancy, use the version from the source
package, since that is what you are actually compiling.
It's confusing that the package "version" matches the kernel "revision",
but that is the gist of it.
Of course, if you're using a pristine kernel source instead of
a Debian source package, there won't be a Debian package version
to use.
You'll have to make something up in this case.
However, make sure that whatever you choose is compliant with
Debian policy guidelines for kernel image package version names.
Otherwise, either make-kpkg will reject it,
or, if it gets past make-kpkg,
dpkg won't let you install it.
The most important rule to remember is that it must start with
a numeric digit.
If you use a pattern similar
to that used by a Debian stock kernel, you should be fine.
One other complication has recently arisen starting with Wheezy.
The kernel's "internal version" is no longer consistent with the
version implied by the package name for stock kernel image packages.
For example, at the time of this writing, the stock kernel image package
name in Wheezy for modern machines of the i386 architecture is
"linux-image-3.2.0-4-686-pae".
(This is the version without
real-time preemption support.)
This package name implies that the kernel version proper is
"3.2.0" and the "--append-to-version" value is
"-4-686-pae".
However, the internal version proper,
at the time of this writing, is actually "3.2.35".
This is reflected in the package version, which is, at the time of
this writing, "3.2.35-2".
(This corresponds to the "--revision" option
of make-kpkg.)
The corresponding kernel source package name is
"linux-source-3.2".
It also has a package version of "3.2.35-2"
at the time of this writing.
When you build a kernel image package with make-kpkg,
it always uses the internal version name, which in this example
is 3.2.35, when constructing a package name.
So if you download "linux-source-3.2" and build a custom kernel
from it using make-kpkg, the package name will
start out with "linux-image-3.2.35"
(at the time of this writing)
and will be followed by whatever
you specify with the "--append-to-version" option,
even though the stock kernel image package built from the same
source starts out as "linux-image-3.2.0".
I don't know why the change in naming convention was made,
but you need to be aware of it and remember how make-kpkg
names the packages that it creates.
"make deb-pkg" should also use the internal version name.
(By the way, the internal version name is prominently displayed
on the initial screen of "make menuconfig";
so you'll know what it is before you run
make-kpkg.)
Note: if you are using the latest Wheezy
kernel sources with the real-time preemption patches applied, the patches will
automatically include the "-rt" string in the final kernel
version name;
so there is no need to include "-rt" in the
--append-to-version option of
make-kpkg.
If you do, you will end up with "-rt" in the kernel version name twice.
As an example, using the latest version of linux-source-3.2
available at the time of this writing, with the real-time preemption patches
applied, I specified an --append-to-version value of
-4custom01-686-pae and got a final kernel version name of
3.2.35-4custom01-686-pae-rt52.
The number after the "rt", 52 in this case, appears to be a serialization
number which gets incremented each time a new version of the real-time
preemption patches is produced.
Unfortunately, the location of the "rt" string is not in the same place
as it is in the naming convention for stock Debian kernels.
(The corresponding stock kernel has a kernel version name of
3.2.0-4-rt-686-pae.)
However, since make-kpkg uses the internal version
name (3.2.35 in this case)
instead of a contrived version name (3.2.0 for stock kernels), the package
name for a custom kernel will sort higher in the ASCII collating sequence
than the package name for the corresponding stock kernel will;
and that is the most important thing.
Also, I need to talk about initial RAM file system images.
A standard stock Debian kernel is configured
with almost everything built as a
module, if it can be a module, rather than built in to the kernel.
This allows for installation on
as wide a variety of hardware configurations as possible
while holding the
size of the kernel down as much as possible.
But modules reside on disk.
And any kernel function that is required
for the kernel to be able to mount the
partitions or do I/O to the disks must be loaded into storage before any
kernel modules can be read from disk.
This means that either this support must be
compiled into the kernel or else it
must be loaded from the initial RAM file system.
This is the primary purpose for an initial RAM file system:
it allows the kernel to
load modules that it needs before it can read them from disk.
(Recently, the initial RAM file system has acquired a second
purpose: it allows user-space processes, such as udev, to be
launched that assist the kernel in finding its permanent root
file system and suspend/resume images.)
Once the permanent root
file system is mounted read-only,
the initial RAM file system is freed from memory.
As an example from the i386 architecture, suppose your
permanent root file system,
which contains /lib/modules/..., is mapped
to a partition on a SCSI disk.
But the kernel support for the SCSI adapter
is not compiled into the kernel:
it is a loadable module.
As an example from the s390 architecture,
how can you load the dasd driver modules from disk
when those modules must be loaded in order to do I/O to the disk?
In such cases, you need an initial RAM file system.
Stock Debian kernel image packages are set up via the boot loader
(grub, lilo, zipl, etc.) to use
initial RAM file system image files.
I am assuming in
these instructions that you are going to do the same.
If not, then you must do five things:
(1) You must make sure that all kernel function needed to get
the permanent root file system mounted is built-in to the kernel.
(2) You must disable initial RAM file system support in the kernel.
This is handled by the CONFIG_BLK_DEV_INITRD variable, which you should
set to N (i.e. make unset).
In the menuconfig menus, this is labeled "Initial RAM file system
and RAM disk (initramfs/initrd) support".
For recent kernels, this is in "General Setup".
(3) You must not supply the "--initrd" option
to make-kpkg when you invoke it.
(4) You must change your boot loader configuration file
so that it does
not expect an initial RAM file system image file.
And (5) you must make sure that your boot loader configuration
file does not specify the permanent root file system by means
of a UUID=xxx or LABEL=xxx specification.
(Without an initial RAM file system, the udev user space process
cannot be started until after the permanent root file system
has been mounted read-only.)
Taking the path of least resistance, I am assuming that you are going
to use an initial RAM file system image the way the stock kernels do.
OK, with all that said, we are ready to start issuing commands.
If you are running Lenny (5.0) or previous releases, issue the following
command:
 
make-kpkg clean
Under Lenny and previous releases it is necessary to run
make-kpkg with the "clean" target after each invocation
of "make menuconfig" (or any *config target, actually).
Otherwise, the --append-to-version and/or the
--revision options of make-kpkg
won't work properly.
If you are running Squeeze (6.0) or later releases, the above command
may be omitted.
(But if you do run it under Squeeze and later releases, it won't
do any harm.)
Now issue the following command to build the package(s):
make-kpkg --append-to-version -5custom01-686 \
--revision 2.6.32-46 --initrd --rootcmd fakeroot \
kernel_image modules_image
If you don't have any out-of-kernel-source-tree kernel module source
packages installed, you can omit the modules_image target.
The "--initrd" flag indicates that a kernel
which uses an initial RAM file system image is
to be built.
The actual initial RAM file system image file, however, is not built at
this time.
That is deferred until the package is installed.
If you are intentionally building a kernel image package which
contains no initial RAM file system image support,
omit this option.
The "--rootcmd fakeroot" option tells make-kpkg
what command to issue in order to become root.
(In this case, it only simulates becoming root; but that is good enough
for package-building purposes.)
If your computer has more than one processor, and your currently-running
kernel is SMP (Symmetric Multi-Processing) enabled, you may be able to
get the compilation done faster by using the CONCURRENCY_LEVEL
environment variable.
Set the CONCURRENCY_LEVEL environment variable to the number of
simultaneous compile tasks that you want to use.
The maximum practical value for CONCURRENCY_LEVEL is the number of
processors which are online in your configuration.
The minimum value is one.
The default value, if CONCURRENCY_LEVEL is not set, is also one.
For example,
CONCURRENCY_LEVEL=2 make-kpkg ...
will allow two simultaneous compile tasks.
However, if your system is memory (RAM) constrained, this can actually
slow things down.
Running too many simultaneous compiles may cause excessive paging,
which will cause the overall process to take even longer than if fewer
compile tasks were running simultaneously.
If you use this option, make sure you have enough memory to support it.
By using the "getconf" command, you can set CONCURRENCY_LEVEL
to the number of processors currently online, which, assuming that
you have sufficient memory (RAM), will be the optimum value
for compiling the kernel in the shortest possible time.
For example,
CONCURRENCY_LEVEL=$(getconf _NPROCESSORS_ONLN) make-kpkg ...
Of course, making all processors available for simultaneous
compilation will slow down the rest of the system.
There's always trade-offs!
A well-packaged out-of-kernel-source-tree kernel module
source package will have a Debian package designed for use with
kernel-package.
An example is nvidia-kernel-source.
(This package is designed for use with kernel-package
or module-assistant.
Another package, nvidia-kernel-dkms, is provided
for use with dkms.)
For these, the modules_image target, as above, is all you need.
Unfortunately, some out-of-kernel-source-tree kernel module
source packages do not provide a Debian package designed for
use with kernel-package.
An example is sl-modem-source.
This package is designed for use only with dkms
(or by hand with "make" / "make install") and no alternate
source package is available for use with kernel-package.
Note: sl-modem-source has been renamed to
sl-modem-dkms in Wheezy.
sl-modem-source still exists in Wheezy as a dummy transitional
package to bring in sl-modem-dkms.
You can still use these
uncooperative packages with your custom kernel
created by make-kpkg, but in order
to do so you will first need to
build a linux-headers-* package
for your custom kernel.
(This is really stupid, since the entire kernel source tree is
already installed; but faced with these uncooperative packages,
what else can one do?)
If this is your situation, you will need to do two things: (1) add the
kernel_headers target to the make-kpkg command line,
and (2) run the entire make-kpkg command under fakeroot,
eliminating the "--rootcmd fakeroot" option.
For example,
if sl-modem-source is the only out-of-kernel-source-tree
kernel module source package that you have to deal with, your
command would look like this:
fakeroot make-kpkg --append-to-version -5custom01-686 \
--revision 2.6.32-46 --initrd kernel_image kernel_headers
This will cause make-kpkg to build a
linux-headers-*
package for your custom kernel,
as well as a linux-image-* package.
If you have a mixture of out-of-kernel-source-tree kernel module
source packages to deal with, some of which are designed for use
with kernel-package and some of which are not,
you will need to
use all three targets: kernel_image, kernel_headers, and modules_image,
and the entire command must be run under fakeroot, as above.
Whenever you run the entire make-kpkg
command under fakeroot,
you must always eliminate the
"--rootcmd fakeroot" option.
It is best to use the "--rootcmd fakeroot" option,
when possible,
rather than running the entire make-kpkg command under
fakeroot, since this keeps the use of (fake) root privileges to a
minimum; but when building kernel headers packages
you don't have a choice:
you must run the entire make-kpkg
command under fakeroot.
(Of course, if you run make-kpkg as root, then you don't
use either one: don't pre-pend fakeroot onto the command and don't use
the "--rootcmd fakeroot" option either.)
Compiling the entire kernel takes a while.
We're talking hours, probably,
depending on the speed of your processor, and
assuming that your kernel configuration is not too different
from a stock kernel configuration file.
If you have configured a "lean and mean" kernel, it will compile
much faster.
For example, it may only take an hour instead of five hours.
When make-kpkg is finished,
there will be a Debian kernel image package in
the parent directory (.. or /usr/src) of the current directory (. or
/usr/src/linux-source-2.6.32).
If you included the modules_image or kernel_headers target(s),
there may be other Debian package files (.deb files) present as well.
I should probably say something here about fakeroot.
Compiling the kernel does not require root privileges, but building
a Debian package file (.deb file) normally does.
Root privileges are normally needed by
make-kpkg (or by lower-level
commands called by make-kpkg) to
use Linux file system functions such as chmod(2), stat(2), etc.,
that normally will not work
as expected unless the user has root authority.
Without going into a lot of detail, suffice it to say that fakeroot
was specifically created for the purpose of allowing non-root users
to create Debian package files (.deb files).
It makes the software think that it has root authority
when it really doesn't, but the ruse is good enough for package
building purposes.
For more information, see the documentation for fakeroot.
Step 10: Customize the Kernel Installation Environment
Do this step as root.
This step has proven to be the most difficult one for me to
document clearly (and concisely)
because there are so many variations.
Before we get lost in the nitty gritty details, I think it would
be good to step back and review a little history.
This will explain why this step is so messy.
The Debian kernel team used to
use kernel-package (make-kpkg) to
create official Debian stock kernel image packages.
The maintainer scripts that come with a kernel image package created
by make-kpkg examine a configuration file, if it is present,
called /etc/kernel-img.conf, which
can be used to "tune" the kernel installation environment.
/etc/kernel-img.conf is not specific
to any particular kernel image package:
it is a system-wide configuration file that affects the installation
of all kernel image packages created by make-kpkg.
The file is typically generated by the Debian installer and is
maintained by hand thereafter.
The advantage of making /etc/kernel-img.conf a system-wide
configuration file is that the installation of all kernel image
packages created by
make-kpkg can be controlled by a single file.
And since official Debian stock kernel image packages and
user-created custom kernel image packages were both created by
make-kpkg in those days, so much the better!
On the down side, however,
is that /etc/kernel-img.conf does
not belong to any package in particular.
Therefore, which package is responsible
for documenting its contents?
(In other words, which package is responsible for providing
and maintaining the "man page" for kernel-img.conf(5)?)
Well, since the common point of origin is kernel-package,
that task fell to kernel-package.
I guess that's OK for people who create
their own custom kernel image packages,
but it's a poor choice for people who only use official Debian
stock kernel image packages,
which is the vast majority of Debian users.
For users who only use official Debian stock kernel image packages,
they must install kernel-package
(and all of its dependencies)
in order to get the man page for kernel-img.conf(5).
That's like buying Maxwell House to get a cup of coffee,
but that's the way it works.
With the exception of the documentation issue
for /etc/kernel-img.conf,
this arrangement worked quite well for a long time;
but during the transition from Etch (4.0) to Lenny (5.0),
the Debian kernel team made the decision to stop using
make-kpkg from kernel-package to create
their official stock kernel image packages.
I do not know why that decision was made, but it was.
Thus began the current confusing situation.
Of course, their initial maintainer scripts were
based on the maintainer scripts provided by
kernel-package, with
some slight modifications to suit their purposes.
In particular, the maintainer scripts provided with official
Debian stock kernel image packages continued to
use /etc/kernel-img.conf
as their configuration file
for tuning the kernel installation environment;
but now there was no official documentation at all for
/etc/kernel-img.conf
as used by official Debian stock kernel image packages.
Initially, the options were the same as those supported by the
maintainer scripts for kernel image
packages created by make-kpkg;
but over time, the supported options began to differ.
One could argue that
if the Debian kernel team felt compelled
to use their own tools for creating official Debian stock kernel
image packages, they should have used a different configuration
file than /etc/kernel-img.conf,
since that was already in use
by kernel-package; but they didn't.
So now we have the confusing situation that the same configuration
file is used for the same purpose by two separately-maintained
sets of maintainer scripts which support different options.
Furthermore, there is no official documentation for the options
supported by official Debian stock kernel image packages.
Things weren't too bad until Squeeze.
But the version of kernel-package
that comes with Squeeze has
undergone a major philosophical change.
The new philosophy is that most post-installation activities,
such as creating an initial RAM file system image file, maintaining
symbolic links, and running the boot loader installer, will no longer
be done by the maintainer scripts.
If you want these functions done, you must provide "hook scripts"
to do this.
The maintainer scripts provided with stock kernel image packages still
perform some of these functions via options
in /etc/kernel-img.conf,
but they are all undocumented, of course!
And hook scripts provided for use with kernel image packages created
by make-kpkg will also be
executed when a stock kernel image package is
installed or removed, whether you want them to be or not!
To further muddy the waters, the upstream Linux kernel developers
now support a "make deb-pkg" option that allows a
Debian kernel image package to be produced directly from kernel sources
(for 2.6.31 and later kernels) without using any Debian-specific
tools, such as make-kpkg.
These kernel image packages use maintainer scripts which are
different from those included with kernel image packages created
by make-kpkg and those included
with official Debian stock kernel
image packages.
As far as I know, these maintainer scripts do not use a
configuration file during installation or removal.
Finally, there are many different boot loaders available,
each with slightly different requirements.
Customizing the kernel installation environment to allow for
all of these variations can be quite challenging.
The future direction seems to be to do everything in hook scripts,
and /etc/kernel-img.conf will eventually fade away.
But the future is not here yet, and we have to come up
with something that works today.
Customizing the Lenny (5.0) Environment
Even if you are running Squeeze or later I suggest that you read this
section because material covered here is assumed as background
knowledge in later sections.
The /etc/kernel-img.conf file for a Lenny
installation on the i386 architecture with the grub version 1
boot loader (the default) looks something like this:
# Kernel image management overrides
# See kernel-img.conf(5) for details
do_symlinks = yes
relative_links = yes
do_bootloader = no
do_bootfloppy = no
do_initrd = yes
link_in_boot = no
postinst_hook = update-grub
postrm_hook = update-grub
Note the reference to the man page for kernel-img.conf(5),
which is not installed on the system unless you have manually
installed kernel-package, which most people haven't.
Here is a link to an on-line version of the man page from Lenny
which I converted to html for your viewing pleasure:
man kernel-img.conf.
It should be fairly accurate for kernel image packages created by
make-kpkg under Lenny.
How accurate it is for official stock Debian kernel image packages
I do not know, but the Lenny version of the man page for
kernel-img.conf(5) is the closest thing there is to
documentation for the options supported by official stock Debian
kernel image packages.
do_symlinks = yes specifies
to create symbolic links.
(I'm not sure why this is set to yes when grub
is the boot loader, since grub,
as installed and configured in Debian, doesn't use symbolic links.
Perhaps this is done for reasons of forward compatibility.)
A symbolic link called vmlinuz
will be created which points to the
current kernel image file, and a symbolic link called initrd.img
will be created which points to its
corresponding initial RAM file system image file.
Similarly, a symbolic link called
vmlinuz.old will be created which points
to the previous kernel image file, if any, and a symbolic link called
initrd.img.old will be created which points to its
corresponding initial RAM file system image file, if any.
These symbolic links are typically used by traditional boot loaders,
such as lilo and zipl.
Where those symbolic links are created is determined by the
link_in_boot option.
If link_in_boot is set to "no", the symbolic
links are maintained in
the / directory;
if link_in_boot is set to "yes", the symbolic
links are maintained in
the /boot directory.
relative_links = yes specifies
that the symbolic links are to use relative path names
rather than absolute path names.
Again, I have no idea why these symbolic links are requested by default
for a boot loader that doesn't need them.
If I were running grub, I would set do_symlinks to "no"
and manually delete the symbolic links from the / directory.
do_bootloader = no specifies not to run the
historic boot loader installer
during a kernel installation.
do_bootloader = yes
is used to request that a traditional boot loader installer,
such as lilo or zipl, should be run during kernel installation.
With grub you don't need this option.
do_bootfloppy = no specifies not to make a bootable
floppy disk as a recovery disk during kernel installation.
This option is vestigial.
It is no longer documented in the man page
for kernel-img.conf(5) in Lenny.
I doubt that do_bootfloppy = yes would work
anymore.
do_initrd = yes
probably doesn't mean what you think it means.
Most people's first guess is that it requests the creation of
an initial RAM file system image file.
That is not what it means.
When installing a stock kernel image package, the maintainer scripts will
always create an initial RAM file system image file,
since a stock kernel image
package always needs one.
When installing a kernel image package created by make-kpkg,
an initial RAM file system image file
will be created if the --initrd option was specified
on the make-kpkg command line when the kernel image
package was created.
All do_initrd = yes does
is to suppress a warning message
that might otherwise be issued.
This is a warning from the transition days between kernel image
packages that did not require or use an initial RAM file system image
and subsequent kernel image packages which did.
The warning was
"Warning: this kernel image package requires an initial RAM
file system image.
Make sure that your boot loader is set up properly to handle it."
(I'm not sure of the exact wording,
but it was something along those lines.)
do_initrd = yes suppresses this warning message.
Finally, postinst_hook = update-grub and
postrm_hook = update-grub
request that the "update-grub"
command be run whenever a kernel
image package is installed or removed.
This is what you want for grub (version 1).
If this is your configuration, and you want to continue using
grub, then you should be OK to install either a stock
kernel image package or a kernel image package created by
make-kpkg under Lenny.
Changing Boot Loaders
This web page really isn't about how to change boot loaders;
but this seems like a good time and place to mention it,
since we are up to our ears in kernel image package installation
issues here.
If you are interested in switching to the LILO boot loader
(my personal favorite), see my
LILO Web Page.
Even if you do not plan to change boot loaders,
you may find it useful to read this page
because it provides useful
insights into how the kernel maintainer scripts,
/etc/kernel-img.conf,
update-initramfs, hook scripts,
and the boot loader interact.
It also provides some useful information about the boot process
in general.
Customizing the Squeeze (6.0) Environment
(If you are running Wheezy/Sid, you should still read this section
because this section is the foundation for both.)
Squeeze changes things.
The maintainer scripts that are packaged with a kernel image package
created by make-kpkg
under Squeeze and later releases no longer
perform most post-installation tasks,
such as building an initial RAM
file system image file, updating symbolic links, or running the boot
loader installer, even if such tasks are requested
in /etc/kernel-img.conf.
The maintainer scripts that are packaged with
kernel image packages created by make-kpkg
in Squeeze and later releases rely on "hook scripts"
to provide these functions, if needed.
The same holds true for the maintainer scripts that are packaged with
kernel image packages created by "make deb-pkg".
Furthermore, it appears to be the goal of the Debian kernel team
to make examination of /etc/kernel-img.conf unnecessary
eventually, even for stock kernel image packages.
Here is a simplified overview of how hook scripts
work under Squeeze.
After a kernel image package is installed, any executable files found in
/etc/kernel/postinst.d will be invoked.
These executable files are normally script files placed there by
various packages that need or want to know about a kernel image package
installation or upgrade.
The kernel image package maintainer script invokes these scripts
via the run-parts utility, and run-parts
executes them in alphabetical order.
They are called hook scripts because they are invoked by a kernel
image package maintainer script, but they do not belong to the
kernel image package itself: they are "hooks" placed there by
other packages.
One of the post-installation scripts
in this directory is initramfs-tools.
Its purpose is to create an initial RAM file system image file
for a kernel image package which needs one when that kernel image
package is installed.
It exits without doing anything if a stock
kernel image package is being installed, since stock kernel
image package maintainer scripts take care of creating the initial
RAM file system image file for a stock kernel image file.
It also exits without doing anything if the kernel image package
was created by make-kpkg and the --initrd
option was not specified on the
make-kpkg command line when the
kernel image package was created.
But for kernel image packages created by make-kpkg
with the --initrd option or for kernel
image packages created by "make deb-pkg",
the initramfs-tools hook script creates
the initial RAM file system image file which is needed by these
kernel image files.
Similarly, when a kernel image package is removed or purged, any
executable files found in /etc/kernel/postrm.d will be invoked.
Again, the run-parts utility
is used to execute these scripts,
and they are run in alphabetical order.
One of the post-removal scripts
in this directory is initramfs-tools.
Its purpose is to delete the initial RAM file system image
file for a kernel image package that uses one
when that kernel image package is removed.
It currently exits without doing anything if a stock kernel image
package is being removed, since the maintainer scripts for a
stock kernel image package take care of deleting the initial RAM
file system image file for a stock kernel image file.
Otherwise, it attempts to delete the
initial RAM file system image file.
But if one is not found, it still exits cleanly.
For completeness' sake, I should also mention that there are two other
directories where hook scripts can be installed: /etc/kernel/preinst.d
and /etc/kernel/prerm.d.
You can probably guess by their names when
their contents are invoked.
But you normally won't need to be concerned about them.
As soon as multiple hook scripts are placed into the same
directory, the issue of execution order arises.
As previously stated, the run-parts utility
is used to execute these
hook scripts; and they are run in alphabetical order.
Thus, the naming convention directly determines in what order
the scripts will execute.
The theory is that a boot loader hook script, if present,
should execute last.
Therefore, current policy is that boot loader hook scripts
must start with "zz-";
and no other hook scripts are allowed to
start with "zz-" or any other string which sorts later
than "zz-" in the
collating sequence used by run-parts.
If your boot loader does not use symbolic links, you probably don't
need any more hook scripts.
But if you are using a boot loader that makes use of symbolic links,
such as lilo or zipl,
you will probably need some additional hook scripts.
The current hook script policy can be found
here.
At the time of this writing, boot loaders which need them
provide hook scripts; but they are usually not optimal.
For example, they may not handle symbolic link maintenance
for custom kernel image packages
or may not prevent unnecessary invocations of
the boot loader installer.
At the time of this writing, no boot loader packages that I have
looked at provide hook scripts that maintain symbolic links.
The maintainers apparently assumed that symbolic links would be
taken care of by "do_symlinks = yes" in
/etc/kernel-img.conf, but that only works
for official Debian stock kernel image packages.
For kernel image packages created by the Squeeze or later
versions of make-kpkg or for kernel image packages
created by "make deb-pkg", this setting has no
effect; and symbolic links, if used, must be maintained by hook
scripts.
At the time of this writing, there are no hook scripts available
as part of the official Debian system which will maintain symbolic
links; but I have written some which are available on my web site
for download.
You can install the
zy-symlinks
hook script in the /etc/kernel/postinst.d directory and the
zy-symlinks
hook script in the /etc/kernel/postrm.d directory.
Because of the naming convention,
they will be invoked after
the initramfs-tools hook script but
before the boot loader hook script,
which is what needs to happen.
(Note that these two hook scripts, though they are not identical,
do have identical names; so don't download both of them to the same
download directory or the second one downloaded will replace the first
one downloaded!)
Once you have downloaded these files and copied them to their proper
destination directories, be sure to use chown, chgrp, and chmod commands,
as needed, to set their attributes properly.
The group should be root, the owner should be root, and the permissions
should be -rwxr-xr-x (755).
The boot loader hook scripts provided with lilo
and zipl do not distinguish between
pre-configure, configure, remove, and purge calls,
and thus invoke the
boot loader installer more times than necessary.
(See Debian bug number
599931
and Debian bug number
599934
for more information.)
What I do on my systems is enhance the hook scripts provided with the
boot loaders based on the suggestions
in the above bug reports plus install
the zy-symlinks hook scripts.
I still have to remember to re-customize the hook scripts when the boot
loader package is updated,
but this seems to be the best solution for right now.
These hook scripts may run underneath a higher-level process,
debconf to be specific, which has redirected both standard input (STDIN)
and standard output (STDOUT).
When the interface is fully active, debconf expects the program to write
debconf protocol commands to STDOUT and read result codes on STDIN.
Thus, output to STDOUT does not display on the terminal
and can potentially wreak havoc.
Thus, any console output produced by hook scripts must be
redirected to standard error (STDERR).
This is accomplished by means of the
>&2 redirection operator.
You can see this on all commands in the scripts that would normally
write to STDOUT.
Similarly, if a command normally reads from STDIN, its input must
be redirected to another source, such as a file.
If you don't anticipate STDIN being used, but you want to protect
yourself against STDIN being accidentally used, you can redirect
STDIN to /dev/null.
This is done by the </dev/null redirection operator.
If you see these redirection operators on commands in the hook scripts,
you now know why they are there.
When run under debconf, for example during an
"aptitude full-upgrade" or an
"aptitude safe-upgrade",
the postinst hook scripts are called during
pre-configuration and again during configuration.
No action need be taken during pre-configuration;
therefore, the zy-symlinks hook script
tests for this condition and returns without doing anything
if called for pre-configuration.
The initramfs-tools hook script does the same.
I hope someday that the zz-zipl and zz-runlilo
hook scripts provided with the s390-tools and lilo packages,
respectively, will provide similar logic.
In the meantime, I have local modifications to them on my systems
to add this logic, as detailed in the above-mentioned Debian bug
reports.
The postrm hook scripts are called for both a remove and
a purge.
For a purge, they don't need to do anything, since all the
work was done at remove time.
Therefore, the
zy-symlinks hook script tests for this condition.
If it is being invoked for a purge it returns to its caller
without doing anything.
The initramfs-tools hook script does the same thing.
I hope someday that the zz-zipl and zz-runlilo
hook scripts provided with the s390-tools and lilo packages,
respectively, will provide similar logic.
In the meantime, I have local modifications to them on my systems
to add this logic, as detailed in the above-mentioned Debian bug
reports.
Note: Debian bug number 599934 is now fixed in
Wheezy for the lilo package, and Debian bug number 599931 is
now fixed in Wheezy for the s390-tools package.
But these fixes have yet to make it into an update for Squeeze,
and probably never will.
Therefore, if you're running Squeeze, you will either have to live
with them or else fix them by hand.
OK, so we've installed these hook scripts for the benefit of
kernel image packages created by make-kpkg
or "make deb-pkg"; but how do they
affect stock kernel image packages?
The maintainer scripts for a stock kernel image package know that
the kernel needs an initial RAM file system image file; so they always
create one during installation.
The initramfs-tools hook script knows this also, and it
does not create an initial RAM file system image file for a stock kernel
image package.
If you have do_symlinks = yes specified in
/etc/kernel-img.conf,
the maintainer scripts for a stock kernel image package
currently honor this and will maintain the symbolic links
during installation.
If you have the zy-symlinks hook scripts installed,
you should change this to do_symlinks = no
to avoid duplication of effort.
do_bootloader = yes in
/etc/kernel-img.conf is no longer honored
in Squeeze.
Set this variable to "no" or eliminate it altogether.
The boot loader hook scripts
will take care of running the boot loader installer during kernel
image package installation, update, and removal, if needed;
and "update-initramfs -u" will
run the boot loader installer as well, if needed.
The postinst_hook = update-grub and
the postrm_hook = update-grub lines
from the /etc/kernel-img.conf file, if they exist,
should be deleted.
Even if you are still running grub, this will be
taken care of by the boot loader hook scripts.
And if you're not running grub,
that's all the more reason to eliminate them!
The maintainer scripts for a stock kernel image
package delete the initial RAM
file system image file during a remove.
The initramfs-tools hook script knows this and does
not attempt to delete the initial RAM file system image file
for a stock kernel image package.
If you have do_symlinks = yes specified in
/etc/kernel-img.conf, the maintainer scripts for
a stock Debian kernel image package will currently attempt to
remove broken links caused by the removal of the kernel image file
and its initial RAM file system image file.
If you have the zy-symlinks hook scripts
installed, this is not necessary, since the
zy-symlinks hook script
will take care of this for you.
You should set do_symlinks = no in this case
to avoid duplication of effort.
Finally, the maintainer scripts for a stock kernel image package
do not run the boot loader installer
during a remove.
However, the boot loader hook script will take care
of that for you, if needed.
In summary, this is what I recommend for
/etc/kernel-img.conf
for Squeeze and later releases when the proper hook scripts are used:
do_symlinks = no
do_symlinks = no is there because the
default value for this variable is still "yes" for stock kernels,
and we need to override the default.
For custom kernels, the option is vestigial.
The zy-symlinks hook scripts, if installed,
will take care of symbolic link maintenance for you,
both for stock and custom kernels.
relative_links is now vestigial in Squeeze,
both for stock and custom kernels;
so it should be omitted.
link_in_boot is now vestigial for custom kernels,
but still has meaning for stock kernels.
However, its value doesn't matter
when do_symlinks = no is used;
so it is also omitted.
The zy-symlinks hook scripts maintain the symbolic links
wherever they are found.
If they exist in both / and /boot, the ones in / take precedence.
You should not allow them to exist in both places.
If you are changing the location where the symbolic links are maintained
from where they were previously, you will have to manually delete the
old symbolic links and manually
create the new symbolic links the first time.
Thereafter, they will be maintained automatically.
(Of course, your boot loader configuration file
will need to be changed too.)
do_bootloader is omitted because its default value is "no"
for stock kernel 2.6.32.
For later stock kernels, it is a vestigial option.
The option is vestigial for all custom kernels in Squeeze
and later releases.
The boot loader hook scripts will take care of running the
boot loader installer during a kernel image package install, update, or
remove; and "update-initramfs -u" will take care of
running the boot loader installer, when necessary, for updates of the initial
RAM file system image file.
do_initrd is also omitted because it is now a vestigial option,
both for stock and custom kernels.
As you can see, /etc/kernel-img.conf
is no longer as important as it once was.
There is one final hook script directory
of which you should be aware.
To allow the removal of special boot loader processing
logic from initramfs creators
(initramfs-tools, yaird, etc.),
the new policy requires hook scripts in
the /etc/initramfs/post-update.d directory
for any boot loader that uses initial RAM file system image files and
that reads the initial RAM file system image files by means of a list
of blocks saved at boot loader installer run time, such
as lilo and zipl.
Since "update-initramfs -u" invokes the boot
loader installer anyway, when needed, you may wonder why the initramfs
hook script is needed.
Due to migration considerations, it takes two releases to get
rid of boot-loader-specific logic from initramfs-tools
(or any other initramfs creator package).
The goal is to remove the boot-loader-specific logic
from initramfs-tools in Wheezy.
In order to do that, they must be able to assume that
the Squeeze release always uses an initramfs hook script
when needed.
The boot-loader-specific code is there only to facilitate
migrations from Lenny and must not be relied upon
in Squeeze itself.
Customizing the Wheezy (7.0) Environment
At the time of this writing, the Wheezy Environment is nearly
identical to the Squeeze environment.
The main differences are as follows:
-
Debian Bug report numbers
599931 and 599934 have been fixed in Wheezy.
However, the initramfs hook script for zipl is still not optimal.
See Debian Bug report
696943
for details, including a patch.
-
Special boot loader processing logic has been removed from
initramfs-tools.
Hook scripts in /etc/initramfs/post-update.d are
now essential for boot loaders which read
the initial RAM file system image file by means
of a list of physical block numbers created when the boot loader
installer is run.
-
The latest kernel source packages now create three binary
packages when "make deb-pkg" is used:
a linux-image-* package, a linux-headers-*
package, and a linux-libc6-dev package.
(With earlier kernel sources,
only a linux-image-* package was created.)
The linux-headers-* package allows kernel module
source packages designed for use with module-assistant
or dkms to be used with these custom kernel image packages.
However, you may not need these extra packages; and there does not
appear to be any easy way to prevent them from being produced.
I still recommend the use of make-kpkg
because of its greater flexibility.
With make-kpkg you only get the binary packages that
you ask for.
If you don't need a headers package, for example, you don't
have to create one.
And even if you're creating out-of-kernel-source-tree modules,
a kernel module source package designed for use with
kernel-package doesn't need a headers package.
-
The maintainer scripts for the latest stock kernel image packages
no longer automatically create an initial RAM file system image file
during installation, nor do they automatically delete an initial
RAM file system image file during removal.
They now rely on the initramfs-tools hook scripts
in /etc/kernel/postinst.d and /etc/kernel/postrm.d to create
and delete, respectively, an initial RAM file system image file, just
as the maintainer scripts for kernel image packages created by
make-kpkg and "make deb-pkg" do.
I hope that before Wheezy becomes stable some type of policy
is created to address the issue of symbolic links, their use by
boot loaders, and their maintenance by hook scripts or other
means.
For non-stock kernels at least, this is currently a "hole" which
is not addressed by any official portion of the Debian system.
(In other words, boot loader hook scripts are not required to
maintain symbolic links, and none that I have seen do.
Also, no hook scripts provided by
any other packages maintain them either.
Nevertheless, the boot loader may rely on the symbolic links
being maintained somehow, and custom kernel maintainer scripts
no longer maintain them.)
My "zy-symlinks" hook scripts address this issue, but they are
not an official part of the Debian system.
Regardless of whether you are running Lenny, Squeeze, or Wheezy,
the customization of the kernel installation environment
only needs to be done
the first time you prepare to install a kernel image package
created by make-kpkg or "make deb-pkg".
Once you've done it, you can create as many kernel image packages
with make-kpkg
or "make deb-pkg" as needed
and install them, skipping this step.
Step 11: Install the Kernel Image Package
Do this step as root.
OK, now it's time to actually install the kernel image package.
You won't use aptitude or apt-get
to install the kernel image package.
That is due to the fact that it doesn't have
to be fetched from anywhere.
Instead, use the low-level package tool dpkg.
cd /usr/src
dpkg -i linux-image-2.6.32-5custom01-686_2.6.32-46_i386.deb
Obviously, use the actual name of the package file,
which can be determined by using the ls command.
If you have both a kernel image package and one or
more modules image packages, install the kernel image package first,
then the modules image packages.
The latter will probably have a dependency on the former.
If you had to build a linux-headers-* package to
accommodate an uncooperative kernel module source package,
install the linux-headers-* package first,
then the linux-image-* package.
(dkms may get activated to build a new binary kernel module
when you install the linux-image-* package,
and the build will fail if you don't have the
linux-headers-* package installed already.
You can ignore dkms-related error messages which occur
during installation of the headers package.)
If the kernel installation environment has been properly customized,
the maintainer scripts or the hook scripts
will automatically create the initial RAM
file system image file, update the symbolic links,
and re-run your boot loader installer, if
necessary.
But before you shut down and reboot, it is a good idea to check
everything out in /boot and in
your boot loader configuration to make sure that the
new kernel was installed properly.
Step 12: Shutdown and Reboot
Do this step as root.
Shutdown and reboot to run your new custom kernel!
shutdown -r now;exit
Step 13: Clean Up
Do this step as a non-root user.
Use the same userid for all non-root steps.
The non-root user must be a member of group "src".
Once the new kernel image package has been installed, you can
delete the package file (.deb file).
cd /usr/src
rm linux-image-2.6.32-5custom01-686_2.6.32-46_i386.deb
If you have also installed one or more modules image packages,
you can delete their package files too.
The same goes for a linux-headers-* package.
Step 13a: Clean Up (Part Two)
Do this step as root.
Once you are satisfied with the new kernel, you may wish to de-install
the old kernel image package.
I like to keep at least one back version unless I know
that the old kernel will no longer work due to changes
made since migrating to the new kernel.
For example, if my system now depends on a kernel module
that did not exist in the old kernel, there's not much point
in keeping the old kernel around.
aptitude purge linux-image-2.6.32-5-686
This will de-install the old kernel image package and
save some more disk space.
If you have out-of-kernel-source-tree kernel module image packages
installed that are tied to the old kernel image package,
purge the kernel module image packages first,
then purge the old kernel.
If you have a linux-headers-* package
that is tied to the old kernel, purge it last.
Note: make sure you have shut down and re-booted using
the new kernel before attempting to purge the old kernel!
You don't want to try to purge a kernel while it is running!
Besides, you don't yet know if your new kernel works!
May you have much enjoyment running your new custom kernel!
Step 14: Maintenance
This is a mixed-mode step: some commands are issued as root
and some commands are issued as a non-root user.
OK, now what if you get the new custom kernel installed and running,
but you want to make changes to the kernel configuration?
Maybe you forgot something the first time.
Use a sequence of commands something like this.
(Note: the commands which must be run as root are prefaced with a
pound sign.
The commands which should be run as a non-root user are prefaced
with a dollar sign.
Use the same userid for all non-root steps.
The non-root user must be a member of the "src" group.)
$ cd /usr/src/linux-source-2.6.32
$ make-kpkg --rootcmd fakeroot modules_clean
$ make-kpkg clean
$ make menuconfig
$ make-kpkg clean
$ make-kpkg --append-to-version -5custom02-686 \
> --revision 2.6.32-46 --initrd --rootcmd fakeroot \
> kernel_image modules_image
$ cd ..
$ su
# dpkg -i linux-image-2.6.32-5custom02-686_2.6.32-46_i386.deb
.
. ("dpkg -i" commands to install the modules image package files)
.
# exit
.
. ("rm" commands to remove the modules image package files)
.
$ rm linux-image-2.6.32-5custom02-686_2.6.32-46_i386.deb
$ su
# shutdown -r now;exit
Something like the above will do nicely.
(The ">" is the shell's continuation prompt.
Do not type it literally, just as you don't type the "$"
or "#" literally.)
Note the extra commands to do cleanup (make-kpkg with the
modules_clean and clean targets).
Since you've done a previous build and have not wiped out the source
directories and started over, these targets are recommended
at this point.
Note that "--rootcmd fakeroot" is not needed for the
"clean" target, but it is usually needed
(depending on how the modules are packaged)
for the "modules_clean" target.
The second "make-kpkg clean" command is only needed
for Lenny and previous releases: it may be omitted for Squeeze
and later releases.
Notice that the "--append-to-version"
flag needs to be changed slightly each time.
If you do not have out-of-kernel-source-tree kernel module
source packages to build,
don't issue the
"make-kpkg --rootcmd fakeroot modules_clean"
command, remove
the modules_image target from the last make-kpkg
command, and of course there will be no extra ".deb" files
to install or remove.
As before, if you need a headers package, add the kernel_headers
target to the main make-kpkg command, remove the
"--rootcmd fakeroot" option, and run the entire
make-kpkg command under fakeroot.
Add a command to install the headers package immediately
prior to the command to install the main image package
and a command to erase the headers package file after installation.
For boot loaders which use symbolic links, such as lilo and zipl,
your boot loader is typically configured to boot two kernels: the primary
kernel, which is the most recently installed one, and one alternate one,
which is the next most recently installed one.
If you didn't de-install the
stock kernel last time, you should probably do so now.
You've got three kernel image
packages installed on your machine now:
the original stock kernel, your first custom
kernel, and your second custom kernel.
And only the two custom ones are
bootable at this point, unless you've been customizing your boot loader
configuration as well.
# aptitude purge linux-image-2.6.32-5-686
If you have out-of-kernel-source-tree kernel module image packages
installed that are tied to the old kernel image package,
purge the kernel module image packages first,
then purge the old kernel.
If you have a headers package installed which is tied to the old kernel,
purge it last.
Once your first custom kernel rolls off the boot loader menu,
de-install it in a similar manner.
For boot loaders such as grub which do not use symbolic links, it's
up to you how many back-level kernels you want to keep around.
For most people, two bootable kernels
(the current one and the previous one) are adequate.
OK, you've been happily running your custom kernel
for several months now;
and you get a security update notice from Debian.
After waiting a couple of days for the upload to propagate to all
mirrors, including the one you use,
you update the list of
available packages via "aptitude update", then you run
"aptitude full-upgrade".
And when you do, you notice that an updated kernel
source package (in this example,
linux-source-2.6.32) has been downloaded
and installed.
What do you do now?
Well, it's time to clean house.
Of course
you've already run "aptitude clean", right?
(You should always run
"aptitude clean" after
running "aptitude full-upgrade".)
$ cd /usr/src
$ rm -r linux-source-2.6.32
$ tar -xjf linux-source-2.6.32.tar.bz2
$ rm linux-source-2.6.32.tar.bz2
For Wheezy kernels, you will also have the real-time
preemption patches to deal with, as discussed earlier.
Either install them or erase them, per your choice.
A similar procedure is followed if an out-of-kernel-source-tree
kernel module source package has been downloaded and installed.
For example, if nvidia-kernel-legacy-96xx-source
is downloaded and installed, you would do the following:
$ cd /usr/src
$ rm -r modules/nvidia-kernel-legacy-96xx
$ tar -xjf nvidia-kernel-legacy-96xx-source.tar.bz2
$ rm nvidia-kernel-legacy-96xx-source.tar.bz2
If your kernel source is replaced, you don't need to use the "clean"
target of make-kpkg.
Similarly, if your module source is replaced, you don't need to
use the "modules_clean" target of make-kpkg
for that module.
But for those sources which are not replaced, it is a good idea
to run make-kpkg with the appropriate "clean" target.
If some but not all of your module sources have been replaced,
you can use the --added-modules option to specify
which module sources to clean (the ones that weren't replaced).
The "clean" target cannot be specified in conjunction with
any other target; so the "clean" and "modules_clean" targets
must be specified in separate commands, and "clean", if needed,
should be last.
Remember, your current directory must be the kernel source
directory (i.e. /usr/src/linux-source-2.6.32)
whenever you run make-kpkg, including the "clean" targets.
If you applied a patch file to your kernel source code
in step 7, you now understand why I recommended to create a
symbolic link to the patch file instead of moving the patch file
to the top level directory of the kernel source code.
When that directory was removed, the symbolic link disappeared
with it; but the patch file itself in /usr/src still exists.
All you need to do is to redefine the symbolic link and you're
back in business.
If you had moved the patch file to the top level directory of
the kernel source code, the patch file would now be gone,
and you would have had to recreate it.
Of course, the same principle applies for a patch file to a kernel
module source code package.
Now proceed to step 7, with some minor variations.
If the kernel source was replaced, you will need to recreate the
symbolic link(s) to the patch file(s), if any, and reapply the
patches.
(The patch files themselves will still be there in /usr/src.)
If a kernel module source package was replaced, do the same for any
patch files you have against the module source.
If the kernel source was replaced, the name of the config
file that gets copied from the /boot directory to .config in the current
directory must change to match the current kernel config file.
Since the old config file may no longer be exactly in sync
with the new source code,
you will need to run "make oldconfig" after you
copy the old config file from /boot to ".config".
(Alternatively, you can obtain a config file from a stock kernel
built from the exact same source.)
If the kernel source was replaced, you must
re-run "make menuconfig",
even if you don't change a thing in the kernel
configuration, because some files get
created by "make menuconfig" that
make-kpkg needs, and you just erased them.
As before, if you're running Lenny, you need to run
"make-kpkg clean" after each run of
"make menuconfig" (or make with any other *config target).
The "--append-to-version" flag
must change slightly to not conflict with any
of the kernel versions you currently have installed.
If the kernel source was replaced,
the "--revision" flag must change too,
since kernel source package updates
always change the package version.
(If you're using pristine kernel sources, change your "made up"
revision name for consistency.)
The name of the kernel image package file,
the kernel headers package file, and the
module image package files will change too;
so the "dpkg -i" command(s) will also change,
as will the commands to remove (rm) the package files.
And of course the "aptitude purge"
commands must change to de-install the correct old
version of the kernel image package,
the kernel headers package,
and their associated module image packages.
By now you get the idea.
Note: sometimes the stock kernel configuration file
will change with a security update
or a new stable point release.
The powers that be may have decided to change a kernel configuration
option for security or other reasons.
The announcement e-mail should tell you what was changed and why.
In that case, if you want to keep your custom kernel configuration file
in sync with the latest stock kernel, you will need to
make a corresponding change to your custom kernel config file
when you run "make menuconfig".
Alternatively, you can obtain a config file from the updated
stock kernel and copy it to .config before
running "make menuconfig".
If you're using an official Debian kernel source package, such as
linux-source-2.6.32, you will automatically
get updates to it when you run the "aptitude update"
and "aptitude full-upgrade" combination.
However, if Debian moves on to a different kernel version,
you don't get the updated kernel source automatically.
For example, when Wheezy was first made the testing release,
it was running a 2.6.32 kernel, just as Squeeze does.
However, as time went on, Wheezy changed from a 2.6.32
kernel to a 2.6.39 kernel, and later to a 3.0.0 kernel.
As of right now it's running a 3.2.35 kernel.
With linux-source-2.6.32 installed, one got automatic
source updates as long as 2.6.32 was the current kernel version;
but once Wheezy moved on to 2.6.39 as the current kernel, source
updates ceased.
You can get around this problem by installing the
linux-source package.
linux-source is a meta-package which depends on the
latest kernel source package.
If you have linux-source installed, you will
automatically get kernel source package updates even when the
kernel version changes.
Obviously, if you are using pristine kernel source tarballs
from kernel.org or one of its mirrors, moving on to a new
kernel version is an entirely manual process.
Alternatives
For Linux kernels 2.6.31 and later, "make deb-pkg" is
an alternative to make-kpkg.
("make deb-pkg" is supported upstream,
whereas make-kpkg is a Debian-specific tool.)
But the author of kernel-package has pointed
out that "make deb-pkg"
is not as feature rich as make-kpkg.
For example, one can't produce doc or debug packages from
one's custom sources with "make deb-pkg".
Until recently, one could not produce headers packages with
"make deb-pkg" either; but the latest
Wheezy kernels have support for creating headers packages with
"make deb-pkg".
Also, I don't recommend using "make deb-pkg" on
Lenny systems, even if the kernel source package
is new enough to support it,
since the hook script architecture required to properly install
the resulting binary Debian kernel image package
is not generally present on Lenny systems.
(For example, the /etc/kernel/postinst.d/initramfs-tools
and /etc/kernel/postrm.d/initramfs-tools hook scripts
are not usually installed on Lenny systems.)
If you have a kernel source package new enough to support
"make deb-pkg", you are running Squeeze or later,
support for headers packages, if needed, is present,
and you want to try out
"make deb-pkg", go ahead.
If you decide to use "make deb-pkg", you will need
to know the analogies to the options of make-kpkg.
"make deb-pkg" does not have the equivalent of
make-kpkg's --append-to-version option,
but you can accomplish the same thing by using the CONFIG_LOCALVERSION
and the CONFIG_LOCALVERSION_AUTO kernel configuration options,
which I earlier told you not to use.
The equivalent of make-kpkg's --revision
option is the make variable KDEB_PKGVERSION.
For example:
$ make KDEB_PKGVERSION=2.6.32-46 deb-pkg
The equivalent of make-kpkg's --initrd
option seems to be hard coded in "make deb-pkg":
The initramfs-tools hook scripts always create
or delete
an initial RAM file system image file for a kernel image package
created by "make deb-pkg".
The equivalent of make-kpkg's --rootcmd
option is the make variable KBUILD_PKG_ROOTCMD.
If "make deb-pkg" is not run as root
(or under fakeroot), and KBUILD_PKG_ROOTCMD is not set,
"fakeroot" is assumed as its default value.
If fakeroot is not installed, you will get an error message.
The CONCURRENCY_LEVEL environment variable is not supported,
but the -j option provides equivalent function.
For example:
$ make -j2 deb-pkg
is the equivalent of setting CONCURRENCY_LEVEL to 2.
Anything pertaining to modules, such as the MODULE_LOC environment
variable, the --added-modules option, the modules_*
targets, etc., has no equivalent, since "make deb-pkg"
does not create kernel module image packages.
If your kernel source is new enough, "make deb-pkg"
will create a linux-headers-* package; otherwise it
won't.
If it does create a linux-headers-* package, you
can handle out-of-kernel-source-tree kernel module source packages
designed for use with
module-assistant or dkms.
/usr/src is the historic (and default) location for package source
code under Debian GNU/Linux, but
some people don't like to put it there because it violates the FHS
(Filesystem Hierarchy Standard).
They prefer to put it somewhere else, such as ~/src.
(~ represents the home directory of the non-root user
who will own the source code.)
If this is what you want to do, there are a few changes you will
need to make.
After installing the source package (as root) with
"aptitude install linux-source-2.6.32",
switch to your non-root user and unpack the file like this:
$ cd /usr/src
$ tar -xjf linux-source-2.6.32.tar.bz2 -C ~/src
The "-C" option of tar specifies the directory
where the files will be extracted.
The default value, if the "-C" option is not specified,
is the current directory.
If you are building out-of-kernel-source-tree
kernel module source packages
as well, use the same "-C" option on the tar commands
to unpack their source tar files.
They will be unpacked to a directory under ~/src/modules.
In addition, when you build out-of-kernel-source-tree kernel module
image packages, you must supply an environment variable called MODULE_LOC
to make-kpkg which specifies the location of the
module source code.
For example,
$ cd ~/src/linux-source-2.6.32
$ MODULE_LOC=~/src/modules make-kpkg ... modules_image
If MODULE_LOC is not specified,
the default value is /usr/src/modules.
Make other adjustments to path specifications as appropriate.
Note that if you do your processing under your home directory, as
in this example, your non-root user account does not need to be a
member of the src group.
If you do your processing under some other directory, make sure that
your non-root user account is a member of the group that owns the
directory, make sure that the group has read, write, and execute
privileges on
the directory, and make sure that the "set-group-ID"
attribute is set for the directory.
Also make sure that the group which owns the directory is listed
in the output of the groups command issued by the non-root userid
that you are going to use before proceeding.
A couple of environment variables used by make-kpkg
have already been
discussed (CONCURRENCY_LEVEL and MODULE_LOC), and there are a few more
environment variables which affect
the operation of make-kpkg
that may occasionally be useful in special circumstances.
(For more information, see the man page
for make-kpkg(1).)
There are two ways to specify environment variables: as a prefix to the
command itself and implicitly via the "export" command.
Here is an example of the prefix method:
$ cd ~/src/linux-source-2.6.32
$ CONCURRENCY_LEVEL=$(getconf _NPROCESSORS_ONLN) \
> MODULE_LOC=~/src/modules make-kpkg ...
In the prefix method, the environment variables are specified as
prefixes to the make-kpkg command itself.
The values of these variables only apply to the environment of
the make-kpkg command (and to all commands which
are invoked by the make-kpkg command).
These environment variable values do not affect the values of
any variables by the same name in the current shell.
Their previous values, if any, remain unchanged in the current shell,
and if they had no previous values in the current shell, they remain
unset.
Also, subsequent invocations of make-kpkg (or any other
command) do not inherit these environment variable values:
they apply only to that specific command.
In the export method, the environment variables are set as ordinary
variables in the current shell, then they are marked for export using
the shell's "export" command.
For example:
$ cd ~/src/linux-source-2.6.32
$ CONCURRENCY_LEVEL=$(getconf _NPROCESSORS_ONLN)
$ MODULE_LOC=~/src/modules
$ export CONCURRENCY_LEVEL MODULE_LOC
$ make-kpkg ...
Optionally, the assignment of a value can take place on the export
command itself.
For example,
$ cd ~/src/linux-source-2.6.32
$ export CONCURRENCY_LEVEL=$(getconf _NPROCESSORS_ONLN) \
> MODULE_LOC=~/src/modules
$ make-kpkg ...
Either way, the shell variables listed on the export command are
passed to every subsequent command, whether you
want them to be or not, including make-kpkg.
However, they only apply to commands invoked from the shell that
issued the export command (and lower-level shells or sub-shells invoked
from that shell).
One may also use a combination of the two methods.
For example, one of the above two environment variables may be set
in the current shell and marked for export, while the other one
is passed using the prefix method.
Use whatever method works best for you.
Note: it is important to distinguish between
an environment variable and a make variable.
A make variable is only used with the make command,
must be assigned a value on the make command line,
and comes after the command name, not
before it.
KDEB_PKGVERSION is an example of a make variable.
A Specific Example
Since I initially announced this page on the debian-user
mailing list, I have been met with mostly positive reviews.
However, I have had a number of requests for a specific example.
In particular, I have had requests for a specific example that involves
using out-of-kernel-source-tree kernel module source packages.
And the most popular example requested involves building a custom
kernel the traditional Debian way that uses the proprietary Nvidia®
graphics driver.
(I am no fan of proprietary drivers; but given the world as it is,
they are sometimes necessary.)
Given: a computer of the i386 architecture
with an Nvidia graphics
card, chipset GeForce2 MX/MX 400, running Debian Squeeze.
To accomplish: build a custom kernel from Debian
kernel sources (2.6.32) that uses the proprietary
"nvidia" X driver.
Note: it is not necessary to build a custom kernel
in order to use the nvidia driver.
There are other installation methods available that will allow
the nvidia driver to be
used with an official stock Debian kernel image package.
But if you need or want to build a custom kernel for other reasons,
and you also want to use the nvidia driver, this is
the traditional Debian way to do it.
Assumptions:
- linux-image-2.6.32-5-686 is the only
installed kernel image package
- No previous attempts have been made to install the Nvidia driver the
native Nvidia way
- No previous attempts have been made to install Debian packages for
the Nvidia driver
- Sources will be unpacked in the traditional Debian location: /usr/src
- A non-root user account will be used whenever possible
- Directory /usr/src is owned by user root, group src
- /usr/src has the attributes drwxrwsr-x
(note the "set-group-ID" attribute)
- Non-root user account "steve" will be used for the non-root steps
- User "steve" is a member of group src,
as reported by the "groups" command
- The /etc/apt/sources.list file is up-to-date for Squeeze and contains
"main", "non-free", and "contrib" sections
- The package management system's list of available packages
is up-to-date
- All pending updates have been applied,
and the distribution is current
- All necessary hook scripts have already been installed,
and the kernel installation environment has been fully customized
- You are logged in via a full-screen terminal
The first step is to determine which kernel module source package you
need.
At the time of this writing
there are four nvidia kernel module source packages:
nvidia-kernel-legacy-71xx-source,
nvidia-kernel-legacy-96xx-source,
nvidia-kernel-legacy-173xx-source,
and nvidia-kernel-source.
These packages are listed from oldest to newest.
Immediately you might be thinking, "Why not always use
the newest package?"
That's a good thought.
The problem is that Nvidia periodically drops support for older
chipsets from their drivers;
so the newest driver may not support your chipset.
That's why the legacy driver packages exist.
You want to use the newest driver package that supports your chipset.
Follow the links above for web pages which describe each package
and the chipsets they support.
Note: if you don't know which chipset your Nvidia
graphics card uses, the easiest way to find out is to use the
lspci command.
For example:
lspci|grep VGA
My first attempt at this was on a computer which has an Nvidia graphics
card with a RIVA TNT2 chipset, which requires the
nvidia-kernel-legacy-71xx-source
kernel module source package.
I got the kernel module source package installed
and the binary package built,
but when it came time to
install the corresponding user-space package,
nvidia-glx-legacy-71xx, I got a nasty surprise:
this user-space driver has not been updated to support the version
of the X server which runs under Squeeze!
Attempting to install it under Squeeze caused aptitude to ask me if I
wanted to de-install all of my xorg-* packages!
This is not Debian's fault.
At the time of this writing Nvidia itself has not updated this legacy
driver to support the newer release of the X server; and the last
I heard, they had no plans to do so.
So if your chipset requires the 71xx legacy driver, and if you want to
use it on Squeeze, you're presently out of luck.
You might be able to get it to work with Lenny, but not with
Squeeze.
My second attempt, which is documented here, was on a computer which
has an Nvidia graphics card with a GeForce2 MX/MX 400 chipset,
which requires the nvidia-kernel-legacy-96xx-source
kernel module source package.
The corresponding user-space package,
nvidia-glx-legacy-96xx,
has been updated to support the release of the X server which runs under
Squeeze.
OK, now let's get started.
We assume that the login shell belongs to steve.
$ su
# aptitude install linux-source-2.6.32
# aptitude install kernel-package
# aptitude install libncurses5-dev zlib1g-dev
# aptitude -R install nvidia-kernel-legacy-96xx-source
# vi /etc/kernel-pkg.conf
.
. (change maintainer's name and e-mail address)
.
ZZ
# exit
$ cd /usr/src
$ tar -xjf linux-source-2.6.32.tar.bz2
$ rm linux-source-2.6.32.tar.bz2
$ tar -xjf nvidia-kernel-legacy-96xx-source.tar.bz2
$ rm nvidia-kernel-legacy-96xx-source.tar.bz2
$ cd linux-source-2.6.32
$ cp /boot/config-2.6.32-5-686 .config
$ make menuconfig
$ make-kpkg --append-to-version -5custom01-686 \
> --revision 2.6.32-46 --initrd --rootcmd fakeroot \
> kernel_image modules_image
(The "-R" option of aptitude is used when installing
nvidia-kernel-legacy-96xx-source to avoid the
installation of nvidia-kernel-common.
It seems best to me to avoid installing this package until
the kernel module image package has been successfully built.)
As issued above, make-kpkg will compile the
kernel source package and all the installed
out-of-kernel-source-tree kernel module source packages
and build binary Debian package files for them.
If you wish to specify which of the installed kernel module source
packages to build, use the --added-modules option of
make-kpkg.
The --added-modules option value is a comma-separated
list of directory names under /usr/src/modules which
make-kpkg will examine.
(If your source code is not under /usr/src/modules, as it is in this
example, use the environment variable MODULE_LOC
to tell make-kpkg where to look for it.)
By default, all directories under /usr/src/modules
(or the value of the environment variable MODULE_LOC, if specified)
are examined if
the --added-modules option is omitted and
a modules_* target is present.
Note that the directory name does not necessarily match the package
name; so be sure to use the directory name(s).
In the specific case of the nvidia-kernel-legacy-96xx-source
package, the corresponding directory name is
nvidia-kernel-legacy-96xx; thus the option to build only
this kernel module package would be
--added-modules nvidia-kernel-legacy-96xx
It is possible to build the module packages separately,
but the kernel package
must be built first.
Otherwise, you will get errors involving "genksyms not found",
or something like that.
If you build the module package(s) separately, make sure to use the
same --append-to-version and --revision
options each time.
Note that the --initrd option only has meaning
when building a kernel image package; so you can omit it when
building only module image packages.
Similarly, the --added-modules option and the
MODULE_LOC environment variable only have meaning when building
module image packages; so you can omit them when building only
a kernel image package.
Note that you do not need to build or install kernel headers packages
when using this installation method.
They are not needed because you have the kernel source package installed,
and the kernel headers are included as part of the kernel source.
Also, avoid installing packages such as module-assistant,
dkms, or nvidia-kernel-legacy-96xx-dkms.
Deinstall them if you can; and if they aren't installed,
don't install them.
Continuing on ...
$ cd ..
$ su
# dpkg -i linux-image-2.6.32-5custom01-686_2.6.32-46_i386.deb
# aptitude install nvidia-kernel-common
# dpkg -i nvidia-kernel-legacy-96xx-2.6.32-5custom01-686_96.43.18-2+2.6.32-46_i386.deb
It is important to install both the custom kernel image package
and nvidia-kernel-common before installing the
module image package, since the module image package recommends
the former and depends on the latter.
Now we are ready to install the user-space package:
# aptitude install nvidia-glx-legacy-96xx
# aptitude clean
This package (nvidia-glx-legacy-96xx) has a dependency on
nvidia-kernel-96.43.18,
which is a virtual package provided by the module image package,
nvidia-kernel-legacy-96xx-2.6.32-5custom01-686,
which you just installed.
That's why we couldn't install it earlier.
Make sure that the glx package you install corresponds to
the kernel module source package that you used.
(For example, if you built a module image package from the
legacy-96xx kernel module source package,
you also need to install
the legacy-96xx glx package.)
The "aptitude clean" command cleans up the package
cache after installing all these new packages.
Now make a backup copy of your existing /etc/X11/xorg.conf file,
if you have one, and create a new one that looks like this:
Section "Device"
Identifier "Configured Video Device"
Driver "nvidia"
EndSection
You can tweak it later if you like, but right now we just want
to make sure that the nvidia driver gets loaded.
Now enroll in the "video" group all non-root users
on the system that might
possibly start or use the X server, if they aren't
already enrolled.
For example:
# adduser steve video
# adduser candy video
Now shutdown and reboot.
It should work.
For help with troubleshooting, see
this link.
After rebooting, you might want to consider purging the stock kernel,
since your system now depends on the nvidia kernel
module, which doesn't exist in the stock kernel.
You may also delete the package files (.deb files) that you
created in /usr/src, now that they have been installed.
Another Specific Example
This example illustrates how to use out-of-kernel-source-tree
kernel module source packages which are not designed for use
with kernel-package and make them work anyway.
In this example, we desire to use the proprietary kernel module
for the Smart Link Audio Modem Riser card (slamr).
The corresponding out-of-kernel-source-tree kernel module source
package is sl-modem-source.
This package is designed for use only with dkms,
and there is no alternate package designed to work with
kernel-package.
That's not nice!
Note: As previously mentioned,
sl-modem-source has been renamed to
sl-modem-dkms in Wheezy.
sl-modem-source still exists in Wheezy as a dummy transitional
package to bring in sl-modem-dkms.
All the assumptions for the previous specific example
(except those involving Nvidia hardware and software)
are repeated here.
We add the additional assumption that you have already verified
that you have an internal modem physically installed
and recognized by lspci or lsusb that is supported
by this driver.
(This package also supports certain USB modems as well.)
We also add the assumption that no previous attempts have been
made to install this driver, either through Debian packages
or using native upstream installation methods.
The first thing we need to do is to disable the ALSA drivers
that want to take control of this modem.
Login as root, switch to directory /etc/modprobe.d, and
create a file called local.conf.
The contents should look like this:
blacklist snd_intel8x0m
Now, rebuild the initial RAM file system image file
for the running kernel, then shutdown and reboot.
# update-initramfs -uk $(uname -r)
# shutdown -r now;exit
(The "$(uname -r)" substitutes the version name of the currently-running
kernel.
In this case, it would be 2.6.32-5-686.)
After the reboot, login as a normal user and verify that snd_intel8x0m
is no longer loaded.
$ lsmod|grep snd_intel8x0m
OK, now it's time to install some stuff
$ su
# aptitude install linux-source-2.6.32
# aptitude install kernel-package
# aptitude install libncurses5-dev zlib1g-dev
# vi /etc/kernel-pkg.conf
.
. (change maintainer's name and e-mail address)
.
ZZ
# exit
$ cd /usr/src
$ tar -xjf linux-source-2.6.32.tar.bz2
$ rm linux-source-2.6.32.tar.bz2
$ cd linux-source-2.6.32
$ cp /boot/config-2.6.32-5-686 .config
$ make menuconfig
$ fakeroot make-kpkg --append-to-version -5custom01-686 \
> --revision 2.6.32-46 --initrd kernel_image kernel_headers
Note that since the kernel_headers target is specified the entire
make-kpkg command must be run under fakeroot and
the "--rootcmd fakeroot" option must be omitted.
$ cd ..
$ su
# dpkg -i linux-headers-2.6.32-5custom01-686_2.6.32-46_i386.deb
# dpkg -i linux-image-2.6.32-5custom01-686_2.6.32-46_i386.deb
# shutdown -r now;exit
You should now be running your new kernel.
Login again as a normal user.
$ su
# aptitude install dkms
# aptitude install sl-modem-source sl-modem-daemon
# aptitude clean
dkms should automatically build the slamr and slusb
kernel modules for the running kernel during installation
of the sl-modem-source package.
The "aptitude clean" command cleans up the package
cache after installing all these new packages.
Now edit /etc/modprobe.d/local.conf again.
Add two more lines to blacklist slamr and slusb.
It should now look like this.
blacklist snd_intel8x0m
blacklist slamr
blacklist slusb
Why blacklist the new modules?
Because the init script will unload any driver modules it finds
for this modem, including slamr and slusb, then it will load slamr
or slusb.
So why load the appropriate module twice?
Blacklist it and it will only be loaded once.
(Remember, blacklisting a module only prevents udev
from loading it.
That is due to the fact that
when udev attempts to load a module, it uses the
"-b" option of the modprobe command.
But the module can still be loaded by issuing the modprobe command
without the "-b" option, as the init script does.)
Save the file and exit the editor.
Now update the initial RAM file system, shutdown, and reboot,
as illustrated below.
# update-initramfs -uk $(uname -r)
# shutdown -r now;exit
(This time, "$(uname -r)" substitutes as "2.6.32-5custom01-686",
since you are now running your new custom kernel.)
Upon reboot, the modem drivers should be fully functional.
Of course, to actually use the modem, you must install
some type of user space package to access it, such as
minicom, ppp, etc.
Use device name /dev/ttySL0 to access the modem using these programs,
rather than a traditional serial port device name (/dev/ttyS0,
/dev/ttyS1, etc.).
You might want to consider purging the original stock kernel
at this point, since your system now depends on the slamr or
slusb kernel module, which doesn't exist in the stock kernel.
You may also delete the package files (.deb files) that you
created in /usr/src, now that they have been installed.
Conclusion
Happy Kerneling!
If anyone has any comments, suggestions, complaints, corrections,
or any other form of feedback, please drop me a line at
zlinuxman@wowway.com.
Return to my home page