2010年5月16日 星期日

Running a Buildroot System

Buildroot System for Mini2440

Startup Requirement

In my earlier write up i've showed how to Build a Root File System manually from the ground up base on the FHS, in fact there are a few system tools available to automate this building process systematically, one of this package is Buildroot.

Buildroot come with a set of Makefiles and patches to generate a cross-compilation toolchain and root filesystem using uclibc library mainly for embedded Linux system, targeted processor range from ARM, Power PC, MIPS and x86 and etc. It also help to generate system libraries and application packages simply by selecting the menu option similar to the kernel menuconfig compilation.

Here i will use Buildroot to create a basic rootfile system for mini2440, test run on it and further generate a simple madplay program to play MP3 music without worrying anything about autoconfig and compile process.

This build process require an internet access, a NFS setup environment and assume you have kernel compiled and a bootloader updated in mini2440.



Buldroot Menu Configuration

download a copy from Buildroot and open up the zip file into your home directory, a good thing about Buildroot is it doesn't need root permission to cross compile.

Create a top directory (eg. /arm/sys) where all the system output will be generated.

mkdir /arm/sys
bzip2 -dc buildroot-2010.05-rc2 | tar xvf -


or you may use git to get a download copy.

git clone //git.buildroot.net/buildroot


Change to top directory and start up the menu configuration.

cd buildroot
make menuconfig




You will see a main menu with a highlighting option display, here i will just change a few important settings below.

1) Go to 'Target Architecture' --> select arm

2) Go to 'Target Architecture Variant' --> select arm920t

3) Go to 'Target option' --> select 'System hostname' and change to mini2440, move to 'System banner' and change to Welcome to mini2440, move to 'Generic serial port config' and press space-bar to enable it.

go into 'Generic serial port config' --> select 'Serial port to run a getty on' and select ttySAC0

press 'Exit' to go back to the main menu.

4) Go to 'Toolchain' --> look for 'Enable RPC' option and enable it, move to 'Enable toolchain locale/i18n support' and enable it, move to 'Purge unwanted locales' and enable it, move to 'Locales to keep' and change to C en_US zh_TW.

press 'Exit' to go back to the main menu.

5) Go to 'Target filesystem options' --> select 'ext2 root filesystem' and disable it, move to 'jffs2 root filesystem' and enable it.

go into 'Flash Type' --> select 'NAND flash with 2kB Page and 128 kB erasesize.

press 'Exit' to go back to the main menu.

6) press 'Exit' and 'Yes' to save the configuration settings.

Note, i omit the 'Package Selection for the target' configuration until there is a working copy, i also skip many options like the uclibc C library, Binutils, gcc compiler, Busybox and etc, which Buildroot set by default which you can change to experiment as require.

At last, run the building process.

make


This will take a long time to complete, you can take a break now.

If all goes well, a directory output will be created in the top directory which contain all of the output files, a directory dl is also created consist all of the downloaded source files.

CHANGES    configs  dl    fs        output   scripts  TODO
Config.in COPYING docs Makefile package target toolchain


In the output directory, there are a few more directories.

build  host  images  staging  stamps  target  toolchain

The important one is the staging/usr/bin directory consist of the uclibc version of gcc compiler, set this entry into the search path so that future source compilation can be reference.

export PATH=/arm/sys/buildroot/output/staging/usr/bin:$PATH
arm-linux-gcc -v

使用內建 specs。
目的:arm-unknown-linux-uclibcgnueabi
配置為:/arm/sys/buildroot/output/toolchain/gcc-4.3.4/configure --prefix=/usr --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-unknown-linux-uclibcgnueabi --enable-languages=c --with-sysroot=/arm/sys/buildroot/output/staging --with-build-time-tools=/arm/sys/buildroot/output/staging/usr/arm-unknown-linux-uclibcgnueabi/bin --disable-__cxa_atexit --enable-target-optspace --with-gnu-ld --disable-libssp --enable-tls --enable-shared --with-gmp=/arm/sys/buildroot/output/toolchain/gmp --with-mpfr=/arm/sys/buildroot/output/toolchain/mpfr --enable-threads --disable-multilib --disable-decimal-float --with-float=soft --with-abi=aapcs-linux --with-arch=armv4t --with-tune=arm920t --disable-largefile --with-pkgversion='Buildroot 2010.05-rc2' --with-bugurl=http://bugs.buildroot.net/
執行緒模型:posix
gcc version 4.3.4 (Buildroot 2010.05-rc2)

Note also, the target directory you will find the hierarchy root filesystem is created here and the image directory with a copy of jffs2 image of the root filesystem.



Extract JFFS2 image filesystem

In this stage i extract the JFFS2 image and dump it into a NFS directory so that i can make any changes whenever it is require.

I will use RAM disk module to open the image, in case there is a problem check whether kernel RAM disk is supported in your environment.

First, use root permission to load the modules and verify it is available.

modprobe mtdblock
modprobe mtdram total_size=32768 erase_size=256
modprobe jffs2
lsmod | grep mtd

mtdram                  2680  0
mtdblock 4132 0
mtd_blkdevs 6124 1 mtdblock
mtd 15948 5 jffs2,mtdram,mtd_blkdevs

Check also the device file is ready.

ls /dev/mtd*

/dev/mtd0  /dev/mtd0ro  /dev/mtdblock0

Once checked, dump the image into the block device and mount it into a new directory.

dd if=/arm/sys/buildroot/output/images/rootfs.jffs2 of=/dev/mtdblock0
mkdir /arm/fs/rootfs
mount -t jffs2 /dev/mtdblock0 /arm/fs/rootfs


If everything works fine, you will find the hierarchy root filesystem in the new directory.

bin  etc   lib      mnt  proc  sbin  tmp  var
dev home linuxrc opt root sys usr


Make a backup of the directory.

cd /arm/fs
tar jcvf rootfs.bz2 rootfs/


Dismount the block device and release the RAM and modules.

umount -t jffs2 /dev/mtdblock0
modprobe -r mtdblock
modprobe -r mtdram
modprobe -r jffs2


Restore the backup file into the new directory.

cd /arm/fs
bzip2 -dc rootfs.bz | tar xvf -


Setup the NFS for the new directory

cp /etc/exports /etc/exports.bak
echo /arm/fs/rootfs *(rw,sync,no_root_squash)>>/etc/exports


Change the bootargs to look at the new directory

setenv bootargs console=ttySAC0 noinitrd init=/sbin/init mini2440=0tb root=/dev/nfs nfsroot=$(serverip):/arm/fs/rootfs ip=$(ipaddr)::$(gateway):$(netmask):mini2440:eth0:off
saveenv


Reboot the device, if its working a final prompt message will show up, this is the result of a basic copy of root filesystem from Builroot, study the etc/inittab, etc/init.d, etc/network, etc/profile and understand the start up process.



Once tested, you can flash the image.



Build additional package from Buildroot

In this section i will include additional library and program to show that it is easy to build a package if you know the name of the library/software, the objective function and its require dependency modules.

Below i add in a zlib library, a tslib touch screen module and include a command-line MP3 player program into our target image.

Start up the menu configuration and make the following changes.

1) Go to 'Package Selection for the target' --> look for 'Libraries' --> select 'Compression and Decompression' --> move to 'zlib' and enable it.

press 'Exit' to go back to the 'Libraries' menu.

2) Go to 'Hardware Handling' --> select 'libts - The Touchscreen tslib library' and enable it.

press 'Exit' to go back to the 'Package Selection for the target' menu.

3) Go to 'Audio and Video libraries and applications --> select 'madplay' and enable it, notice the 'libmad' and 'libid3tag' option is also being set as its dependency modules.

if you want video playback, move to 'mplayer' and its dependant module 'libdvdread' and enable it.

press 'Exit' to go back to the main menu.

4) Go to 'Toolchain' --> select 'Enable large file'

5) press 'Exit' and 'Yes' to save the configuration settings.


Finally, run the building process.

If all goes well, go to the output/target/usr/lib directory, you will find all the libraries is being generated here.

libid3tag.so        libmad.so        libts-0.0.so.0      libz.so        ts
libid3tag.so.0 libmad.so.0 libts-0.0.so.0.1.1 libz.so.1
libid3tag.so.0.3.0 libmad.so.0.2.1 libts.so libz.so.1.2.3


In the output/target/usr/bin directory, you will see the madplay and ts programs.

[         cut         fuser     logger    realpath     test          unzip
[[ dc head logname renice tftp uptime
abxtest deallocvt hexdump lzmacat reset time uudecode
ar diff hostid madplay resize top uuencode
arping dirname iconv md5sum seq tr vlock
awk dos2unix id mesg setkeycodes traceroute wc
basename du install mkfifo setsid ts_calibrate wget
bunzip2 eject ipcrm nohup sha1sum ts_harvest which
bzcat env ipcs nslookup sha256sum ts_print who
chrt ether-wake killall od sha512sum ts_print_raw whoami
chvt expr killall5 openvt sort ts_test xargs
cksum fdformat last passwd strings tty yes
clear find ldd patch tail uniq
cmp fold length printf tee unix2dos
crontab free less readlink telnet unlzma


Now, before we extract the jffs2 image into the new directory there are a few changes to make below.

Edit the ts.conf in buildroot/package/tslib and uncomment the 'module raw input'.

Modify the profile in buildroot/target/generic/target_skeleton/etc to append code below.

for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
. $i
fi
done


Create a new directory name 'profile.d' to keep our system profile startup script, this will be the tslib.sh to setup the touchscreen environment's setting.

export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_CONSOLEDEVICE=none


Setup the network ip address require in the etc/network/interface file.

# static ip
auto eth0
iface eth0 inet static
address 192.168.1.190
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1


or setup as a dhcp (handy for me as internet connection when flash the image).

# The primary network interface - use DHCP to find our address
auto eth0
iface eth0 inet dhcp


add a new script resolv.sh in profile.d to setup the DNS and domain name for the resolv.conf in order to access to the internet.

echo search domain.com.tw >/tmp/resolv.conf
echo nameserver 168.95.1.1 >>/tmp/resolv.conf


to restart network service, use the init.d script below.

/etc/init.d/S40network restart


Next, modify the device_table.txt in buildroot/target/generic to uncomment the /dev/dsp sound device file require by our madplay program.

Finally, regenerate the image file for the above changes and extract the jffs2 into the new directory again.

make



Once finish copy a few mp3/mpeg files into 'var' directory and reset the device,
log in as root and test the touchscreen library and madplay/mplayer.

ts_calibrate
ts_test




madplay music.mp3

MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.
usb 1-1: USB disconnect, address 2
gspca: disconnect complete
6268 frames decoded (0:02:43.7), +0.6 dB peak amplitude, 106 clipped samples

mplayer video.mpeg

MPlayer 1.0rc2.atmel.1-4.3.4 (C) 2000-2007 MPlayer Team
CPU: ARM

Playing video.mpeg.
MPEG-PS file format detected.
VIDEO: MPEG1 320x240 (aspect 1) 30.000 fps 512.0 kbps (64.0 kbyte/s)
==========================================================================
Opening video decoder: [mpegpes] MPEG 1/2 Video passthrough
Read DOCS/HTML/en/video.html for tuning/speedup tips.
If none of this helps you, read DOCS/HTML/en/bugreports.html.

A: 86.3 V: 86.2 A-V: 0.173 ct: 1.346 2585/2585 29% 23% 49.8% 2128 0

Exiting... (End of file)