Building a custom kernel

From ComputingPlugs

Jump to: navigation, search

Building a custom kernel is one of those things that looks daunting at first, but really isn't that hard after you do it a few times. It is worthwhile to learn to build a custom kernel especially for a developer kit like the Sheeva Plug because eventually, you'll need functions that are offered by the new kernel.

At lot of information I've used to build the custom kernel is from here. You may want to browse to that location if you could not find the information you need here.

Contents

Deciding on the kernel

The first thing you need to decide when building a custom kernel is which kernel you want to use. There are 3 that I know of:

  • 2.6.22.18 (Feroceon) - This is the kernel that came with the Sheeva Plug, the source and the patches comes with the development kit.
  • 2.6.30-rc1 (Orion) - This is Marvell's kernel tree and is maintained by Marvell. You get this from Marvell's GIT repository.
  • 2.6.30-rc3 (kernel.org) - This is the Linux's mainline kernel development tree. At lot of Marvell's changes have already made it to this tree. The difference between this tree and Orion is the different updates that are available. Meaning that Orion will likely see more updates/fixes that are specific to the Sheeva Plug. While the kernel.org tree will likely see updates/fixes to other parts of the kernel such as driver support some new USB gadget. I expect that when 2.6.30 is finally released, the 2 trees will merge.

Choosing between the different kernels depends on your level of comfort with running the latest and greatest. 2.6.30-rc* is still a development branch and is a kernel under test. Although the kernel should work, it is not bug free. As an example, the current Orion tree has a bug in the MMC detection where it prints out

mmc0: error -110 whilst initialising SD card

on the serial console when you plug in a SDHC memory card into the SD slot. A patch is available to fix the problem, but this illustrates the differences between a tested (Feorceon) kernel and a development kernel.

Getting the Feroceon tree

The 2.6.22.18 Feroceon tree is in the development CD that came with the Sheeva Plug. You can get it online as well here. You can get Marvell's instructions File:SheevaPlug Development Kit - Configuring the kernel with LSP for KW A0 based device-Rev1.1.pdf. Download SheevaPlug_LSP.zip from Marvell and unzip. You should then see 2 subdirectories LSP - Image and LSP - Sources. The image is the same as what was loaded in the Sheeva Plug. The sources directory contains the kernel source. The instructions from Marvell is a oddly worded, but essentially you need to untar linux-2.6.22.18.tar.bz2 and unzip linux-feroceon_4_2_7_KW.zip. Both will untar/unzip into their own directories, then, copy all the files from linux-feroceon_4_2_7_KW to linux-2.6.22.18. After that, you can follow Marvell's instructions make mrproper, make mv88f6281_defconfig and make uImage.

Getting the Orion tree

To get the Orion tree from Marvell, you'll need git. Clone the Orion repository with:

git clone git://git.marvell.com/orion.git

After a few minutes, you should see the orion directory that holds the kernel tree.

Getting the tree from kernel.org

The 2.6.30 is not yet released, the source is found under the test folder. You can use wget, which is the easiest way to get the kernel tree.

wget http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.30-rc3.tar.bz2

You can also use the git repository if you want the working copy.

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

The working copy is nice because it has snapshots of any previous released versions back to 2.6.12-rc2 and of course it has the latest, greatest, most cutting edge coded checked into mainline. If you download and build from this tree, you will end up with a 2.6.30-rc4 kernel. If you want to use the slightly less sharp version 2.6.30-rc3, type this in the linux-2.6 directory.

git checkout v2.6.30-rc3

Fixing U-Boot to load the Orion/Mainline kernel

The Current U-Boot only loads the Feroceon build kernel correctly. So if tried to boot an Orion or Mainline kernel, you will get the following error message:

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.

So if you plan to boot the Orion or Mainline kernel, you need to type the following at the U-Boot prompt.

setenv arcNumber 2097
setenv mainlineLinux yes
saveenv

You must save the environments otherwise the kernel will not boot.

Cross-compile

Cross-compiling is another one those things that sounds hard but really isn't, so don't let the term scare you. It is a lot faster to cross-compile and that's a big plus if you plan to compile a lot.

Advantages of cross-compiling:

  • Compile time is a lot faster. It takes about 5 minutes to cross-compile the kernel on a decent desktop compare to about 70 minutes on the Sheeva Plug.
  • Lots of storage. You don't have to worry about storage on the Sheeva Plug on a desktop.
  • Kernel debugging. You can't build a new kernel if the one you build doesn't boot. So you'll need to have access to the cross-compiler anyway.

Setup the cross-compiler

You can either use the cross-compiler supply on the developer CD, or download it from Marvell's website under Host Software Support Package. You can also download Code Sourcery's ARM compiler for the x86 here. Any one of them will work fine. After you download the cross-compiler you want, unzip it and put the cross-compiler and kernel tree that you got earlier in this directory structure.

/sheeva
|
+-/sheeva/orion
+-/sheeva/arm-2008q3

Your directories will be different depending on which cross-compiler/kernel. But the structure should be the same.

Getting U-Boot's mkimage

Before you can compile the kernel, you need a tool call mkimage from U-Boot so that the kernel image can be packaged into something U-Boot understands. The file is inside the U-Boot source package from Marvell, download and unzip. Copy mkimage to somewhere in your path and set the executable bit:

cp ./SheevaPlug_U-Boot/Tools/mkimage /usr/bin
chmod +x /usr/bin/mkimage

Cross-compile the kernel

Now you're ready to compile the kernel. Go to the kernel source directory (orion, in my case) and type:

make ARCH=arm kirkwood_defconfig

That will load the default kirkwood kernel config. You can then do a

make ARCH=arm menuconfig

If you want to change any settings. If you have trouble with menuconfig, it is likely you didn't install developers libraries for ncurses. So do a

apt-get install libncurses5-dev

When you're happy with the config, start the build with:

make -j4 ARCH=arm CROSS_COMPILE=../arm-2008q3/bin/arm-none-eabi- uImage

The finish product is located in /sheeva/orion/arch/arm/boot/uImage.

You'll need to build modules that goes along with this kernel, even if you didn't select any modules in the kernel config.

make -j4 ARCH=arm CROSS_COMPILE=../arm-2008q3/bin/arm-none-eabi- modules

Then install the modules into a temporary directory:

make -j4 ARCH=arm CROSS_COMPILE=../arm-2008q3/bin/arm-none-eabi- INSTALL_MOD_PATH=.. modules_install

The modules and the dependency list will be install in the /sheeva/lib directory.

Installing the kernel and modules

Copy uImage to the Sheeva Plug and burn it into the flash. If you're like me, and use a external HDD to boot the uImage, replace the old uImage with the new one. As for the modules, copy all the files under /sheeva/lib to the Sheeva Plug's /lib.

Compile locally on the Sheeva Plug

Cross-compile might be fast, but there are still some advantages to compiling locally on the Sheeva Plug.

Advantages of compiling locally

  • Everything is on the Sheeva Plug instead of a separate development computer. Keep in mind that all the cross-compile tools only run in Linux. So you'll need to build a separate Linux machine if you only have Windows. Remember, the Sheeva Plug is already a separate Linux machine, so why build another one?
  • make modules_install works like it should. Cross-compile requires you to install the modules to a separate directory and then copy it to the Sheeva Plug. It is an extra step.

Personally I have both working, but I tend to compile on the Sheeva Plug because I don't really mind the wait. I like the idea of keeping the source I used to build the kernel I'm running on the same system. That way, I could always recompile the kernel if I need to. Also, I have an external HDD as my main storage and lots of space to hold different kernel versions (in case the one I build is bad).

Setup the compiler

This is an easy one, on the Sheeva Plug, type:

apt-get install build-essential libncurses5-dev

Also download and unpack your kernel of choice.

Getting U-Boot's mkimage

This is the hard one, because you can't use the mkimage from Marvell directly. So you'll have to compile it from source. Get the Marvell U-Boot source with:

wget http://www.marvell.com/files/products/embedded_processors/developer/kirkwood/SheevaPlug_U-Boot.zip

Unpack the file, change directory to SheevaPlug_U-Boot. In this directory you should see U-Boot - Sources, you'll need to rename the sources directory so it doesn't have whites spaces in there. Otherwise the U-Boot build will fail. I renamed it to U-Boot-Sources. Go into U-Boot-Sources, unpack u-boot-1.1.4.tar.bz2 and u-boot-3.4.16.zip. Copy the contents of the u-boot-3.4.16 directory into u-boot-1.1.4 and replace the old files. Then go to the u-boot-1.1.4 directory and type:

make rd88f6281Sheevaplug_config
make tools
cp tools/mkimage /usr/local/bin

If you don't feel like going through the process of compiling your own mkimage, you can download the one I've already made here.

Compile the kernel

Once all the tools are installed, changed to the kernel source directory and compile the kernel with the follow:

make kirkwood_defconfig; make uImage; make modules; make modules_install

Copy uImage to the boot directory or burn it into the flash.



Comments:
  • Kenny Says:

    Please keep comments clean and constructive. Inappropriate comments will be removed. Thank you.

  • Greg Says:

    I cannot find the "linux-feroceon_4_2_7_KW.zip" file, where is it supposed to come from? I have extracted the SheevaPlug_LSP.tgz from both the development cd and downloaded from the marvel site. I have searched the downloads on the marvel site and am unable to find it there, either.

  • Kenny Says:

    I've just downloaded the file "SheevaPlug_LSP.zip" from Marvell. It looks like they incorporated the feroceon patch already so you don't need to merge the trees yourself. You can tell by looking at the /Sources/linux-2.6.22.18/arch/arm/ directory. You should see several directories with "feroceon" in it.

  • Jim Says:

    Hi. I built an Orion kernel because the default kernel would not connect to my 1 GigE switch. It would only connect to my Linksys router which has a 100M connection. I was hoping the Orion kernel would fix this problem for me, but it fails to mount the root file system.

    ...

    rtc-mv rtc-mv: setting system clock to 2000-01-01 16:55:59 UTC (946745759) Waiting 3sec before mounting root device... List of all partitions: 1f00 1024 mtdblock0 (driver?) 1f01 4096 mtdblock1 (driver?) 1f02 519168 mtdblock2 (driver?) No filesystem could mount root, tried: ext3 ext2 cramfs vfat msdos Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2) [] (unwind_backtrace+0x0/0xe0) from [] (panic+0x64/0x130) [] (panic+0x64/0x130) from [] (mount_block_root+0x1d4/0x214) [] (mount_block_root+0x1d4/0x214) from [] (prepare_namespace+0x128/0x180) [] (prepare_namespace+0x128/0x180) from [] (kernel_init+0xdc/0x110) [] (kernel_init+0xdc/0x110) from [] (kernel_thread_exit+0x0/0x8)

    I tried to load the old kernel via tftp:

    Marvell>> tftp

        • Warning: no boot file name; using 'C0A8C8FB.img'

    Using egiga0 device TFTP from server 192.168.200.10; our IP address is 192.168.200.251 Filename 'C0A8C8FB.img'. Load address: 0x2000000 Loading: #################################################################

            #################################################################
            #################################################################
            #################################################################
            #################################################################
            #################################################################
            ######################
    

    done Bytes transferred = 2106764 (20258c hex) Marvell>> bootm

      1. Booting image at 02000000 ...
      Image Name:   Linux-2.6.22.18
      Created:      2009-07-15  22:18:52 UTC
      Image Type:   ARM Linux Kernel Image (uncompressed)
      Data Size:    2106700 Bytes =  2 MB
      Load Address: 00008000
      Entry Point:  00008000
      Verifying Checksum ... OK
    

    OK

    Starting kernel ...

    Uncompressing Linux.................................................................................................................................... done, booti ng the kernel.


    It just hangs. I'm wondering if the Orion kernel corrupted the root flash file system? Any ideas? Thanks.

  • Astro Says:

    Jim, what's your bootargs env? Have you got "console=ttyS0,115200"?

  • Kenny Says:

    did you remember to

    setenv arcNumber 2097

    and

    setenv mainlineLinux yes

    in uboot?

  • Jim Says:

    Yes, I set the arcNumber and mainlineLinux environment. The problem was my JFFS2 was corrupted due to what I believe was caused by passing incorrect parameters for mtdparts. When my environment settings was reset to default, the mapping for the JFFS2 was different than what I had set. This corrupted the JFFS2 which seems like a bug. Anyway, I restored the file system and also updated with Development U-Boot and everything is working now.

  • jml Says:

    This is a great tutorial. I spent hours figuring this out in order to get Debian installed and booting on an external USB drive (not using the internal flash at all). Wish it had been available at the time. Keep up the great work!

  • Manic Says:

    Excellent guide and site, a huge help for us developers :P

    now that the v.1 installer has come out, which seems to be based on the Orion, is it easier to add individual modules (e.g. drivers) by modifying that or by compiling a custom kernel?

    Cheers

  • Kenny Says:

    I haven't tried the installer yet so I can't really comment on it. However I've been using the mainline kernel (from kernel.org) and it seems to work fine. Personally I think that the mainline kernel will be kept more up to date than Orion so I plan to stick with the mainline kernel. YMMV.

  • Alex Says:

    Kenny,

    Great work and a very useful site to supplement the Sheevaplug wiki.

    I would also be interested if either you or another developer could come up with an update set of instructione to use your guide in conjunction with the v1.0 installer.

    I think this combination would be a great resource for all newbies looking to compile their own kernels.

    thanks again.

  • eFfeM Says:

    Kenny, nice work.

    Jim, if you build the 2.6.22.18 kernel you should *NOT* set mainlineLinux (you can unset by typing

    setenv mainlineLinux

    in u-boot)

    FM

  • Kenny Says:

    Unfortunately I don't have plans to try out the installer unless my uboot gets corrupted because I only have 1 sheeva plug and it is running this website. It would be hard for me to take it down and mess with the installer for a week.

  • Michael Says:

    The "Getting U-Boot's mkimage" section can be updated to use the newer u-boot build as described at http://www.openplug.org/plugwiki/index.php/Das_U-boot_plug_support

  • Dennis Schafroth Says:

    Sorry a newbie to u-boot here.

    Build a new uImage using mainline (2.6.31), and copied to /boot/ together with the modules.

    Configured the uboot with the mainline settings.

    but... what do I do to load it?

    which bootargs / bootcmd is required to load a non-flashed kernel?

  • Kenny Says:

    If you're loading the kernel from somewhere else other than the flash, then you need to change the bootarg so that it loads from the new place. For example, nand is the flash, usb is a usb storage device. Take a look at the section of the wiki about booting from a usb device, that should get you started.

  • vt Says:

    http://www.marvell.com/files/products/embedded_processors/developer/kirkwood/SheevaPlug_U-Boot.zip returns 404, looking for mirrors...

Click here to leave a comment




... ...

Did you find this page useful?
Help others find this site
by linking here.

... ...
Personal tools