Linux Kernel Build

Hi there,

I was experimenting with building the Linux kernel (3.18) for the Debian (Jessie) 15.06 release. I referred to the instructions in section 7 of the Getting Started guide, and thought it might be helpful to add some clarification to a few of the steps, since a few things were unclear the first time around.

First of all, here’s the cross-compile build environment I used:

Linux acencini-GA-970A-D3 3.16.0-43-generic #58~14.04.1-Ubuntu SMP Mon Jun 22 10:21:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

The toolchain I used was the x86_64 version:


As opposed to using the i386/multiarch version. Setup was similar to the instructions on the page - added toolchain to PATH, and noted for future use elsewhere (see below).

After installing the toolchain:

git clone linux.git
cd linux.git
git checkout 96boards-hikey-15.06
git clone build_utilities.git
git clone -b hikey build_utilities.git/src/driver
git clone -b R8.5 build_utilities.git/src/fw_download
git clone -b hikey build_utilities.git/src/backports
patch -p1 < build_utilities.git/patches/hikey_patches/0001-defconfig-hikey-discard-CFG80211-and-MAC80211.patch

This was largely similar to the instructions, but is keyed to a newer build.

Perhaps the most unclear thing in the documentation was how to set up build_utilities.git/setup-env, specifically, which environment variables to set, and what to set them to. For this, I did the following:

cp build_utilities.git/setup-env.sample build_utilities.git/setup-env

Then, I set the following things within setup-env:

export TOOLCHAIN_PATH=/absolute/path/to/gcc-linaro-4.9-2014.11-x86_64_aarch64-linux-gnu/bin
export ROOTFS=/absolute/path/to/linux.git/build_utilities.git/fs
export KERNEL_PATH=/absolute/path/to/linux.git

left KERNEL_VARIANT alone. Finally:

export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

Then I went through the build process as follows:

export LOCALVERSION="-linaro-hikey"
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

Note: I modified defconfig to meet the needs of my custom kernel prior to the make above.

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8 Image modules hi6220-hikey.dtb

At this point, things compile happily.

Next, making the modules worked smoothly using the following steps (from linux.git):

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8 modules INSTALL_MOD_PATH=./build_utilities.git/fs modules_install
cd build_utilities.git
./ modules
./ firmware

In the documentation, it says to ignore warnings/errors that may occur. This was a little vague. Specifically, the warnings/errors I encountered on this build were related to a few patch failures, specifically:

acencini@acencini-GA-970A-D3:~/hikey/linux.git/build_utilities.git$ ./ modules
 Changing ROOTFS path to /home/acencini/hikey/linux.git/build_utilities.git/fs
 Using user defined kernel
Makefile was found. Kernel version was set to 3.18.0.
   *****  building only Driver modules  *****  
Copy original source files ...
Apply patches ...
Failed to apply changes from backport-adjustments/flow_dissector.patch
> patching file compat/net-core-flow_dissector.c
> Hunk #1 FAILED at 177.
> 1 out of 1 hunk FAILED -- saving rejects to file compat/net-core-flow_dissector.c.rej
Failed to apply changes from collateral-evolutions/network/85-hid_ll_driver/net_bluetooth_hidp_core.patch
> patching file net/bluetooth/hidp/core.c
> Hunk #1 succeeded at 268 with fuzz 1 (offset 45 lines).
> Hunk #2 succeeded at 353 with fuzz 2 (offset 45 lines).
> Hunk #3 FAILED at 396.
> Hunk #4 succeeded at 474 with fuzz 2 (offset 65 lines).
> Hunk #5 FAILED at 739.
> 2 out of 5 hunks FAILED -- saving rejects to file net/bluetooth/hidp/core.c.rej
Failed to apply changes from collateral-evolutions/network/86-qdisc_tx_busylock/ieee802154.patch
> patching file net/ieee802154/6lowpan.c
> Hunk #1 FAILED at 530.
> Hunk #2 FAILED at 545.
> 2 out of 2 hunks FAILED -- saving rejects to file net/ieee802154/6lowpan.c.rej

As well as a couple warnings in the compilation process later. An incorrectly configured setup_env results in other warnings/errors, so it might help to be specific about what are “ok” warnings/errors vs bad ones.

Building the firmware was smooth and successful as well.

Finally, these steps work fine:

cd build_utilities.git/fs/lib
sudo chown -R root:root *
sudo tar jcvf fw-modules.tar.bz2 * 

However, at this point, I deviated from the process to what (for me) was an easier method for propping the files into the HiKey build image:

From some staging location (e.g. home directory), I download and dd the existing 15.06 image to an SD card - this requires an SD card reader on the build box.

gzip -d -c hikey-jessie_developer_20150701-323.img.gz > /tmp/jessie.img
sudo dd bs=4M if=/tmp/jessie.img of=/dev/sdb

(Note that all partitions on the SD card should be unmounted, and the device to write to may vary from system to system).

When complete, I mounted the /boot and /rootfs partitions, and did the following:

cd /path/to/sdcard/rootfs/lib
sudo tar xvf /path/to/build_utils/fs/lib/fw-modules.tar.bz2

This drops the modules and firmware into the appropriate place on the rootfs /lib.

It should also be noted that there are two stale links that could be cleaned up (/lib/modules/3.18.0-linaro-hikey/build and /lib/modules/3.18.0-linaro-hikey/source both point to locations on the build machine - these could be removed)

While in there, I also update /etc/network/interfaces.d/wlan0 to my wifi config…

Finally, I copy over the kernel

cd /path/to/sdcard/boot
sudo cp /path/to/linux.git/arch/arm64/boot/Image .

And unmount the SD card partitions, and off we go.

TLDR: The setup_env instructions and module build details are vague, it might be easier to use x86_64 toolchain on cross-compile system, and using a mounted clean-image SD card via SD card reader may help improve the documentation on kernel building.

Anyway, that’s my $0.02. Hopefully this helps - feedback welcome, and apologies in advance for any mistakes. Thought I’d share this.

The patch errors are NOT the ones it was referring to when saying it is ok to ignore.
Did it say to ignore errors/warnings throughout? Or just during the build itself? Those patch errors happened before the build.

Usually patch errors are caused by the source of the code being patched, having diverged too far from the source the patches were based on. Basically, it means that patch can’t figure out how to apply the diff.

Once you get to the actual build, it is generally ok to ignore any warnings or errors that don’t cause it to bail out of the process. Those can mean simple things, like converting between types without a cast. Casting is effectively just you telling the compiler to shut up because you know what you’re doing. If you forget to tell the compiler to shut up, then it keeps making noise. As the language evolves, some coding conventions change, so you can have legacy code that processed perfectly well with an older compiler, setting off warnings with a new one.

Anyhow, the first thing to do is typically building the code exactly how it was originally. I.e., you obtain the same source that the patches were generated from, apply the patches, run the build, etc. This is the situation that the instructions would be describing. Once you start changing things, changing the kernel source with respect to the original, then you need to stop thinking like a robot and start thinking like a programmer, and adjust the parts that break.

From the Getting Started guide:

Please ignore any warnings/errors reported during the following steps

$ cd linux.git
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8 modules INSTALL_MOD_PATH=./build_utilities.git/fs modules_install
$ cd build_utilities.git
$ ./ modules
$ ./ firmware

The main point is it is not clear which warnings/errors to ignore…