4.9.y Kernel Compile Guide
This board has a 4.9 LTS kernel, the source for which is on github in embeddedTS/linux-4.9.y. Compiling the kernel requires an armhf toolchain.
Preparing to Build
We recommend building in a Debian environment, whether actual system (or VM) or a Docker container. Here are the instructions for each:
Building under Debian
Builds require several tools to be present your distribution. For Debian:
WARNING: | This process may be broken for generic Debian; the commands for Ubuntu should be correct. |
su root
apt-get install curl git build-essential lzop u-boot-tools libncursesw5-dev
echo "deb http://emdebian.org/tools/debian buster main" > /etc/apt/sources.list.d/emdebian.list
curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add -
dpkg --add-architecture armhf
apt-get update
apt-get install crossbuild-essential-armhf
For Ubuntu:
sudo apt-get update
sudo apt-get install crossbuild-essential-armhf git build-essential lzop u-boot-tools libncursesw5-dev
Building under Docker
Debian only provides their cross compiler for their distribution. Our examples will set up a Docker for Debian to use for development. If using Debian 10 Buster directly, or through a VM then the docker usage can be skipped.
Create a file called "Dockerfile" with these contents:
FROM debian:buster
RUN dpkg --add-architecture armhf
RUN apt-get update && apt-get install -y \
autogen \
automake \
bash \
bc \
bison \
build-essential \
bzip2 \
ca-certificates \
ccache \
chrpath \
cpio \
curl \
diffstat \
fakeroot \
file \
flex \
gawk \
gcc-arm-linux-gnueabihf \
git \
gzip \
kmod \
libgpiod-dev:armhf \
libncursesw5-dev \
libssl-dev \
libtool \
locales \
lzop \
make \
multistrap \
ncurses-dev \
pkg-config \
python \
python3 \
python3-pip \
python3-pexpect \
qemu-user-static \
rsync \
socat \
runit \
texinfo \
u-boot-tools \
unzip \
vim \
wget \
xz-utils
# To make a more readable PS1 to show we are in the Docker
ENV debian_chroot debian_buster
RUN echo "PS1='\${debian_chroot}\\[\033[01;32m\\]@\\H\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /etc/bash.bashrc
# Set up locales. Needed by yocto.
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
In the same directory as the file named "Dockerfile" run:
docker build --tag armhf-buster-toolchain .
When this has finished the docker can be used with:
docker run --rm -it --volume $(pwd):/work armhf-buster-toolchain bash
This will map the current directory to /work.
At this point the Debian Docker is ready to compile armhf binaries. For example, create a hello world in your home folder at ~/hello.c
#include <stdio.h>
int main(){
printf("Hello World\n");
}
To compile this enter the docker with:
docker run -it --volume $(pwd):/work armhf-buster-toolchain bash
# Then from the docker:
cd /work/
arm-linux-gnueabihf-gcc hello.c -o hello
Check "file hello" to verify the binary type:
user@host:~/$ file hello hello: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=8a8cee3341d3ef76ef6796f72d5722ae9d77c8ea, not stripped
This can also be used to develop against dynamic libraries from Debian. The armhf packages can be installed in the Docker. For example, to link against curl:
# Enter the Docker:
docker run -it --volume $(pwd):/work armhf-buster-toolchain bash
cd /work/
apt-get install libcurl4-openssl-dev:armhf
# Download curl's simple.c example
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl
The "simple" binary is now built for armhf and links dynamically to curl.
This will only retain the armhf libcurl package until the docker is exited. To make the changes permanent, add the package to the Dockerfile and rerun:
docker build --tag armhf-buster-toolchain .
Compiling the Kernel
Once your build environment is prepared:
git clone https://github.com/embeddedTS/linux-4.9.y
cd linux-4.9.y
git checkout master
## If you are using the 64-bit toolchain:
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
export LOADADDR=0x80800000
make tsimx6ul_defconfig
## Make any changes in "make menuconfig" or driver modifications, then compile
make && make zImage && make modules
Installing the Kernel, Headers, or Modules
To install the headers and/or objects built above to a board, first create a tarball so you can copy it to removable media or another machine.
The following will install the kernel and modules to a temporary directory, and then pack them up in to a single tarball:
TEMPDIR=$(mktemp -d)
mkdir "${TEMPDIR}/boot/"
cp arch/arm/boot/zImage "${TEMPDIR}"/boot/zImage
cp arch/arm/boot/dts/imx6ul*ts*.dtb "${TEMPDIR}"/boot/
INSTALL_MOD_PATH="${TEMPDIR}" make modules_install
INSTALL_HDR_PATH="${TEMPDIR}" make headers_install
tar czf linux-tsimx6ul-"$(cat include/config/kernel.release)"-"$(date +"%Y%m%d")".tar.gz -C "${TEMPDIR}" .
rm -rf "${TEMPDIR}"
This will output a tarball with the kernel version and short git hash, as well as the date the tarball was created. For example: linux-tsimx6ul-v4.9.171-60-g01e2117e-20190823.tar.gz
This tarball can be directly unpacked to the root folder of a bootable media for the device. It is also possible to unpack it directly on a booted system, however we do not recommend doing so on an active deployed system without extensive testing.
# Unpack it to a mounted disk, this assumes the disk is mounted to "/mnt"
tar xf linux-tsimx6ul...tar.gz -C /mnt
# Unpack it to the root directory of a booted system
tar xf linux-tsimx6ul...tar.gz -C /
Troubleshooting
If you experience problems compiling the kernel with the compiler in your distribution, please try whichever of the below toolchains is appropriate for your architecture:
In the case of either toolchain you would run these commands to install them:
chmod a+x poky-*.sh
sudo ./poky-*.sh