Thursday, October 18, 2012

Compiling VirtualBox guest addition with Ubuntu mainline kernel

When compiling the guest addition of VirtualBox 4.2.0 on my system which runs Ubuntu 12.04 and mainline kernel (kernel-ppa/mainline), I encountered lots of error: unknown type name ‘uint64_t’. This happens even when all the linux-headers-* packages are already installed.

To fix these errors, the kernel headers from Ubuntu's linux-headers-* needs to be merged with the kernel source from http://kernel.org. Here're the steps.

[DISCLAIMER: please do not hold me responsible if your machine becomes unusable due to the following steps]

First, ensure that the kernel headers from kernel-ppa/mainline are installed, and they match with the running kernel.

cincai@cincai-VirtualBox:~$ uname -r
3.6.0-030600-generic
cincai@cincai-VirtualBox:~$ ls -1d /usr/src/linux-headers-* #Note: dash one d
/usr/src/linux-headers-3.6.0-030600
/usr/src/linux-headers-3.6.0-030600-generic
Before proceeding, backup those linux-headers sub-directories so that they can be restored in case bad things happen.

The next step is to download the matching kernel source. In our example, it is http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.6.tar.bz2.

Now we need to merge the Ubuntu's and kernel.org's files. Please copy the following script and saved into a file called, let's say, merge.sh.
#!/bin/bash
kversion=$(uname -r)
find /usr/src/linux-headers-$kversion -type l | xargs rm
cp -a /usr/src/linux-headers-$kversion/* /usr/src/linux-headers-${kversion%-*}
rm -fr /usr/src/linux-headers-$kversion
mv /usr/src/linux-headers-${kversion%-*} /usr/src/linux-headers-$kversion
topdir=$(tar -tjf $1 | head -1)
topdir=${topdir%/*}
tar --strip-components=1 -C /usr/src/linux-headers-$kversion -xjf $1 $topdir/arch $topdir/include

#Fix kernel version
kver=${kversion%%-*}
cat > /usr/src/linux-headers-$kversion/include/linux/version.h <<EOF
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#define LINUX_VERSION_CODE KERNEL_VERSION(${kver//\./,})
EOF

Flag merge.sh as executable, then then run it.
cincai@cincai-VirtualBox:~$ chmod u+x merge.sh
cincai@cincai-VirtualBox:~$ sudo ./merge linux-3.6.tar.bz2

If everything works, then the VirtualBox guest edition should compile cleanly.