To put the root file system of the RPi on the SD Card might decrease the lifetime of the card due:
- the offical RPi kernel misses a build-in flash aware file system:
nilfs2is only available as kernel module
f2fsare missing at all
- no initrd support → unable to use non-build-in file systems as rootfs
This might result in dramaticly reduced lifetime of the flash storage (SD card). This might be workarounded by using a read-only rootfs and create a writeable /var partition using i.e.
Another approach is to put the idea of an initrd onto the SD card and use any supported file system for the rootfs (built-in and by modules). This enables to use an usb-storage device for the rootfs, too. This article shows howto move a Raspian or Debian Wheezy installation onto an usb-storage devices using any file system supported by the stock kernel.
As the stock boot-loader and kernel does not support using an initrd we use a init partition. From with-in this partition the init of the rootfs is launched after the rootfs has been mounted.
root file system type
Choosing the right file system is not that easy. Using a log-structured file system for flash based storage might be a good choice. The only log-structed file system supported by the stock kernel is
nilfs2. This solution does not depend on any particular root file system - any file system which works as a rootfs in general should work with this approach. USB storage devices might show up under different device nodes if multiple USB storage devices are attached to a host. Therefore the file system should be identified by it’s UUID or LABEL.
The base system might be installed by
debootrap, Raspian’s prepared root file systems or Raspian’s SD card images. The package
busybox-static is required to be installed on the system. This might be done from within the running base system, from within the debootraped root file system using
qemu-user-static or by downloading and extracting the package manually.
The init partition uses a small C program as it’s own stub init process. Therefore the packages
make might be installed to fetch the sources and build the stub init process on the target’s CPU architecture.
There is a small git repository containing all stuff used to setup the
init partition. It should be cloned somewhere on the rootfs:
:::console /usr/src# git clone https://github.com/liske/rpi-initp.git Cloning into 'rpi-initp'... remote: Counting objects: 49, done. remote: Compressing objects: 100% (37/37), done. remote: Total 49 (delta 21), reused 36 (delta 12) Unpacking objects: 100% (49/49), done. Checking connectivity... done /usr/src# cd rpi-initp/ /usr/src/rpi-initp# git submodule init Submodule 'busybox' (git://busybox.net/busybox.git) registered for path 'busybox' /usr/src/rpi-initp# git submodule update Cloning into 'busybox'... remote: Counting objects: 89183, done. remote: Compressing objects: 100% (20694/20694), done. remote: Total 89183 (delta 69811), reused 86693 (delta 67954) Receiving objects: 100% (89183/89183), 21.20 MiB | 534.00 KiB/s, done. Resolving deltas: 100% (69811/69811), done. Checking connectivity... done Submodule path 'busybox': checked out 'e73f3c1d3d83699b723251f7e6a981021ce75475' /usr/src/rpi-initp# make gcc -Wall -static sinit.c -o sinit cp blkid.config busybox/.config cd busybox && make install make: Entering directory `/usr/src/rpi-initp/busybox'
The repository has the busybox git repository as a submodule. It is used to build a staticly linked
blkid binary. Debian Wheezy’s busybox version does not contain the blkid functionality - the busybox version is just to old. You might skip the busybox stuff if you have a more recent busybox version (>= 1.21) shipped with your distribution.
Moving to USB
/ onto the new storage the following steps are required (done from within the new rootfs; adjust device names as need):
create mount point for the init partition:
# mkdir /initp
mount the init partition:
# mount /dev/mmcblk0p2 /initp
move the kernel modules onto the init partition:
# mkdir /initp/lib # mv /lib/modules /initp/lib/ # ln -s ../initp/lib/modules /lib/modules
install the required files from the
/usr/src/rpi-initp# make install cp pinit-stub "/lib/init/" cp update.sh "/initp/" mkdir -p "/initp/sbin" cp pinit "/initp/sbin/" cp sinit "/initp/sbin/" cp blkid "/initp/bin/"
run update.sh (copies busybox and creates some directories)
configure the kernel cmdline (
/boot/cmdline.txton Raspberry Pi) parameters:
||device node of the init partition file system (required)|
||file system of the init partition (required)|
||device identifier (UUID or LABEL value) of the root partition (defaults to
||mount flags for the root partition (optional)|
||rpi-initp specific init (required)|
||kernel mounts rootfs r/o - should always be added (highly recommended)|
- kernel will mount the init partition
- kernel spawns init using
pinittries to discover the root partition, probing every 5 seconds, up to 12 times
pinitmounts the root partition and swaps the mountings using
/lib/init/pinit-stub, releasing all open file handles on the
/sbin/initof the root partition
- classic boot-up begins
:::console Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0 [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.6.11+ (dc4@dc4-arm-01) (gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08) ) #545 PREEMPT Fri Sep 20 23:57:55 BST 2013 [ 0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache [ 0.000000] Machine: BCM2708 [ 0.000000] cma: CMA: reserved 16 MiB at 1e000000 [ 0.000000] Memory policy: ECC disabled, Data cache writeback [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 125984 [ 0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=512 bcm2708.boardrev=0xe bcm2708.serial=0x5fa250c4 smsc95xx.macaddr=B8:27:EB:C2:70:A9 sdhci-bcm2708.emmc_clock_freq=100000000 vc_mem.mem_base=0x1fa00000 vc_mem.mem_size=0x20000000 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext3 pivot=UUID=0bbc4207-1ffe-42fd-9123-a6dh3fb2dbb3 init=/sbin/sinit televator=deadline rootwait console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 ro [..] [ 2.074588] Waiting for root device /dev/mmcblk0p2... [ 2.084590] Indeed it is in host mode hprt0 = 00021501 [ 2.227228] mmc0: read SD Status register (SSR) after 9 attempts [ 2.241644] mmc0: new high speed SDHC card at address aaaa [ 2.247846] mmcblk0: mmc0:aaaa SU08G 7.40 GiB [ 2.254515] mmcblk0: p1 p2 [ 2.303515] EXT4-fs (mmcblk0p2): mounting ext3 file system using the ext4 subsystem [ 2.324482] usb 1-1: new high-speed USB device number 2 using dwc_otg [ 2.331488] Indeed it is in host mode hprt0 = 00001101 [ 2.337798] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) [ 2.354459] VFS: Mounted root (ext3 filesystem) readonly on device 179:2. [ 2.377260] devtmpfs: mounted [ 2.380719] Freeing init memory: 132K [ 2.555226] usb 1-1: New USB device found, idVendor=0424, idProduct=9514 [ 2.563474] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0 [ 2.571712] hub 1-1:1.0: USB hub found [ 2.575654] hub 1-1:1.0: 5 ports detected Looking for rootfs UUID=0bbc4207-1ffe-42fd-9123-a6dh3fb2dbb3 (#1) rootfs is not here, yet... [ 3.002137] smsc95xx v1.0.4 [ 3.069209] smsc95xx 1-1.1:1.0: eth0: register 'smsc95xx' at usb-bcm2708_usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:c2:80:a5 [ 3.174627] usb 1-1.3: new high-speed USB device number 4 using dwc_otg [ 3.298307] usb 1-1.3: New USB device found, idVendor=2101, idProduct=8500 [ 3.305224] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 3.312528] usb 1-1.3: Product: USB2.0 Hub [ 3.316648] usb 1-1.3: Manufacturer: Action Star [ 3.322414] hub 1-1.3:1.0: USB hub found [ 3.326921] hub 1-1.3:1.0: 5 ports detected [ 3.614802] usb 1-1.3.1: new high-speed USB device number 5 using dwc_otg [ 3.718199] usb 1-1.3.1: New USB device found, idVendor=2101, idProduct=8501 [ 3.725289] usb 1-1.3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 3.732765] usb 1-1.3.1: Product: USB HID [ 3.736799] usb 1-1.3.1: Manufacturer: Action Star [ 3.746741] hid-generic 0003:2101:8501.0001: hiddev0,hidraw0: USB HID v1.11 Device [Action Star USB HID] on usb-bcm2708_usb-1.3.1/input0 [ 3.834827] usb 1-1.3.4: new high-speed USB device number 6 using dwc_otg [ 3.935893] usb 1-1.3.4: New USB device found, idVendor=12d1, idProduct=1f01 [ 3.942945] usb 1-1.3.4: New USB device strings: Mfr=2, Product=1, SerialNumber=0 [ 3.950457] usb 1-1.3.4: Product: HUAWEI Mobile [ 3.955035] usb 1-1.3.4: Manufacturer: HUAWEI [ 3.962217] scsi0 : usb-storage 1-1.3.4:1.0 [ 4.965915] scsi 0:0:0:0: CD-ROM HUAWEI Mass Storage 2.31 PQ: 0 ANSI: 2 Looking for rootfs UUID=0bbc4207-1ffe-42fd-9123-a6dh3fb2dbb3 (#2) rootfs is not here, yet... [ 9.824928] usb 1-1.3.5: new high-speed USB device number 7 using dwc_otg [ 9.925708] usb 1-1.3.5: New USB device found, idVendor=152d, idProduct=2329 [ 9.932760] usb 1-1.3.5: New USB device strings: Mfr=1, Product=2, SerialNumber=5 [ 9.940277] usb 1-1.3.5: Product: USB to ATA/ATAPI bridge [ 9.945701] usb 1-1.3.5: Manufacturer: JMicron [ 9.950144] usb 1-1.3.5: SerialNumber: C61B04728410 [ 9.956583] usb-storage 1-1.3.5:1.0: Quirks match for vid 152d pid 2329: 8020 [ 9.963864] scsi1 : usb-storage 1-1.3.5:1.0 [ 10.965477] scsi 1:0:0:0: Direct-Access INTEL SS DSA2M040G2GC 2CV1 PQ: 0 ANSI: 2 CCS [ 10.975368] sd 1:0:0:0: [sda] 78163247 512-byte logical blocks: (40.0 GB/37.2 GiB) [ 10.986142] sd 1:0:0:0: [sda] Write Protect is off [ 10.991726] sd 1:0:0:0: [sda] No Caching mode page present [ 10.997340] sd 1:0:0:0: [sda] Assuming drive cache: write through [ 11.006486] sd 1:0:0:0: [sda] No Caching mode page present [ 11.011979] sd 1:0:0:0: [sda] Assuming drive cache: write through [ 11.020104] sda: sda1 sda2 [ 11.026738] sd 1:0:0:0: [sda] No Caching mode page present [ 11.032235] sd 1:0:0:0: [sda] Assuming drive cache: write through [ 11.038365] sd 1:0:0:0: [sda] Attached SCSI disk Looking for rootfs UUID=0bbc4207-1ffe-42fd-9123-a6dh3fb2dbb3 (#3) Device found, trying to switchover... [ 12.874972] EXT4-fs: Warning: mounting with data=journal disables delayed allocation and O_DIRECT support! [ 12.908742] EXT4-fs (sda2): mounted filesystem with journalled data mode. Opts: data=journal; (null) <F8><F8>INIT: <F8>version 2.88 booting<F8>CC<85><F8>[info] Using makefile-style concurrent boot in runlevel S. [....] Starting the hotplug events dispatcher: udevd[ 14.775631] udevd: starting version 175 [ ok . [....] Synthesizing the initial hotplug events...[ ok done. [....] Waiting for /dev to be fully populated...[ ok done. [....] Activating swap...[ 18.489442] Adding 976556k swap on /dev/sda1. Priority:-1 extents:1 across:976556k [ ok done. [ 18.628833] EXT4-fs (sda2): re-mounted. Opts: (null) [....] Checking root file system...fsck from util-linux 2.20.1 rootfs: clean, 35124/2383872 files, 429225/9526009 blocks [ ok done. [ 18.959210] EXT4-fs (sda2): re-mounted. Opts: data=journal [....] Cleaning up temporary files... /tmp[ ok .