Wednesday, May 18, 2011

How to use an SD card as the root file system

How to use an SD card as the root file system (Source URL: http://www.plugcomputer.org/plugwiki/index.php/SD_Card_As_Root_File_System)

This is the procedure I followed in order to use an SD card, rather than the internal NAND flash, as the root file system. My reasons to do this are in order to have a bigger root FS (I’m using 8GB), in order to avoid hammering the internal flash & wearing it out, & to make it effortless to make duplicate plugs, by simply by duplicating the SD card. It moreover seems to run quite a bit faster, though I haven’t measured anything.

I did this with a very early sheevaPlug, running u-boot 1.1.4, & the built-in debian/ubuntu.
How to test the read & write speed of your SD card

Type in the following command to write a file to the SD card that is 1GB big.

>dd bs=1024 count=1M if=/dev/zero of=/path/to/sdcard/speedtest.txt

if you want a smaller file like 50MB to be written then just alter it to

>dd bs=1024 count=50K if=/dev/zero of=/path/to/sdcard/speedtest.txt

count determines the size of the file you are going to write.

After the command is finished it should print out the write speed like this (mine is very slow by the way)

>892108+0 records in>892108+0 records out>104857600 bytes (105 MB) copied, 48.0403 s, 2.2 MB/s

To test the read speed run this command on the file you just created

>dd if=/mnt/sdcard/speedtest.txt of=/dev/null

It should donate you a print out like this

>204800+0 records in>204800+0 records out>104857600 bytes (105 MB) copied, 0.857745 s, 122 MB/s

Now you will know if your SD card is swift enough to run a file system from.
Create a bootable file system on the SD card

The first step is to make a bootable file system on the SD card. Insert the card into the slot of a running plug. Enter the following commands:

>fdisk /dev/mmcblk0	press "o"  / delete the existing (FAT) partition table	press "n"  / create a new partition	press "p"  / it's a primary partition	press "1"  / partition #1	press enter / default first cylinder	press enter / default last cylinder	press "a"  / set the boot flag	press "1" / ... for partition #1	press "w" / save changes	>mkfs -t ext2 (or ext3, if you wish) /dev/mmcblk0p1>mkdir /mnt/sdcard>mount /dev/mmcblk0p1 /mnt/sdcard>df

You’ve now received an empty file system mounted on /mnt/sdcard. The df that you just typed should show you something like the following. Note the last line, which is the new SD file system. This one is an 8GB card, & because it’s an ext3 journaling file system, a bunch of it is already set aside for directories, journals & such.

Filesystem           1K-blocks      Used Available Use% Mounted onrootfs                  519168    185612    333556  36% /tmpfs                   257816         0    257816   0% /lib/init/rwvarrun                  257816       260    257556   1% /var/runvarlock                 257816         0    257816   0% /var/lockudev                    257816        12    257804   1% /devtmpfs                   257816         0    257816   0% /dev/shmtmpfs                   257816     21824    235992   9% /var/cache/apt/dev/mmcblk0p1         7707056    148400   7167156   3% /mnt/sdcard

Now copy your existing nand file system onto the sd card. The second cp of /dev is required because the first cp doesn’t populate the new /dev directory. The first cp takes 10–15 minutes, so relax for a bit.

If you are like me, & you want to see that there is something going on, add a “v” to the commands below, if not, exclude it.

>cp -axv / /mnt/sdcard # takes 13 minutes>cp -av /dev /mnt/sdcard

The SD card should now mirror your internal nand flash, which you can confirm with df -h, etc. On my system, df -h now shows:

Filesystem           1K-blocks      Used Available Use% Mounted onrootfs                  519168    185612    333556  36% /tmpfs                   257816         0    257816   0% /lib/init/rwvarrun                  257816       260    257556   1% /var/runvarlock                 257816         0    257816   0% /var/lockudev                    257816        12    257804   1% /devtmpfs                   257816         0    257816   0% /dev/shmtmpfs                   257816     21824    235992   9% /var/cache/apt/dev/mmcblk0p1         7707056    516216   6799340   8% /mnt/sdcard

Congrats, your SD card now has a bootable system. The next step is to boot it.
Booting from the SD Card

You need to interact with u-boot now. You must do this from a program talking to the usb-serial port, not from an ssh shell (duh). I use minicom, from an ubuntu system.

>shutdown -r now

When u-boot appears, stop it by typing ENTER a few times, to stop it from booting automatically.

Marvell>> printenv bootargsbootargs=console=ttyS0,115200 mtdparts=nand_mtd:0x400000@0x100000(uImage),0x1fb00000@0x500000(rootfs) rw root=/dev/mtdblock1 rw ip=10.4.50.4:10.4.50.5:10.4.50.5:255.255.255.0:DB88FXX81:eth0:none

This is the line that you’ll need to change. Copy everything after the first “=”, & paste it into a text editor. Edit the line to alter “root=/dev/mtdblock1” to “root=/dev/mmcblk0p1”. Optionally, you can moreover obtain rid of the mtdparts stuff. So, the new line (at least on my plug) is

console=ttyS0,115200 root=/dev/mmcblk0p1 rw ip=10.4.50.4:10.4.50.5:10.4.50.5:255.255.255.0:DB88FXX81:eth0:none

Add, at the beginning of the line “setenv bootargs”. The line is now:

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p1 rw ip=10.4.50.4:10.4.50.5:10.4.50.5:255.255.255.0:DB88FXX81:eth0:none

Copy it. Paste that line into u-boot as a command, then proceed as follows:

Marvell>> setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p1 rw ip=10.4.50.4:10.4.50.5:10.4.50.5:255.255.255.0:DB88FXX81:eth0:noneMarvell>> printenv bootargs (if you like, just to confirm that you did it right)Marvell>> boot

With any luck, the system will now boot. If you watch the boot text scrolling by, you should see something like this. If you formatted with ext2 instead of ext3, it will be different of course.

EXT3 FS on mmcblk0p1, internal journalEXT3-fs: mounted filesystem with ordered data mode.VFS: Mounted root (ext3 filesystem).

When the system comes up, log in & type “df”. You should see something like this, with a much bigger root fs than you had before.

> dfFilesystem           1K-blocks      Used Available Use% Mounted onrootfs                 7707056    516388   6799168   8% /tmpfs                   257816         0    257816   0% /lib/init/rwvarrun                  257816       260    257556   1% /var/runvarlock                 257816         0    257816   0% /var/lockudev                    257816        12    257804   1% /devtmpfs                   257816         0    257816   0% /dev/shmtmpfs                   257816         0    257816   0% /var/cache/apt/dev/mtdblock2          521216    202120    319096  39% /mnt/nand

Note that on this display, the rootfs is the new SD file system, & is much bigger. The last line is the internal nand flash. You won’t see that unless you mount it, as follows. The -r on the mount command mounts the nand read-only. Leave it off, if you like.

mkdir /mnt/nandmount -r /dev/mtdblock2 /mnt/nand -t jffs2	 # takes 1–2 minutes

Write u-boot environment to flash if desired.

The changes you made to the boot environment (setenv) don’t persist across a reboot. You’ll need to do that every time, unless you explicitly write your changes to internal flash. You do so by inserting “saveenv” after the setenv.

Marvell>> setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p1 rw ip=10.4.50.4:10.4.50.5:10.4.50.5:255.255.255.0:DB88FXX81:eth0:noneMarvell>> printenv bootargs (if you like, just to confirm that you did it right)Marvell>> saveenvMarvell>> boot

I DON’T suggest you do this the first time. Try it first and, if it works, reboot with the saveenv. Once you’ve done this, it will automatically boot from the SD card after a power-up, reboot, or reset.
Changes for Alpha6 Beta

This tutorial doesn’t quite work out of the box for the Alpha6 system. Namely, the printenv bootargs will not work, & will say variable not found. Instead you can see:

 printenv bootargs_root bootargs_root=ubi.mtd=1 root=ubi0:rootfs rootfstype=ubifs

it seems to work for me if you alter this bootargs_root variable to be the following:

 setenv bootargs_root root=b301

This seems to work- for more information see the thread at: http://plugcomputer.org/plugforum/index.php?topic=591.0

Ensure that you power cycle (at the wall) to ensure that the configuration works. Should you end up with a message like this:

VFS: Cannot open root device “b301” or unknown-block(179,1)
Please append a correct “root=” boot option; here are the available partitions:

 1f00            4096 mtdblock0 (driver?) 1f01          519168 mtdblock1 (driver?) Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,1) [] (unwind_backtrace+0x0/0xe0) from [] (panic+0x50/0x120) [] (panic+0x50/0x120) from [] (mount_block_root+0x1d4/0x214) [] (mount_block_root+0x1d4/0x214) from [] (prepare_namespace+0x16c/0x1c4) [] (prepare_namespace+0x16c/0x1c4) from [] (kernel_init+0xc0/0xec) [] (kernel_init+0xc0/0xec) from [] (do_exit+0x0/0x6ac)

Then setting the following may work around the problem:

 setenv bootcmd 'mmcinit; setenv bootargs $(bootargs_console) $(mtdpartitions) $(bootargs_root); nand read.e 0x00800000 0x00100000 0x00400000; bootm 0x00800000'

Mystery

If you just type “printenv” into u-boot, you’ll see lots of environment variables, including:

bootargs_root=root=/dev/mtdblock2 ro

or

x_bootargs_root= ....   (if you have a guruplug)

Have a look a the uboot manual .. & at the rest of the environment variables. You will find one with

.... ${x_bootargs_root} ....

wich will be replaced by the content of the x_bootargs_root variable, like in any shell ….
Where Credit is Due

As I tried to obtain this working, I returned frequently to plugforum (http://plugcomputer.org/plugforum/index.php?topic=149.0) where I received a lot of assist from karurosu, sethlans, wb6ymh & cbxbiker61. They’re smart.

No comments:

Post a Comment