Compiling Linux Kernel for the Plug Computer

From PlugWiki
Jump to: navigation, search

You can compile the kernel either directly on the plug or cross-compiling it in another machine. Since compiling on the plug takes around 50 minutes, and you maybe don't have your plug set-up already, you probably want to cross-compile it. The following instructions are aimed at GNU/Linux.

Contents

Setting up the environment

Getting the Appropriate Cross-Compiler

You can either compile your cross-compiler, or use an already built cross-compiler. The minimum requirement is that the cross-compiler should support the ARM embedded-application binary interface ("EABI")(called armel on Debian/Ubuntu). Check the following links for more info regarding the cross-compilers and feel free to add more:

  • Pre-built toolchains:
    • CodeSourcery: This cross-compiler is used by almost all developers/companies using ARM devices. However, they only provide cross-compilers that work on x86/i386.
    • Emdebian: This cross-compiler is used by Debian. Available for amd64/x86_64 and i386/x86.
  • Tools for creating cross-compilers:
    • Crosstool-ng: Builds a cross-compiler from source. Non-distribution specific.
    • Crossdev: Gentoo's cross-compiler builder. Needs Gentoo.
    • Emdebian: Emdebian also provides ways to build your own toolchain.

Getting the appropriate kernel

You can choose between two kernels: Marvell's and kernel.org. Both are the same, in fact the Marvell tree gets merged to kernel.org's tree from time to time(when stuff committed to Marvell's tree is good enough), also it gets done the other way. The first kernel.org(from now on, upstream) version that supported the SheevaPlug, was the 2.6.30_rc1 release. Therefore, this is the preferred way.

Kernel.org

The download is around 60MB and once extracted, its around 361MB.

Just download the tarball:

wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.30-rc1.tar.bz2

And extract it:

tar -xjvf linux-2.6.30-rc1.tar.bz2

Now, go to #U-Boot's mkimage

Marvell

If you prefer to use Marvell's tree, you need to either do a git clone of it, or download an snapshot and extract it. The differences are the following:

  • GIT clone: Needs around 700MB of space when extracted , and around 272MB of download data, contains the git metadata, which allows to play with the commits made to the tree, mading it easy to debug the problems appeared after a new commit.
  • Snapshot: Needs around 361MB of space when extracted, and its around 72MB of tarball download. Doesn't contain the git metadata, yet you can convert it to a git repository later.
Getting the kernel using GIT

For git cloning it, make sure you have git installed in your system, just do:

git clone git://git.marvell.com/orion.git
Getting the kernel using an snapshot

Download the tarball from the web interface of the GIT repository, just click on any "snapshot" link, it may take a while to start the download. Then just extract it

tar -zxfv FILE

You should get an orion.git directory containing the kernel tree.

U-Boot's mkimage

We also need U-Boot's mkimage binary, so we can make a kernel image that U-Boot, the bootloader of the Plug, can load. If you're cross-compiling, get mkimage from Marvell (details). If you're compiling on a plug, you need to compile mkimage; run the following commands on the plug.

user $ mkdir ~/tmp
user $ cd tmp
user $ wget ftp://ftp.denx.de/pub/u-boot/u-boot-latest.tar.bz2
user $ tar -xjvf u-boot-latest.tar.bz2
user $ cd u-boot-2010.09
user $ make tools
root # install tools/mkimage /usr/local/bin

Once its there, when we build the kernel, it'll automatically create a valid U-Boot image.

Crosscompiling the kernel

In this example we'll use the CodeSourcery toolchain.

  1. Go here, select GNU/Linux, and get the latest EABI IA32 GNU/Linux TAR from Advanced Packages. As of this posting, the lastest version is 2009q1-203, which you can also get from my mirror here.
  2. Download and extract the crosscompiler
  3. user $ tar -xjvf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
    
  4. Go to the kernel directory
  5. # replace ~/orion.git with the directory where the kernel is extracted
    user $ cd ~/orion.git
    
  6. Create the default config file
  7. user $ make ARCH=arm kirkwood_defconfig
    
  8. Configure our kernel
  9. user $ make ARCH=arm menuconfig
    
  10. Compile the kernel
  11. # (Replace 4 by the number of your processors)
    user $ make -j4 ARCH=arm CROSS_COMPILE=~/tmp/arm-2009q1/bin/arm-none-gnueabi- uImage
    
  12. Copy the uImage to our ~
  13. user $ cp arch/arm/boot/uImage ~
    
  14. Build modules
  15. user $ make -j4 ARCH=arm CROSS_COMPILE=~/tmp/arm-2009q1/bin/arm-none-gnueabi- modules
    user $ make -j4 ARCH=arm CROSS_COMPILE=~/tmp/arm-2009q1/bin/arm-none-gnueabi- INSTALL_MOD_PATH=.. modules_install
    

After everything was done successfully, you have your kernel built. If you want to modify the configuration of your kernel later on, start from the point 4, after having entered the directory where the kernel is.

Installing the kernel

Copy the uImage to the plug and burn it to flash using flash_eraseall and nandwrite (details). If you get flash errors, burn it again.

Booting the kernel

Reboot the device by pushing a paperclip into the reset hole. Using the serial console, press a key when boot starts to drop into the U-Boot console.

On the U-Boot console, you need to execute the following, otherwise your kernel won't boot:

Marvell>> setenv arcNumber 2097
Marvell>> setenv mainlineLinux yes
Marvell>> saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
Marvell>> reset

You may need to replace nand_mtd with orion_nand and add rootfstype=jffs2 in the environment.

NB: mainlineLinux must be set back to 'no' to boot the original kernel


Note for guruplugs : It seems that this fix does not work for most of us, as you can see there on the forum:

But the problem is in fact this arch number.
bdinfo will give you the "arch_number = 0x00000A29" (2601) but the vanilla AND plugcomputer sources have the other one : 2659

Two ways to fix this :

  • change the uboot to one with the right arch_number (mind you may not come back to original kernel then). Find informations about this over the wiki and the pointed threads from the forum, I did not test yet.
  • modify the file "arch/arm/tools/mach-types" in the kernel sources, to use 2601 for the guruplug (do not forget to comment out the other machine type using 2601).

I think the first version is best, but the second is more secure if you do not have a jtag board to restore a uboot image in case of problem. (though, without a jtag board, I do not see how you will recover from a problem with the kernel anyway.... maybe using tftpboot ....)

Troubleshooting

If you get the following error:

Error: unrecognized/unsupported machine ID (r1 = 0x0000020f).

Available machine support:

ID (hex)		NAME
00000690	Marvell DB-88F6281-BP Development Board
00000691	Marvell RD-88F6192-NAS Development Board
00000682	Marvell RD-88F6281 Reference Board
00000831	Marvell SheevaPlug Reference Board
0000085b	QNAP TS-119/TS-219

Please check your kernel config and/or bootloader.

Make sure you've done the #Booting the kernel step.

If it fails to boot, and the kernel panics, don't panic.

I have a newer Shivaplug, and I used the Installer for version 1.0 on it recently. I compiled and installed a new kernel, and ended up with a kernel panic on my hands. I finally looked at a dmesg I'd done earler (lucky for scrollback and having done a dmesg randomly), and saw that the kernel boot parameters were as follows:

Kernel command line: console=ttyS0,115200 mtdparts=orion_nand:0x400000@0x100000(uImage),0x1fb00000@0x500000(rootfs) ubi.mtd=1 root=ubi0:rootfs rootfstype=ubifs

I used the tftp boot method, which is described in detail here, but substituted these options for the bootargs.

Personal tools