linux-initcpio-tutorial

Linux initcpio tutorial

Tutorial for creating and using a Linux kernel with an initcpio initial RAM filesystem. Some notes are specific to the Gumstix Overo, but the ideia is the same for any other embedded platform.

Partitioning memory card

Create two partitions on the memory card, one small 16MB FAT16 for the boot files, the other with FAT32 for storage (logs, etc...):

# fdisk /dev/sdx Command: d (delete existing partitions) Command: n (add a new partition) Command action: p (primary partition) Partition number (1-4): 1 First cylinder (1-yyy, default 1): 1 Last cylinder (1-yyy, default yyy): +16M Command: t (change a partition's system id) Hex code: 6 (FAT16) Command: a (toggle a bootable flag) Partition number (1-4): 1 Command: n (add a new partition) Command action: p (primary partition) Partition number (1-4): 2 First cylinder (xxx-yyy, default xxx): xxx Last cylinder (xxx-yyy, default yyy): yyy Command: t (change a partition's system id) Partition number (1-4): 2 Hex code: c (W95 FAT32 LBA) Command: w (write table to disk and exit) # dd if=/dev/zero of=/dev/sdx1 bs=512 count=1 # mkdosfs /dev/sdx1 # dd if=/dev/zero of=/dev/sdx2 bs=512 count=1 # mkdosfs /dev/sdx2

Boot files

Copy the boot loader files, the Linux image and the initcpio image to the boot partition of the memory card.

Gumstix Overo

# mount -t msdos /dev/sdx1 /mnt # cp linux/overo/MLO /mnt/mlo (boot loader boot loader) # cp linux/overo/u-boot.bin /mnt (boot loader) # cp linux/overo/boot.scr /mnt (boot loader script) # cp linux/overo/uImage /mnt/uimage (Linux kernel image) # cp initcpio/overo/initcpio.img /mnt (initcpio image) # umount /mnt

After this, the memory card is ready: insert it in the Gumstix Overo and it should boot into Linux automatically.

To generate the boot.scr file, edit the boot.txt file and then run make. Here is a Makefile:

boot.scr: boot.txt mkimage -T script -C none -A arm -O linux -d $+ $@

And here is a boot.txt:

setenv bootargs mt9v032.auto_exp=0 fatload mmc 0 82000000 uImage fatload mmc 0 83000000 initcpio.img bootm 82000000 83000000

To generate the initcpio.img file, see below.

Creating initcpio image

Generate the initcpio.img file.

Gumstix Overo

Requires the gen_init_cpio program (linux/usr/gen_init_cpio.c) and the mkimage program (uboot-mkimage Debian package).

$ cd initcpio/gen_init_cpio $ make $ cd initcpio/overo $ make

Here is a Makefile for the latter:

gen_init_cpio = ../gen_init_cpio/gen_init_cpio all: $(gen_init_cpio) list | gzip -9 >initcpio.gz mkimage -T ramdisk -C gzip -A arm -O linux -d initcpio.gz initcpio.img $(RM) initcpio.gz

Description of the initcpio/ files:

    • overo/list - list of files used by gen_init_cpio to generate the initcpio image (see the gen_init_cpio.c source code for the specification of the list file)

    • overo/init - sh script run by Linux at startup

    • overo/hotplug - sh script run by Linux at run time in response to an event (module load, firmware load request, device plug in/out, etc...)

    • bin/arm - utility programs statically built for ARM processors

    • bin/all - platform-independent binary files (firmwares, etc...)

Sample list file:

dir bin 0755 0 0 file bin/ftpd ../bin/arm/ftpd 0555 0 0 file bin/gzip ../bin/arm/gzip 0555 0 0 file bin/reaper ../bin/arm/reaper 0555 0 0 file bin/rshd ../bin/arm/rshd 0555 0 0 file bin/sh ../bin/arm/uutils 0555 0 0 bin/_reboot bin/cat bin/date bin/dosfsck bin/echo bin/ifconfig bin/iwconfig bin/mount bin/nice bin/pkill bin/sleep bin/umount dir boot 0755 0 0 dir dev 0755 0 0 nod dev/mmcblk0p1 0600 0 0 b 179 1 nod dev/mmcblk0p2 0600 0 0 b 179 2 nod dev/null 0666 0 0 c 1 3 nod dev/ttyS2 0600 0 0 c 4 66 nod dev/ttyUSB0 0600 0 0 c 188 0 nod dev/video0 0600 0 0 c 81 0 file init init 0555 0 0 dir lib 0755 0 0 dir lib/firmware 0755 0 0 file lib/firmware/sd8686.bin ../bin/all/sd8686.bin 0444 0 0 file lib/firmware/sd8686_helper.bin ../bin/all/sd8686_helper.bin 0444 0 0 dir proc 0755 0 0 dir sbin 0755 0 0 file sbin/hotplug hotplug 0555 0 0 dir sys 0755 0 0

Sample init file:

#!/bin/sh exec /dev/null 2>/dev/null mount -t proc proc /proc mount -t sysfs sysfs /sys ifconfig lo 127.0.0.1 up ifconfig eth0 192.168.1.1 up rshd & nice ftpd & exec nice reaper

Sample hotplug file:

#!/bin/sh case $SUBSYSTEM in net) case $INTERFACE in wlan0) case $ACTION in add) iwconfig wlan0 essid myrouter ifconfig wlan0 192.168.2.1 up ;; remove) ifconfig wlan0 down esac esac ;; firmware) case $ACTION in add) echo 1 >/sys/$DEVPATH/loading cat /lib/firmware/$FIRMWARE >/sys/$DEVPATH/data echo 0 >/sys/$DEVPATH/loading esac esac

Running programs on the remote host

To run a program on a running Gumstix Overo, remotely from your computer, is a three step process: cross-compile the program statically, upload the program to the bin/ directory on the RAM of the Gumstix Overo, and remotely run the program with the necessary arguments if any:

$ make $ curl -sST ${program} ftp://${ipaddress}/bin/ $ rsh ${ipaddress} ${program} ${arguments}...

Requires the curl and rsh programs (curl and rsh-client Debian packages).

Cross-compiling programs statically

Gumstix Overo

The easiest way is to install the ARM cross-compiler toolchain in Ubuntu 10.10 (other versions will not work)! Install the g++-arm-linux-gnueabi package, and apt-get will automaticaly install all the dependencies packages.

Then just write a Makefile to use the arm-linux-gnueabi- toolchain. Example:

CROSS = arm-linux-gnueabi- CC = $(CROSS)gcc CXX = $(CROSS)g++ CFLAGS = -Wall -O3 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ffast-math CXXFLAGS = $(CFLAGS) LDFLAGS = -static -s

Cross-compiling OpenCV

Steps to cross-compile OpenCV and install it in OpenCV-x.y.z-install.

First create a toolchain-arm.cmake file:

SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_C_COMPILER arm-linux-gnueabi-gcc) SET(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++)

Then unpack OpenCV, cross-compile it and install it:

$ tar xjf OpenCV-2.3.0.tar.bz2 $ mkdir OpenCV-2.3.0-{build,install} $ cd OpenCV-2.3.0-build $ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-arm.cmake \ -DCMAKE_INSTALL_PREFIX=../OpenCV-2.3.0-install \ -DBUILD_SHARED_LIBS=OFF ../OpenCV-2.3.0 $ make -j2 $ make install $ cp 3rdparty/lib/liblibjasper.a ../OpenCV-2.3.0-install/lib/libjasper.a $ cp 3rdparty/lib/liblibjpeg.a ../OpenCV-2.3.0-install/lib/libjpeg.a $ cp 3rdparty/lib/liblibpng.a ../OpenCV-2.3.0-install/lib/libpng.a $ cp 3rdparty/lib/liblibtiff.a ../OpenCV-2.3.0-install/lib/libtiff.a $ cp 3rdparty/lib/libzlib.a ../OpenCV-2.3.0-install/lib/libz.a

Now, to link your programs with this cross-compiled OpenCV, you can use a Makefile like this:

OPENCV = ../OpenCV-2.3.0-install CXX = arm-linux-gnueabi-g++ CXXFLAGS = -Wall -O3 CPPFLAGS = -I$(OPENCV)/include -I$(OPENCV)/include/opencv LDFLAGS += $(OPENCV)/lib/libopencv_core.a LDFLAGS += $(OPENCV)/lib/libopencv_highgui.a LDFLAGS += $(OPENCV)/lib/libjasper.a LDFLAGS += $(OPENCV)/lib/libpng.a LDFLAGS += $(OPENCV)/lib/libtiff.a LDFLAGS += $(OPENCV)/lib/libjpeg.a LDFLAGS += $(OPENCV)/lib/libz.a LDFLAGS += -lrt -lpthread LDFLAGS += -static -s

Aug 7 2011

Andre B. Oliveira