Compiling Linux Kernel for the Plug Computer
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.
- 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.
- Download and extract the crosscompiler
- Go to the kernel directory
- Create the default config file
- Configure our kernel
- Compile the kernel
- Copy the uImage to our ~
- Build modules
user $ tar -xjvf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
# replace ~/orion.git with the directory where the kernel is extracted user $ cd ~/orion.git
user $ make ARCH=arm kirkwood_defconfig
user $ make ARCH=arm menuconfig
# (Replace 4 by the number of your processors) user $ make -j4 ARCH=arm CROSS_COMPILE=~/tmp/arm-2009q1/bin/arm-none-gnueabi- uImage
user $ cp arch/arm/boot/uImage ~
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:
- http://plugcomputer.org/plugforum/index.php?topic=1722.0
- http://plugcomputer.org/plugforum/index.php?topic=1669.0
- http://plugcomputer.org/plugforum/index.php?topic=1698.0
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.