Building Kernel for Linux Distribution

From Linux Rockchip
Jump to: navigation, search

Contents

Prepare your host distribution for cross compiling

Preparations on Ubuntu 12.04

Prerequisites

  • Ubuntu 12.04.2 LTS
  • Cross-compile toolchain. The default Ubuntu gcc-arm-linux-gnueabihf toolchain is used here:
 arm-linux-gnueabihf-gcc --version
 arm-linux-gnueabihf-gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3


The Ubuntu/Linaro toolchain on Ubuntu 12.04 will stay at this version as this is Ubuntu policy (Ubuntu rarely bumps versions) and will only have incremental updates. It's also easy to install and the resulting recovery and kernel images boot without issues. This toolchain is however not the recommended version to use for development.

Setting up the build environment

Install the necessary packages to build the kernel:

 sudo apt-get install git-core flex bison build-essential gcc-arm-linux-gnueabihf libncurses5-dev zlib1g-dev lib32z1 lib32ncurses5 sharutils lzop

If you're building on a 32-bit 12.04 installation you can omit the lib32z1 and lib32ncurses5 packages.

Preparations on Gentoo

Install some packages

Install the necessary packages to get the source code and build the kernel:

emerge git crossdev sharutils

Install the toolchain

"arm-linux-gnueabihf-gcc" on Ubuntu mean for gentoo cross development:

  • CPU Architecture: arm
  • Hardware Platform or Vendor: hardfloat
  • Operating System: linux
  • C Library: gnueabi

Now you can build the toolchain for "arm-hardfloat-linux-gnueabi":

crossdev --target arm-hardfloat-linux-gnueabi

Because there are known that some toolchain combinations not work correctly it should be checked in case of problems.

emerge -p cross-arm-hardfloat-linux-gnueabi/binutils cross-arm-hardfloat-linux-gnueabi/gcc cross-arm-hardfloat-linux-gnueabi/glibc

This is known to work:

[ebuild   R   ~] cross-arm-hardfloat-linux-gnueabi/binutils-2.23.2 
[ebuild   R   ~] cross-arm-hardfloat-linux-gnueabi/gcc-4.7.3 
[ebuild   R   ~] cross-arm-hardfloat-linux-gnueabi/glibc-2.17

Preparations for all systems

Tool to create kernel image

Hint: This is for direct boot. In case you always want dual boot, you don't need this steps - please go to the next step instead of.

To burn the kernel (zImage) to your rom kernel partition you have to create an image (kernel.img). The "rkcrc" tool will provide this feature.

Clone git repo with the rkcrc tool to create kernel images:

 git clone --depth 1 https://github.com/naobsd/rkutils

Build the rkcrc tool:

 cd rkutils
 gcc rkcrc.c -o rkcrc

Tool to create recovery image

Hint: This is for dual boot. In case you don't need dual boot, that means you want boot direct into Linux, you don't need this steps.

In order to flash the compiled kernel into the recovery partition (to be able to dual boot Android/Linux) you need the tool "mkbootimg" and an fake ramdisk.

Download image making tools:

 git clone https://github.com/olegk0/tools.git

Download ramdisk for kernel build and fake ramdisk for recovery image (dual boot):

 git clone https://github.com/Galland/rk30_linux_initramfs.git initramfs

Build the Kernel

RK3066 devices

Some preparations

You need:

  • Installed toolchain for your distribution
  • Device with a RK3066 SoC

The following instructions allow you to build kernel and recovery images that can be flashed onto RK3066 based devices like PC/TV sticks. These images are meant to be used with a Linux installation on an SD card and may need a different .config file to work with Android. These instructions have been tested with many RK3066 TV sticks/boxes (i.e. Measy U2C, MK808, MK808B, MK802III, MK802IIIS, UG80X, etc).

Other RK3066 devices may also work using this procedure as is, or with minor configuration changes (usually switching main display: LCDC0 <-> LCDC1).

Create a directory for the kernel source and a directory for the firmware and modules that will get built:

 mkdir -p $HOME/src/rk3066/mod_fw
 cd $HOME/src/rk3066

Clone git repo with kernel source tailored for RK3066 based devices:

 git clone --depth 1 https://github.com/Galland/rk3x_kernel_3.0.36.git
 cd rk3x_kernel_3.0.36/

Choose your build script

Because there are some different possibilities please read this page about kernel build scripts carefully and make your choice.

Build the kernel

With build scripts of the Option(1) and (2) now run the build:

 # From the previous step, you may probably cloned your initramfs under $HOME.
 # You may copy or make a soft link to the initramfs directory
 mv $HOME/initramfs $HOME/src/rk3066/
 # And since the build script is looking for initramfs.cpio, you may need to make a soft link pointing to the actual cpio version
 cd $HOME/src/rk3066/initramfs
 ln -s initramfs-3.0.36+.cpio initramfs.cpio
 
 cd $HOME/src/rk3066/rk3x_kernel_3.0.36
 ./build_rk3066

With the scripts of Option(3) you have to run (pay attention: names modified for rk3066):

./build_rk3066_flat.sh
./build_rk3066_modules.sh

Now the kernel is available in the directory "rk3x_kernel_3.0.36/arch/arm/boot/zImage". Also the "rk3x_kernel_3.0.36/arch/arm/boot/Image" was created ready to pack into the recovery image. Last but not least the modules were build and are located at "mod_fw" directory.

Now you have to choose your favorite boot behavior "direct boot" or "recovery boot".

Build the image to flash for "direct boot"

For "direct boot" the file kernel.img have to create with the following command line (or using the script "make_rk3066_kernelimg.sh"):

 rkutils/rkcrc -k rk3x_kernel_3.0.36/arch/arm/boot/zImage kernel.img

Then, file "kernel.img" is ready to be flashed onto kernel partition in the stick.

Build the image to flash for "dual boot"

To be able to dual boot Android/Linux you need to flash the compiled kernel into the recovery partition. The following alternative steps have to be followed:

To create the file recovery.img with the next command line (or using the script "make_rk3066_recoveryimg.sh"):

  tools/mkbootimg --kernel rk3x_kernel_3.0.36/arch/arm/boot/Image --ramdisk initramfs/fakeramdisk.gz --base 60400000 --pagesize 16384 --ramdiskaddr 62000000 -o recovery.img

Then, file "recovery.img" is ready to be flashed onto recovery partition in the stick.

RK3188 devices

This is done with the same steps and tools as RK3066, but using a RK3188 kernel source code repository, such as:

 git clone --depth 1 https://github.com/Galland/Linux3188.git rk3188_kernel_3.0.36


And then changing all folder references from "rk3x_kernel_3.0.36" to "rk3188_kernel_3.0.36".

Here is a simple script __prepare_rk3188.sh to prepare all the code and tools for the rk3188 device.

#!/bin/bash
#__prepare_rk3188.sh
#prepare all the source code

#zero: save the old config file
cp rk3188_kernel_3.0.36/.config ./my_config_`date +%y_%m_%d`


#first: get the initramfs files
git clone --depth 1 https://github.com/Galland/rk30_linux_initramfs.git initramfs

#second: get the kernel source code from galland
git clone --depth 1 https://github.com/Galland/Linux3188.git rk3188_kernel_3.0.36

##second#a get the kernel source code from linuxium
#git clone --depth 1 https://github.com/linuxium/3188-SRC-AP6210.git rk3188_kernel_3.0.36
##second#b move the kernel source to the right location (only neccessary for kernel in sub dir)
#cd rk3188_kernel_3.0.36
#mv kernel_ruikemei/* ./
#rm -rf kernel_ruikemei
#cd ../

#third: copy/unzip/rename the initramfs file to "../initramfs/initramfs.cpio" related to the kernel path
cd initramfs
cp initramfs-3.0.36+.cpio initramfs.cpio
cd ../

#fourth: get the tool to create the kernel image for direct boot
git clone --depth 1 https://github.com/naobsd/rkutils rkutils
cd rkutils
gcc rkcrc.c -o rkcrc
cd ../

#fifth: get the tool and fake ramdisk for dual boot
git clone --depth 1 https://github.com/olegk0/tools.git tools
git clone --depth 1 https://github.com/Galland/rk30_linux_initramfs.git initramfs

cd ../

Install the kernel

Read on Installing new kernel image for this topic.

Known Issues

Kernel and initramfs seems to be not matching

During bootup there is the message:

rk30xxnand_ko: version magic '3.0.36+ SMP preempt mod_unload ARMv7 ' should be '3.0.36rk31+ SMP preempt mod_unload ARMv7 '

The difference is the string "3.0.36+" and "3.0.36rk31+". This is generated from the kernel configuration (.config file) entry:

CONFIG_LOCALVERSION="rk31"

The easiest solution is to change the line to:

CONFIG_LOCALVERSION=""

or even with "make menuconfig" or script "_configure_rk3188.sh" this is located at:

General setup
..
..
(rk31) Local version - append to kernel release