Recently, I bought a GuruPlug Plus specifically for use as a router. I wanted to use less watts than a desktop machine, but have a little more power to run applications than on my favorite commercial-router-firmware, Tomato. So when the dual-interface GuruPlugs came out, I bought one.
Lesson one: buy the JTAG board too if you are going to mess around with the kernel, or in any way render the thing unbootable. Unlike its predecessor the SheevaPlug, the GuruPlug does not have debugging built in, so you’ll need to buy the JTAG board to debug the boot process.
Lesson two: The PlugComputer wiki and forums are invaluable. I also used this guy’s notes for help with the Debian setup.
Lesson three: (as of June 2010) the factory UBoot image and the factory kernel are married. You can’t upgrade one without the doing the other. Fortunately, while you can render the plug unbootable pretty easily, it’s easy to fix. It’s much harder to turn the thing into a real brick, as long as you can follow directions and are willing to trust complete strangers on the Internet. (It’s still possible to recover from a total brick.)
Lesson four: Recovery! Factory uboot can be downloaded here ; you might want to have it around. Hook up the JTAG board (the wires can only go one way) then plug the JTAG board into your computer via USB. Open the serial console. Power on the plug. Within a few seconds, hit any key to interrupt autoboot. Type “printenv” and save these values !
Lesson five: Upgrade UBoot. The latest image can be found here. Get uboot.guruplug.bin and put it on a computer in a directory served by TFTP. I got the April 22 2010 (2010.03-01161-gd91b0a9) version when I did. On the plug, in the UBoot shell,
setenv ipaddr clientip
setenv serverip serverip
saveenv
tftp 0x6400000 <file-name>.bin
nand erase 0x0 0x100000
nand write.e 0x6400000 0x0 0x100000
reset
You’ll probably get a message about a CRC mismatch and the NAND being cleared. That’s fine, but you should reset the environment variables, specifically bootcmd. You don’t need to keep the ethernet stanzas within bootcmd on newer UBoots. Unless you keep losing your MAC addresses :).
setenv bootcmd '${x_bootcmd_usb}; ${x_bootcmd_kernel}; setenv bootargs ${x_bootargs} ${x_bootargs_root}; bootm 0x6400000;'
Lesson six: compile your new kernel. I tried 2.6.34(.1) and could not get it to work – so I went with 2.6.33.6. Download the kernel sources somewhere, for example ~/guru.
mkdir ~/guru && cd ~/guru
wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.33.6.tar.bz2
tar xjf linux-2.6.33.6.tar.bz2
Download the Marvell patches to the same place.
wget http://www.openplug.org/plugwiki/images/c/c6/Guruplug-patchset-2.6.33.2.tar.bz2
tar xjf Guruplug-patchset-2.6.33.2.tar.bz2
Apply the patches.
patch -p1 -E -d linux-2.6.33.6 < guruplug-patchset/0001-Kirkwood-Marvell-GuruPlug-support.patch
patch -p1 -E -d linux-2.6.33.6 < guruplug-patchset/0002-Driver-for-Marvell-Libertas-8688-SDIO-micr
patch -p1 -E -d linux-2.6.33.6 < guruplug-patchset/0003-Initial-defconfig.patch
Install mkimage:
aptitude install uboot-mkimage
Get a cross-compiler like CodeSourcery (which is x86 only):
wget http://www.codesourcery.com/sgpp/lite/arm/portal/package6493/public/arm-none-eabi/arm-2010q1-188-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
tar xjf arm-2010q1-188-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
cd to your kernel; make the defconfig; make any config changes you want. Set CROSS_COMPILE to the location of your cross compiler prefix.
cd linux-2.6.33.6/
make -j3 ARCH=arm CROSS_COMPILE=~/guru/arm-2010q1/bin/arm-none-eabi- guruplug_defconfig
make -j3 ARCH=arm CROSS_COMPILE=~/guru/arm-2010q1/bin/arm-none-eabi- menuconfig
Make the kernel and modules; “install” the modules one level up for later use.
make -j3 ARCH=arm CROSS_COMPILE=~/guru/arm-2010q1/bin/arm-none-eabi- uImage
make -j3 ARCH=arm CROSS_COMPILE=~/guru/arm-2010q1/bin/arm-none-eabi- modules
make -j3 ARCH=arm CROSS_COMPILE=~/guru/arm-2010q1/bin/arm-none-eabi- modules_install INSTALL_MOD_PATH=..
Make the kernel headers (this may be Debian specific).
KPKG_ARCH=armel CROSS_COMPILE=~/guru/arm-2010q1/bin/arm-none-eabi- make-kpkg --rootcmd fakeroot kernel_headers
Lesson seven: Boot your new kernel. Once compiled, the file you want is called uImage in your kernel source directory. Copy it to the TFTP folder.
cp ./arch/arm/boot/uImage /srv/tftp/uImage.2.6.33.6
At the UBoot prompt, tell it you’re booting a vanilla kernel. You may need to set it to a different number based on arch_number from “bdinfo” (it’s in hex) (eg 2097) or the version of the kernel you’re trying to boot. 2659 (A63) worked for me. (If you go back to the factory uboot/kernel, unset these.) Then boot from the kernel via tftp.
setenv mainlineLinux yes
setenv arcNumber 2659
saveenv
tftpboot 0x6400000 uImage.2.6.33.6
setenv bootargs ${x_bootargs} ${x_bootargs_root}
bootm 0x6400000
Decompression of the kernel may be instant, but you should get additional output within seconds after “done, booting the kernel.” You will get errors about modules but should eventually get to a login prompt, and the network should still work. Have it pull an address from your existing router and then transfer over the modules lib directory we made earlier, to /var/tmp. Log in locally and you should take a backup of /lib/modules and /lib/firmware. You can then just move /var/tmp/lib/modules/2.6.33.6 into /lib/modules. You should then rsync /var/tmp/lib/firmware to /lib (don’t lose /lib/firmware/mrvl!!). Run depmod -a and reboot. You’ll have to interrupt the autoboot again, and now we’re going to write the new kernel to flash since we successfully booted it last time.
tftp 0x6400000 uImage.2.6.33.6
nand erase 0x100000 0x400000
nand write.e 0x6400000 0x100000 0x400000
boot
Bam. Boot up and transfer over the kernel headers package you made earlier, and install it (may need —force-deps). That should be it: you have a new kernel on your GuruPlug. Now, I hope mine doesn’t overheat.
Comment
Commenting is closed for this article.
Setting "nofiles" ulimit to "unlimited" causes PAM to fail Performance differences between Sun T series and M series