Custom Kernel Compilation with ABS

From ArchWiki
Revision as of 11:08, 27 December 2005 by (remove spam)
Jump to: navigation, search

Due to the addition of LOCALVERSION and EXTRAVERSION variables in the kernel compilation process from 2.6.9 onwards this document has been updated and the previous version has been moved to Kernel Compilation With ABS (2.6.8 or Earlier).

This howto has been updated provide a definitive PKGBUILD for the creation of custom kernel pkgs. It allows you to maintain multiple custom kernels with a unique naming scheme under pacman version control. It is ideal for ANY custom kernel build and can be easily adapted to fit many requirements. The PKGBUILD automatically accounts for the EXTRAVERSION and LOCALVERSION variables that are now fully supported in the kernel. EXTRAVERSION is frequently set by major patchsets such as -ck and -nitro. EXTRAVERSION is also used in the 2.6.x.y branch to carry the .y variable. LOCALVERSION can be set during the config stage and is the easiest and RECOMMENDED way to customize your kernel pkgnames. Simply setting LOCALVERSION to -custom or the date e.g. -20050105 will suffice! A unique LOCALVERSION guarantees a unique pkg.

Philosophy and Logic how it works and why it works this way

  • The Arch Way - Keep It Simple.
  • This PKGBUILD builds on the previous, widely accepted version.
  • This build provides kernel packages and components with a simple, logical and uncomplicated naming scheme that ONLY uses variables that are part of the ABS system and part of the kernel compilation process itself. Rationale:
    • Stock Arch kernels use the kernel24 and kernel26 base pkgnames these are logically extended here under the 2.6.x and 2.6.x.y schemes e.g kernel2611 and kernel26117
      These also provide the basis of /boot filenames e.g. vmlinux26 and vmlinuz26117
    • The kernel compilation process uses the kernel version (2.6.x), EXTRAVERSION from the Makefile and CONFIG_LOCALVERSION from the kernel config to create the name for the kernel's module directory, e.g.:
This is beyond the control of the PKGBUILD so to provide a pkg with similarly named components the PKGBUILD uses the same scheme to create unique /boot files and a unique /usr/src directory by appending -EXTRAVERSION-LOCALVERSION, e.g.:

  • If you have the recommended knowledge of ABS you will see that the PKGBUILD is transparently constructed, self-explanatory and easily customized.
  • User input is almost identical to all ABS builds: simply set pkgver, pkgrel and pkgdesc and add additional sources, including patches, to the source array. Patch users should insert the appropriate patch commands where indicated. Aside from uncommenting the config method and choosing whether to make clean or not the rest of the build is automated.
  • Having created a custom pkg naming scheme during the build the PKGBUILD automatically corrects/updates itself with the new pkgname variable allowing simple gensync operation.


  1. This PKGBUILD is only suited to builds of the 2.6 kernel branch - an effort to make a unified or alternative PKGBUILDS for the 2.4 branch can be found here - Kernel Compilation With ABS 2.4
  2. This is NOT an ABS howto - to successfully follow this HOWTO a working knowledge of building pkgs with ABS is ESSENTIAL - please read ABS - The Arch Build System, The Arch package making HOW-TO - with guidelines and Patching in ABS

I don't advise you build a kernel for your first ABS project. If you need guidelines on how to use fakeroot or set up a build directory read the other documents first.

  1. Likewise it helps if you know how to configure a kernel! If this is your first effort building a kernel I strongly recommend you start from the default Arch config, this is detailed further below.

Usage Notes

  • The patch variable has been removed. You should now simply specify patch sources in the source array and place the patch commands as indicated. Also see Other versions
  • pkgname must be declared within 10 lines of the top of the PKGBUILD - so DO NOT move it - just leave it.

If you miss this simple instruction don't worry, it won't screw up your build but your PKGBUILD file will not have the pkgname automatically updated at the end of the build. This is to allow you to use gensync correctly BUT you can edit the PKGBUILD file manually afterwards of course.

  • Until you have your own config that you are happy with it is easiest just to start with the default Arch config; you should also get the Arch kernel26.install file. These are both in your ABS tree, normally under /var/abs/kernels/kernel26. To download the ABS tree to your system simply run abs as root. It doesn't take long, even on dialup. You should keep this updated by running abs as root on a regular basis.
  • To check if EXTRAVERSION is set by your patchset try doing
grep +EXTRAVERSION= ./patchname
and it should return something like this:
if it doesn't then EXTRAVERSION is probably not being set by your patchset and you should ensure you use LOCALVERSION to customize the pkgname.
Arch default kernels are set with the -ARCH LOCALVERSION variable - you can set anything you like e.g. -custom (note the need for the preceding dash -)
Because of these added variables there is no need to alter the pkgname manually at any point or use any other variables. The build process automatically updates the pkgname variable in the PKGBUILD file at the end of each build to reflect the final full kernel version naming scheme.
  • If used correctly this PKGBUILD should always provide a unique kernel build based on EXTRAVERSION and LOCALVERSION, and on the pkgver and pkgrel (as normal) - however it is up to the user to double check resulting pkgnames and contents before installation to prevent overwrites (see below for more details and examples).

Configuring the PKGBUILD

Copy the PKGBUILD below to your $startdir. The PKGBUILD can also be downloaded from here. Before building remember the following:

  1. pkgname can be left as it is it will automatically be set and correct itself.
  2. Insert the pkgver for your kernel (for example: 2.6.9).
  3. Change the pkgrel for your current revision. You should increment this each time you make changes to the kernel config and want to build a REPLACEMENT pkg. If you don't want to replace the previous build but rather install in parallel you should use LOCALVERSION to create a unique pkg.
  4. Change/expand the pkgdesc to describe any patches or special config options applied.
  5. Change the source to use a closer mirror, if you are using a patchset add the patches to the source array.
  6. {OPTIONAL} Place the patch commands where indicated.
  7. Choose a make method by leaving your preferred method uncommented - gconfig (gtk based) xconfig (qt based) menuconfig (ncurses based).
  8. During the build you will be asked if you want to make clean - the default is yes, reply NO if you know what you are doing.
# Contributor: dibblethewrecker <>
pkgdesc="The Linux Kernel 2.6.x.y and modules (IDE support)"

##### add any patch sources to this section
source=(config$pkgver.tar.bz2 )

# Function to grab var from src
getvar() {
  old=$(cat Makefile | grep "^$1")
  echo $(echo ${old/"$1 ="/} | sed -e "s/[ ]*\(.*\)[ ]*/\1/g")
  return 0

build() {
  cd $startdir/src/linux-$pkgver

  ##### Uncomment and apply any patches here
  #patch -Np1 -i ../patchname || return 1

  # get rid of the 'i' in i686
  carch=`echo $CARCH | sed 's|i||'`
  cat ../config | sed "s|#CARCH#|$carch|g" >./.config

  ##### Load config - uncomment your preferred config method
  #yes "" | make config
  #make oldconfig || return 1
  #make menuconfig
  #make xconfig
  make gconfig


  # save the current pkgname

  # set pkgname for build purposes - DO NOT alter!

  # save the updated config to build with today's date
  cp ./.config $startdir/config-$(date +%b%d\-%Hh)

  # get EXTRAVERSION from Makefile to create a unique pkgname and /usr/src directory
  _kernextra=$(getvar "EXTRAVERSION")
  # grab the 2.6.x.y version suffix from pkgver
  _y="`echo $pkgver | cut --delim "." --fields 4`"
  # remove .y version suffix from _kernextra
  _kernextra="`echo $_kernextra | sed "s|\.$_y||g"`"

  # Read the full kernel version info from new config to use in pathnames and pkgname
  . ./.config

  # Kernel custom - to create a unique pkgname (see below)
  # Kernel release - will be the same as Makefile
  # Get the pkgver suffix for unique pkgname and /boot file suffices
  _pkgversuf="`echo $pkgver | sed "s|2.6.||g" | sed "s|\.||g"`"
  # Set /boot file suffices from kernel release and pkgver suffix

  # Set a new pkgname from  kernel release and pkgver suffix

  # build!
  echo -n "Do you want to make clean (default YES)? (YES/NO): "
  read choice
  echo -n "Press any key to start make or CTRL+C to quit"
  read anykey

  if [ "${choice}" = "NO" ] ; then
  	make bzImage modules || return 1
	make clean bzImage modules || return 1

  mkdir -p $startdir/pkg/{lib/modules,boot}
  make INSTALL_MOD_PATH=$startdir/pkg modules_install || return 1
  cp $startdir/pkg/boot/System.map26${_kernboot}
  cp arch/i386/boot/bzImage $startdir/pkg/boot/vmlinuz26${_kernboot}
  install -D -m644 Makefile \
  install -D -m644 .config \
  install -D -m644 .config $startdir/pkg/boot/kconfig26${_kernboot}
  mkdir -p $startdir/pkg/usr/src/linux-${_kernrel}/include
  mkdir -p $startdir/pkg/usr/src/linux-${_kernrel}/arch/i386/kernel
  for i in acpi asm-generic asm-i386 config linux math-emu net pcmcia scsi video; do
    cp -a include/$i $startdir/pkg/usr/src/linux-${_kernrel}/include/
  # copy files necessary for later builds, like nvidia and vmware
  cp Module.symvers $startdir/pkg/usr/src/linux-${_kernrel}
  cp -a scripts $startdir/pkg/usr/src/linux-${_kernrel}
  mkdir -p $startdir/pkg/usr/src/linux-${_kernrel}/.tmp_versions
  cp arch/i386/Makefile $startdir/pkg/usr/src/linux-${_kernrel}/arch/i386/
  cp arch/i386/kernel/asm-offsets.s \
  # copy in Kconfig files
  for i in `find . -name "Kconfig*"`; do
    mkdir -p $startdir/pkg/usr/src/linux-${_kernrel}/`echo $i | sed 's|/Kconfig.*||'`
    cp $i $startdir/pkg/usr/src/linux-${_kernrel}/$i
  cd $startdir/pkg/usr/src/linux-${_kernrel}/include && ln -s asm-i386 asm
  chown -R root.root $startdir/pkg/usr/src/linux-${_kernrel}
  cd $startdir/pkg/lib/modules/${_kernrel} && \
    (rm -f source build; ln -sf /usr/src/linux-${_kernrel} build)

  # Correct the pkgname in our PKGBUILD - this allows correct gensync operation
  # NOTE: pkgname variable must be declared with first 10 lines of PKGBUILD!
  cd $startdir
  sed -i "1,11 s|pkgname=$old_pkgname|pkgname=$pkgname|" ./PKGBUILD
# vim:syntax=sh
  • Install your new pkg as normal.

Your config file

PLEASE NOTE: during the build the final kernel config is stored in your $startdir as, for example, config-Apr13-12h. Your original config remains in the $startdir named config. If you wish to use the new config in another build make sure you copy the correct file!

Update Bootloader

  • Remember to edit the Lilo or Grub configuration files to include an entry to the new kernel. The new kernel will install alongside any existing stock or custom kernels, so you may wish to keep a reference to your old kernel in the bootloader config file, at least until you know the new one is working. THIS IS STRONGLY RECOMMENDED!
  • If you use lilo remember to run lilo to update it.

Other versions

There several variations on this PKGBUILD available, they are all provide identical results but the mechanics are slightly different:

  • patch - includes the old patch= variable.
  • verbose - provides Package Info (like that shown above) for review before starting the make process.
  • buildstats - similar to verbose but writes more info, including build times, to a file called buildstats, which is stored in the $startdir. This can also be reviewed before starting the make process but also provides a permenant record.

I want the Arch logo!

Copy the logo_linux_clut224.ppm from /var/abs/kernels/kernel26 to your $startdir and add logo_linux_clut224.ppm to the source array. Then you need to paste the marked text (>>) into the PKGBUILD as indicated:

   ##### Uncomment and apply any patches here
   #patch -Np1 -i ../patchname || return 1

>>  ##### Arch logo - not compatible with gensplash!
>>  cp ../logo_linux_clut224.ppm drivers/video/logo/

   # get rid of the 'i' in i686
   carch=`echo $CARCH | sed 's|i||'`
   cat ../config | sed "s|#CARCH#|$carch|g" >./.config

The stock Arch config uses the following logo settings, ensure you set them at the config stage or use the stock config:

# Logo configuration

Customization and Advanced Use normal people can stop here!

Several people have successfully customized this PKGBUILD to their own needs, while others have derived a completely new approach from it. One customization recommended to people who make multiple builds of the same version for use in parallel is to add a sed command that automatically sets the CONFIG_LOCALVERSION variable in the config to a unique value before the config stage. This can based on the date, your hostname, etc. For example:

    # get rid of the 'i' in i686
    carch=`echo $CARCH | sed 's|i||'`
    cat ../config | sed "s|#CARCH#|$carch|g" >./.config

  >>  # set LOCALVERSION to -date
  >>  sed -i "s|CONFIG_LOCALVERSION=.*|CONFIG_LOCALVERSION=-`date +%y%m%d`|g" ./.config

    ##### Load config - uncomment your preferred config method
    #yes "" | make config


    # set LOCALVERSION to -date-hostname
    sed -i "s|CONFIG_LOCALVERSION=.*|CONFIG_LOCALVERSION=-`date +%y%m%d`-`hostname`|g" ./.config

For a truly unique LOCALVERSION you can set the date to seconds since 00:00:00 1970-01-01 UTC!

    sed -i "s|CONFIG_LOCALVERSION=.*|CONFIG_LOCALVERSION=-`date +%s`|g" ./.config


If you have problems with wrong package names try using the verbose PKGBUILD described in Other Versions above to see what naming scheme is being created before you commit to the build - you can quit with ctrl+c at most points before the make starts.


If you have any questions/comments/suggestions about the above PKGBUILD feel free to join the discussion at:

Some suggestions have already been incorporated but please consider the Keep It Simple philosophy and remember the original goal. Kernel compilation is a very individual process and there are a HUGE variety of ways to go about it this PKGBUILD does not even attempt to account for all eventualities, it would be fruitless to try but of course you are completely free to customize this build to your precise needs best of luck!