Here we show how to generate a minimal root filesystem fairly quickly with BusyBox, for the i.MX6 sabre sd platform.
This document assumes you are able to boot a Linux kernel on your platform already. See this post for details on how to do it. This implies you already have a "working" Linux development environment with some ARM cross-compilers at hand (e.g. Debian + Emdebian).
busybox is so small that we will go for a ramdisk as our main root filesystem.
We will use git to fetch busybox sources:
$ git clone git://git.busybox.net/busybox
This should create a busybox directory with all the latest sources.
Note that for more stability you might want to checkout a release instead of the latest version; to do so, list the available release tags with e.g. git tag -l, and git checkout <the-desired-tag>.
Assuming your cross compiler is called e.g. arm-linux-gnueabihf-gcc, you can compile by doing:
$ cd busybox
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
$ make defconfig
$ sed -i.orig 's/^#.*CONFIG_STATIC.*/CONFIG_STATIC=y/' .config
$ make
$ make install
This should create an _install folder hierarchy containing binaries and links. Note that we force the build of a static binary with the sed command.
We need to add some more configuration into the _install folder before we can call it a minimal filesystem.
We need to create some mountpoints and folders:
$ mkdir _install/dev
$ mkdir _install/proc
$ mkdir _install/sys
$ mkdir -p _install/etc/init.d
We need to prepare the main init configuration file, _install/etc/inittab, with this contents:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
This is very close to the default behavior busybox init has with no inittab file. It just suppresses some warnings about missing tty.
We need to add some more configuration to mount a few filesystems at boot for convenience. This is done with an _install/etc/fstab file containing:
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devtmpfs /dev devtmpfs defaults 0 0
We also need to actually trigger the mount in the _install/etc/init.d/rcS script, which is called from the inittab. It should contain:
#!/bin/sh
mount -a
And we need to make it executable:
$ chmod +x _install/etc/init.d/rcS
Now that we have adapted the root filesystem contents, we can generate a busybox ramdisk image for u-boot with the following commands:
$ (cd _install ; find |cpio -o -H newc |gzip -c > ../initramfs.cpio.gz)
$ mkimage -A arm -T ramdisk -d initramfs.cpio.gz uInitrd
This results in a uInitrd file, suitable for u-boot.
The default u-boot commands are not sufficient to boot our system, so we need to edit a boot.txt file with the following contents:
run loaduimage
run loadfdt
setenv rdaddr 0x13000000
fatload mmc ${mmcdev}:$mmcpart $rdaddr uInitrd
setenv bootargs console=${console},${baudrate} rdinit=/sbin/init
bootm $loadaddr $rdaddr $fdt_addr
Then we generate a boot.scr script, which can be loaded by u-boot with:
$ mkimage -A arm -T script -d boot.txt boot.scr
Assuming you have prepared your SD card with u-boot and Linux as explained in this post, you have a single FAT partition on your card with your kernel and dtb. Our boot script and ramdisk image should be copied alongside:
$ mount /dev/<your-sd-card-first-partition> /mnt
$ cp uInitrd boot.scr /mnt/
$ umount /mnt
Your SD card first partition is typically something in /dev/sd<X>1 or /dev/mmcblk<X>p1. Note that you need write permissions on the SD card for the command to succeed, so you might need to su - as root, or use sudo, or do achmod a+w as root on the SD card device node to grant permissions to users.
Your SD card is ready for booting. Insert it in the SD card slot of your i.MX6 sabre sd platform, connect to the USB to UART port with a serial terminal set to 115200 baud, no parity, 8bit data and power up the platform. Your busybox system should boot to a prompt:
...
Freeing unused kernel memory: 292K (806d5000 - 8071e000)
Please press Enter to activate this console.
After pressing enter you should have a functional busybox shell on the target.
Enjoy!