Booting entirely off an external USB device
The simplest way of adding additional storage is to plug an external USB device into the Sheeva Plug. You can then mount the external storage as some mount point in the default filesystem. You may go a bit further and change /etc/fstab so that it mounts the external storage on startup. However, with a bit more work, you can boot the kernel and the filesystem off the external device instead. There are many advantages to doing that.
- Keep the original kernel/filesystem in NAND flash untouched as a back up.
- Mounting the external device as a mount point means that the bulk of your storage is located in a sub directory. It may be fine for the most part, but if you plan on apt-get'ting a lot of software then it can fill up the / directory quickly.
- Accessing an external hard drive is very fast, take a look at the performance numbers here.
- Updating the kernel is very easy. The boot partition is mounted at /boot like most desktop Ubuntu.
- Backup/duplicate your Sheeva Plug's filesystem is a snap. Simply plug the external storage into another computer and just tar everything up.
You can use any USB external storage device, this guide is generic enough to handle both USB flash storage or disk storage. The process of booting off the SD memory card is basically the same with the exception of the device nodes (ex. SD mounts to /dev/mmcblk0p1). You can find detail instructions on booting off a SD card here.
Prep your external storage
Boot the Sheeva plug to prompt and plug in your external storage. The Sheeva Plug should be able to recognize the device and create a new mount point on /dev/sda. Then you need to delete any old partitions on the external storage and create new ones. To do that, you use fdisk, which already exist in the default filesystem. Create 2 partions, the first holds the kernel images (/boot) and the second the filesystem(/). Right now is a good time to determine if you want a swap space. My suggestion is use swap only if you are using a disk storage. Flash base storage is slower (unless you buy the expensive models), and that you may run into the problem of wearing down the flash prematurely. As an example, here is my partition table with 3 partitions.
Command (m for help): p Disk /dev/sda: 320.0 GB, 320072933376 bytes 255 heads, 63 sectors/track, 38913 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x41ffc810 Device Boot Start End Blocks Id System /dev/sda1 1 4 32098+ 6 FAT16 /dev/sda2 5 38800 311628870 83 Linux /dev/sda3 38801 38913 907672+ 82 Linux swap / Solaris
I chose to make my swap space as sda3 because I want to be option to move the data to a flash base device. With the swap on sda3 all my mount points in fstab remains the same. Also note that sda1 is type FAT16. This is because U-Boot has a build-in fatload command to load files from a FAT base partition. U-Boot also has a ext2load as well but I have not tried it. So if you're worry about Micro$oft knocking on your door about FAT royalties, you may want to look into using ext2 instead.
After the partition tables are created, format each partition with mkfs.vfat and mkfs.ext3. You can use any other filesystem type if you wish (like ext4), but make sure that the kernel you're running has the filesystem type build into the kernel and not as a module. The default kernel has ext3 build in so that is what I used.
Problems with using vfat on /sda1
The original kernel that cames with the Sheeva Plug, as well as the default settings of the orion and mainline kernel does not have vfat support compiled into the kernel. This means that you can't use the Sheeva Plug to mount the vfat partition. Earlier I had talked about using ext2 instead of vfat to avoid Micro$oft royalties. So I decided to change my /dev/sda1 to use ext2 instead. The procedure is still the same except the partition table now looks like:
Disk /dev/sda: 320.0 GB, 320072933376 bytes 255 heads, 63 sectors/track, 38913 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x41ffc810 Device Boot Start End Blocks Id System /dev/sda1 1 4 32098+ 83 Linux /dev/sda2 5 38800 311628870 83 Linux /dev/sda3 38801 38913 907672+ 82 Linux swap / Solaris
Now instead of formating /dev/sda1 with mkfs.vfat, use mkfs.ext2.
Copy over the default kernel and filesystem
The next thing to do is to copy the original kernel and filesystem to the external storage. Make some temporary directories.
mkdir /mnt/mtdroot mkdir /mnt/sda1 mkdir /mnt/sda2
Mount the filesystems
mount /dev/mtdblock1 /mnt/mtdroot mount /dev/sda1 /mnt/sda1 mount /dev/sda2 /mnt/sda2
The first line is to mount the root filesystem (/dev/mtdblock1) from NAND flash to /dev/mtdroot. It is possible that the root filesystem is at another location other than /dev/mtdblock1. This happens if you burn a new image into the flash or by changing the default bootcmd in U-Boot. You can tell the root filesystem's mount point by with cat /proc/mtd:
$ cat /proc/mtd dev: size erasesize name mtd0: 00100000 00020000 "u-boot" mtd1: 00400000 00020000 "uImage" mtd2: 1fb00000 00020000 "root"
root is listed as mtd2. So the correct mount point in this case is /dev/mtdblock2. Therefore, change the first line of the mount instructions from
mount /dev/mtdblock1 /mnt/mtdroot
mount /dev/mtdblock2 /mnt/mtdroot
Next copy the filesystem from the NAND flash to the external storage.
cp -av /mnt/mtdroot/. /mnt/sda2
Finally, you need to copy the kernel(uImage) to /mnt/sda1. You can get a copy of the original uImage from Marvell's LSP package here. I also have just the uImage itself here, don't forget to unzip the file! Then copy the uImage to sda1.
cp uImage /mnt/sda1
Edit fstab to use sda1
You need to edit /mnt/sda2/etc/fstab so that it knows about the new location of the root filesystem. Replace the line:
rootfs / rootfs rw 0 0
with these lines:
/dev/sda2 / ext3 rw 0 0 /dev/sda1 /boot vfat rw 0 0
Here's what the fstab should look like after all the changes:
# UNCONFIGURED FSTAB FOR BASE SYSTEM tmpfs /lib/init/rw tmpfs rw,nosuid,mode=0755 0 0 /proc /proc proc rw,noexec,nosuid,nodev 0 0 sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0 varrun /var/run tmpfs rw,nosuid,mode=0755 0 0 varlock /var/lock tmpfs rw,noexec,nosuid,nodev,mode=1777 0 0 udev /dev tmpfs rw,mode=0755 0 0 tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0 devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=620 0 0 /dev/sda2 / ext3 rw 0 0 /dev/sda1 /boot vfat rw 0 0 # tmpfs /var/cache/apt tmpfs defaults,noatime
You may notice that I commented out the last line tmpfs /var/cache/apt tmpfs defaults, noatime. This is to fix the apt-get problem. The apt-get problem is explained here.
You're now done with the prep, reboot the Sheeva Plug and make the necessary changes to U-Boot.
Changes to U-Boot
You need to make changes to U-Boot so that it loads the kernel from the external devices instead of NAND flash. Connect to the serial console and reboot the Sheeva Plug. Stop the U-boot boot process by pressing any key when it prints
Hit any key to stop autoboot
You should make a backup of the boot arguments so that it is easy to go back if it doesn't work. Type the following at the Marvell prompt:
setenv bootargs_nand $(bootargs) setenv bootcmd_nand $(bootcmd) saveenv
Then, write the new arguments to boot from the external storage:
setenv bootargs 'console=ttyS0,115200 root=/dev/sda2 rootdelay=10 mtdparts=nand_mtd:0x400000@0x100000(uImage),0x1fb00000@0x500000(rootfs) rw' setenv bootcmd 'usb start; fatload usb 0:1 0x8000000 uImage.sheeva.040309; bootm 0x8000000; reset' saveenv
In the first line, the rootdelay option is there to allow the kernel to scan the USB system and create the necessary mount points. Without it, the kernel will be unable to mount the root filesystem and you will end up with a kernel panic. The value 10 depends on the speed of the scan and may have to be adjusted for your particular system.
In the second line, you may need to change uImage.sheeva.040309 to whatever name your uImage is called. Also on the second line you may notice a reset at the end. This is a hack to fix the problem with U-Boot where every other boot it is unable to properly scan the USB system if you have a disk base storage. The error is a timeout when it tries load the uImage from the first partition. The reset is there so that if it failed to get the uImage, it will reboot and try again.
If you used ext2 instead of vfat for the /dev/sda1 partition, replace the line:
setenv bootcmd 'usb start; fatload usb 0:1 0x8000000 uImage.sheeva.040309; bootm 0x8000000; reset'
setenv bootcmd 'usb start; ext2load usb 0:1 0x8000000 /uImage.sheeva.040309; bootm 0x8000000; reset'
Be careful with the forward slash "/" in front of uImage.sheeva.040309. You have to reference files in ext2 with the full pathnames. When in doubt, use the command extls to list the files in the ext2 partition.
If you are using the Orion or Mainline kernel, you will need to add the following variables to U-Boot.
setenv arcNumber 2097 setenv mainlineLinux yes saveenv
Reboot the system and the Sheeva Plug should now use the external storage as its root.
Did you find this page useful?