How to Build Kernel Modules for ATrpms

Accesses to this page since 29/06/2006: Page Visit Counter

Index


Building RPMs as a Normal User

RPMs should never be created as root. One never knows what can be copied to the system area. The easiest way is to reproduce redhat building structure in your home directory:

mkdir ~/redhat
cd ~/redhat
mkdir BUILD BUILDROOT RPMS SOURCES SPECS SRPMS tmp
cd RPMS
mkdir athlon i386 i486 i586 i686 noarch x86_64
or
yum install rpmdevtools

Then, create a file named ~/.rpmmacros, with appropriate defaults, that will tell rpmbuild which directories to use. It is also necessary to install the famous ATrpms macros. For further information, please consult the very good guide from freshrpms. The most complete document about RPMs, I am aware of, is Maximum RPM. Another useful link is the Fedora Extra Macros, and Fedora Wiki has an excellent introduction to kmdls.


Creating an RPM

To make life easier, it is better to define some aliases in your ~/.cshrc or ~/.bashrc:

# builds an rpm for i386 architecture using a spec file.
alias brpm 'rpmbuild -bb --clean --rmsource \!*'
# for building libs for nvidia or lirc.
alias brpm2 'rpmbuild -bb --clean --rmsource --define "kmdl_userland 1" \!*'
# builds an rpm for i386 architecture using a .src.rpm.
alias rrpm 'rpmbuild --rebuild \!*'
# builds an rpm for the appropriate architecture.
switch ($MACHTYPE)
case i386:
alias birpm 'rpmbuild --target i686 -bb --clean --rmsource \!*'
alias bkrpm 'rpmbuild -bp --target i686 \!*'
breaksw;
case x86_64:
alias birpm 'rpmbuild --target x86_64 -bb --clean --rmsource \!*'
alias bkrpm 'rpmbuild -bp --target x86_64 \!*'
breaksw;
endsw
# builds an rpm for the appropriate architecture defining "devices".
alias bdrpm 'birpm \!* --with devices'
# builds a kernel module for the running kernel.
alias bkmdl 'bkmdl.sh \!*'
# builds an rpm and the .src.rpm.
alias bsrpm 'rpmbuild -ba --clean --rmsource \!*'
# builds only the .src.rpm.
alias bsrc 'rpmbuild -bs --rmsource \!*'
# downloads the .src.rpm
alias gsrc 'yumdownloader --source --noplugins --destdir $HOME/temp \!*'
# gets a list of all installed kernels.
alias chkver 'rpm -q --qf "%{name}-%{version} : %{arch}\n" kernel \!*'
# extracts the contents of an rpm.
alias erpm 'rpm2cpio \!* | cpio -ivmud'
# gets all gpg public keys installed.
alias gpgk 'rpm -q gpg-pubkey --qf "%{summary} -> %{version}-%{release}\n" | sort'
# expands the definition of a macro.
alias reval 'rpm --eval "%{\!*}"'
# gets the list of all installed rpms.
alias qrpm 'rpm -qa | grep \!* | sort'
# verify the rpm database for inconsistencies.
alias vrpm '/usr/lib/rpm/rpmdb_verify /var/lib/rpm/Packages'
# updates an rpm.
alias irpm 'sudo rpm -Uvh \!*'
# forces the installation of an rpm even it is already installed.
alias frpm 'sudo rpm -Uvh --force \!*'
# checks the consistency of an rpm.
alias checkrpm 'rpm --checksig \!*'
# lists the contents of an installed rpm.
alias listrpm 'rpm -ql \!* | /bin/more'
# lists the contents of a not installed rpm.
alias lstrpm 'rpm -qlp \!* | /bin/more'

Therefore, to install an .src.rpm, it is enough to use:

rpm -ivh rpm_name.src.rpm

Then, go to ~/redhat/SPECS and do:

brpm rpm_name.spec
or
birpm rpm_name.spec (for the appropriate architecture)

The rpm should be built an stored in ~/redhat/RPMS/i386. To create an rpm from scratch, first write a spec file and put it in ~/redhat/SPECS. Second, put the .tar.gz source code in ~/redhat/SOURCES. Then, go to ~/redhat/SPECS and use:

bsrpm your_spec_file.spec

The source rpm goes to ~/redhat/SRPMS and the rpm goes to ~/redhat/RPMS/i386.


Creating a Kernel Module

To create a kernel module, it is necessary to have the kernel source devel package installed.

rpm -ivh kernel-devel-2.6.27.30-170.2.82.fc10.x86_64.rpm

The module can be created for the running kernel or another kernel installed on your system. The script bkmdl.sh receives the kernel version, the src.rpm and builds the module for the given kernel for an i686 or x86_64 architecture. The kernel version can be obtained by listing the /boot directory. Just use the part in italic vmlinuz-2.6.27.30-170.2.82.fc10.x86_64 from any vmlinuz available (remember that the kernel source devel should also be available). For the nvidia kernel module, for instance:

bkmdl.sh 2.6.27.30-170.2.82.fc10 nvidia-graphics185.18.31-185.18.31-113.src.rpm 0 1
bkmdl.sh 2.6.27.30-170.2.82.fc10 nvidia-graphics185.18.31-185.18.31-113.src.rpm

The first line above builds nvidia libs, and the second, the kernel module. The more recent versions of the nvidia .src.rpm obliges building the libs first, so a file /var/lib/nvidia/log is created. It is also necessary to set the permission of /var/lib to 777, at least the first time, if the package is not built as root.

Also, fakeroot-1.11 has to be installed on the system (more recent versions may not work), prior to building the nvidia kernel module.

It is also possible to use mock (>= 0.8.15) for building the kernel module for another architecture:
mock_kmdl.sh 2.6.23.14-107.fc8 gspcav1-1.00.20-4.src.rpm

It should be noted that the module must be built for the correct architecture (match the kernel arch): i686, x86_64, i386, PAE i686, etc. Otherwise it will not work. If everything goes right, the module should appear in ~/redhat/RPMS/i686. If there is any error during the compilation then, probably, it is necessary to have the complete source code for your kernel installed and configured.


Preparing the Kernel Source

To compile a new 2.6 kernel module, first install the kernel source:

rpm -ivh kernel-2.6.22.5-49.fc6.src.rpm

# Change the spec file (only if you need different options):
cd ~/redhat/SPECS
vi kernel-2.6.spec

# Prepare the source code for compilation:
bkrpm kernel-2.6.spec # --> (applies patches and put source in BUILD directory).
cd /usr/src
sudo ln -s ~/redhat/BUILD/kernel-2.6.22/linux-2.6.22.i686 linux # --> (not really necessary)

# Change the Makefile:
cd /usr/src/linux
vi Makefile
# --> EXTRAVERSION = .5-49.fc6

# Configure the Kernel:
cd /usr/src/linux
cp -p .config config.orig
make mrproper
cp -p /boot/config-2.6.22.5-49.fc6 .config
# choose just one option below:
make oldconfig OR xconfig OR gconfig OR menuconfig OR cloneconfig

# Compile the kernel: Can be skipped.
make bzImage
cp -p ~/redhat/BUILD/kernel-2.6.22/linux-2.6.22.i686/arch/i386/boot/bzImage /boot/vmlinuz-2.6.22.5-49.fc6
cp -p .config /boot/config-2.6.22.5-49.fc6

# Build the Modules:
cd /usr/src/linux
make prepare <---- maybe this is enough
make modules <----- this is the only part necessary for a new module.
make modules_install <----- you do not need this. Only if you want to replace everything.

# Substitute the source from the devel package: This is very important.
cd /usr/src/kernels
sudo mv 2.6.22.5-49.fc6-i686 2.6.22.5-49.fc6-i686.orig
sudo ln -s ~/redhat/BUILD/kernel-2.6.22/linux-2.6.22.i686 2.6.22.5-49.fc6-i686

Finally, you are ready to recompile your new module:

bkmdl.sh 2.6.22.5-49.fc6 lirc-0.8.3-70_cvs20070827.src.rpm


Acknowledgements

We would like to thank Axel Thimm and Matthias Saou, for keeping ATrpms and Freshrpms running for all these years, and for the hundreds of very good spec files they wrote for us.

/Paulo Roma.