Introduction

Linux From Scratch (LFS) is a project providing instructions for building your own Linux system from scratch. If you have not already, I recommend you visiting their homepage http://www.linuxfromscratch.org.

LFS has many flavors, and a few of them targets cross-compilation and embedded systems; the CLFS tracks. You will find more information about them here. This blog post is inspired by the CLFS Embbedded 1.x track, but as that track is not yet finished and also quite general, I will make a few shortcuts and hardware specific tweaks. Also, I will not go through the exact same steps as the original, so if you are trying to follow that at the same time, you might notice me jump around quite a bit. The end result should however be quite similar.

In short, we will do the following:

Create our own cross-compiler.

Build the root file system using two main components; uClibc and Busybox.

Build the Raspberry Pi specific kernel (this is actually cheating a little, since LFS is based on vanilla software).

Download hardware specific binary blobs for booting the Raspberry Pi (also cheating).

Prepare a SD-card and populate it with the binary sw, kernel and root file system.

One final piece of information. This post is quite condensed. If you want more information on a specific command or software, I recommend you to look up the corresponding section in the CLFS handbook:

http://cross-lfs.org/view/clfs-embedded/arm/

Preparing the build environment

CLFS recommends creating a completely new user to get a clean build environment. Let’s do that:

[bash]

# Add the clfs group

groupadd clfs

# Add the clfs user

useradd -s /bin/bash -g clfs -m -k /dev/null clfs

# Give clfs a password

passwd clfs

# Log in as the new user

su – clfs

[/bash]

Make sure you’re logged in as the clfs user, then continue with setting up the environment:

[bash]

# Create build directories

mkdir -pv ~/build/clfs/{sources,firmware,tools,cross-tools,rootfs}

export CLFS=$HOME/build/clfs/rootfs

export CLFS_SRC=$HOME/build/clfs/sources

export CLFS_FW=$HOME/build/clfs/firmware

export CLFS_TOOLS=$HOME/build/clfs/tools

export CLFS_CROSS_TOOLS=$HOME/build/clfs/cross-tools

# Make sure the environment is set up every time you log in

# Create a bash_profile

cat > ~/.bash_profile << "EOF" exec env -i HOME=${HOME} TERM=${TERM} PS1='u:w$ ' /bin/bash EOF # And a bashrc cat > ~/.bashrc << "EOF" set +h umask 022 CLFS=$HOME/build/clfs/rootfs CLFS_SRC=$HOME/build/clfs/sources CLFS_FW=$HOME/build/clfs/firmware CLFS_TOOLS=$HOME/build/clfs/tools CLFS_CROSS_TOOLS=$HOME/build/clfs/cross-tools LC_ALL=POSIX PATH=${CLFS_CROSS_TOOLS}/bin:/bin:/usr/bin export CLFS CLFS_SRC CLFS_FW CLFS_TOOLS CLFS_CROSS_TOOLS LC_ALL PATH EOF [/bash] Now, lets download the source packages: [bash] cd $CLFS_SRC # Binutils wget http://ftp.gnu.org/gnu/binutils/binutils-2.21.1a.tar.bz2 # Busybox wget http://busybox.net/downloads/busybox-1.18.4.tar.bz2 # CLFS bootscripts wget http://cross-lfs.org/files/packages/embedded-0.0.1/clfs-embedded-bootscripts-1.0-pre5.tar.bz2 # GCC wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.6.0/gcc-4.6.0.tar.bz2 # GMP wget http://ftp.gnu.org/gnu/gmp/gmp-5.0.1.tar.bz2 # iana-etc wget http://cross-lfs.org/files/packages/embedded-0.0.1/iana-etc-2.30.tar.bz2 # MPC wget http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz # MPFR wget http://gforge.inria.fr/frs/download.php/27105/mpfr-3.0.0.tar.bz2 # uClibc wget http://www.uclibc.org/downloads/uClibc-0.9.31.tar.bz2 # Kernel git clone git://github.com/raspberrypi/linux.git # Busybox patch wget http://patches.cross-lfs.org/embedded-dev/busybox-1.18.4-config-1.patch # iana-etc patch wget http://patches.cross-lfs.org/embedded-dev/iana-etc-2.30-update-1.patch # uClibc patch wget http://patches.cross-lfs.org/embedded-dev/uClibc-0.9.31-configs-2.patch cd $CLFS_FW # Broadcom firmware git clone git://github.com/raspberrypi/firmware.git cd $CLFS_TOOLS # Extra tools git clone git://github.com/raspberrypi/tools.git [/bash] Finally, lets prepare the target file system by creating the directory structure according to FHS (http://www.pathname.com/fhs/): [bash] mkdir -pv ${CLFS}/{bin,boot,dev,{etc/,}opt,home,lib/{firmware,modules},mnt} mkdir -pv ${CLFS}/{proc,media/{floppy,cdrom},sbin,srv,sys} mkdir -pv ${CLFS}/var/{lock,log,mail,run,spool} mkdir -pv ${CLFS}/var/{opt,cache,lib/{misc,locate},local} install -dv -m 0750 ${CLFS}/root install -dv -m 1777 ${CLFS}{/var,}/tmp mkdir -pv ${CLFS}/usr/{,local/}{bin,include,lib,sbin,src} mkdir -pv ${CLFS}/usr/{,local/}share/{doc,info,locale,man} mkdir -pv ${CLFS}/usr/{,local/}share/{misc,terminfo,zoneinfo} mkdir -pv ${CLFS}/usr/{,local/}share/man/man{1,2,3,4,5,6,7,8} for dir in ${CLFS}/usr{,/local}; do ln -sv share/{man,doc,info} ${dir} done [/bash]

Creating the cross-compiler

Setup variables for creating a cross-compiler for the Raspberry Pi:

[bash]

# Clear compiler flags

unset CFLAGS

unset CXXFLAGS

# Set ABI

export CLFS_ABI=aapcs-linux

# Set host and target

export CLFS_HOST=$(echo ${MACHTYPE} | sed “s/-[^-]*/-cross/”)

export CLFS_TARGET=arm-unknown-linux-uclibcgnueabi

# Set architecture and endianess

export CLFS_ARCH=arm

export CLFS_ENDIAN=little

# Set specific ARM architecture

export CLFS_ARM_ARCH=armv6zk

export CLFS_ARM_MODE=arm

# Set hw float of type vfp

export CLFS_FLOAT=hard

export CLFS_FPU=vfp

# Add to bashrc

echo unset CFLAGS >> ~/.bashrc

echo unset CXXFLAGS >> ~/.bashrc

echo export CLFS_ABI=””${CLFS_ABI}”” >> ~/.bashrc

echo export CLFS_HOST=””${CLFS_HOST}”” >> ~/.bashrc

echo export CLFS_TARGET=””${CLFS_TARGET}”” >> ~/.bashrc

echo export CLFS_ARCH=””${CLFS_ARCH}”” >> ~/.bashrc

echo export CLFS_ENDIAN=””${CLFS_ENDIAN}”” >> ~/.bashrc

echo export CLFS_ARM_ARCH=””${CLFS_ARM_ARCH}”” >> ~/.bashrc

echo export CLFS_ARM_MODE=””${CLFS_ARM_MODE}”” >> ~/.bashrc

echo export CLFS_FLOAT=””${CLFS_FLOAT}”” >> ~/.bashrc

echo export CLFS_FPU=””${CLFS_FPU}”” >> ~/.bashrc

[/bash]

The next step builds the whole toolchain. However, I wouldn’t recommend simply copy-pasting the whole shebang into your console. Instead, do each section/software in turn, to make sure you follow what’s going on.

[bash]

# Linux headers

cd $CLFS_SRC/linux

make mrproper

make ARCH=${CLFS_ARCH} headers_check

make ARCH=${CLFS_ARCH} INSTALL_HDR_PATH=dest headers_install

cp -rv dest/include/* ${CLFS}/usr/include

# GMP

cd $CLFS_SRC

tar -jxvf gmp-5.0.1.tar.bz2 && cd gmp-5.0.1

CPPFLAGS=-fexceptions ./configure

–prefix=${CLFS_CROSS_TOOLS}

make

make check

make install

cd $CLFS_SRC && rm -rf gmp-5.0.1

# MPFR

cd $CLFS_SRC

tar -jxvf mpfr-3.0.0.tar.bz2 && cd mpfr-3.0.0

LDFLAGS=”-Wl,-rpath,${CLFS_CROSS_TOOLS}/lib”

./configure –prefix=${CLFS_CROSS_TOOLS} –enable-shared

–with-gmp=${CLFS_CROSS_TOOLS}

make

make install

cd $CLFS_SRC && rm -rf mpfr-3.0.0

# MPC

cd $CLFS_SRC

tar -zxvf mpc-0.9.tar.gz && cd mpc-0.9

LDFLAGS=”-Wl,-rpath,${CLFS_CROSS_TOOLS}/lib”

./configure –prefix=${CLFS_CROSS_TOOLS}

–with-gmp=${CLFS_CROSS_TOOLS}

–with-mpfr=${CLFS_CROSS_TOOLS}

make

make install

cd $CLFS_SRC && rm -rf mpc-0.9

# Binutils

cd $CLFS_SRC

tar -jxvf binutils-2.21.1a.tar.bz2 && mkdir -v binutils-build && cd binutils-build

../binutils-2.21.1/configure –prefix=${CLFS_CROSS_TOOLS}

–target=${CLFS_TARGET} –with-sysroot=${CLFS} –disable-nls

–enable-shared –disable-multilib

make configure-host

make

make install

cp -v ../binutils-2.21.1/include/libiberty.h ${CLFS}/usr/include

cd $CLFS_SRC && rm -rf binutils-2.21.1 && rm -rf binutils-build

# GCC

cd $CLFS_SRC

tar -jxvf gcc-4.6.0.tar.bz2 && mkdir -v gcc-build && cd gcc-build

AR=ar LDFLAGS=”-Wl,-rpath,${CLFS_CROSS_TOOLS}/lib”

../gcc-4.6.0/configure –prefix=${CLFS_CROSS_TOOLS}

–build=${CLFS_HOST} –host=${CLFS_HOST} –target=${CLFS_TARGET}

–with-sysroot=${CLFS} –disable-nls –disable-shared

–with-mpfr=${CLFS_CROSS_TOOLS} –with-gmp=${CLFS_CROSS_TOOLS}

–with-mpc=${CLFS_CROSS_TOOLS} –without-headers –with-newlib

–disable-decimal-float –disable-libgomp –disable-libmudflap

–disable-libssp –disable-threads –enable-languages=c,c++

–disable-multilib –with-abi=${CLFS_ABI} –with-arch=${CLFS_ARM_ARCH}

–with-mode=${CLFS_ARM_MODE} –with-float=${CLFS_FLOAT}

–with-fpu=${CLFS_FPU}

make all-gcc all-target-libgcc

make install-gcc install-target-libgcc

cd $CLFS_SRC && rm -rf gcc-4.6.0 && rm -rf gcc-build

# uClibc

cd $CLFS_SRC

tar -jxvf uClibc-0.9.31.tar.bz2 && cd uClibc-0.9.31

patch -Np1 -i ../uClibc-0.9.31-configs-2.patch

sed -i”.bak” ‘/_init, .-_init/d’ libc/sysdeps/linux/arm/crtn.S

sed -i”.bak” ‘/_fini, .-_fini/d’ libc/sysdeps/linux/arm/crtn.S

cp -v clfs/config.${CLFS_ARCH}.${CLFS_ENDIAN} .config

if [ “${CLFS_ABI}” == “aapcs” ] || [ “${CLFS_ABI}” == “aapcs-linux” ];

then sed -i s/CONFIG_ARM_OABI/CONFIG_ARM_EABI/g .config; fi

make oldconfig

make

make PREFIX=${CLFS} install

cd $CLFS_SRC && rm -rf uClibc-0.9.31

# GCC – second (final) iteration

cd $CLFS_SRC

tar -jxvf gcc-4.6.0.tar.bz2 && mkdir -v gcc-build && cd gcc-build

AR=ar LDFLAGS=”-Wl,-rpath,${CLFS_CROSS_TOOLS}/lib”

../gcc-4.6.0/configure –prefix=${CLFS_CROSS_TOOLS}

–build=${CLFS_HOST} –target=${CLFS_TARGET} –host=${CLFS_HOST}

–with-sysroot=${CLFS} –disable-nls –enable-shared

–enable-languages=c,c++ –enable-c99 –enable-long-long

–with-mpfr=${CLFS_CROSS_TOOLS} –with-gmp=${CLFS_CROSS_TOOLS}

–with-mpc=${CLFS_CROSS_TOOLS} –disable-multilib

–with-abi=${CLFS_ABI} –with-arch=${CLFS_ARM_ARCH}

–with-mode=${CLFS_ARM_MODE} –with-float=${CLFS_FLOAT}

–with-fpu=${CLFS_FPU}

make

make install

cp -v ${CLFS_CROSS_TOOLS}/${CLFS_TARGET}/lib/libgcc_s.so.1 ${CLFS}/lib

cd $CLFS_SRC && rm -rf gcc-4.6.0 && rm -rf gcc-build

[/bash]

Done! Now lets build the actual system…

Build the system

First, add the newly create cross-compiler to the environment:

[bash]

echo export CC=””${CLFS_TARGET}-gcc”” >> ~/.bashrc

echo export CXX=””${CLFS_TARGET}-g++”” >> ~/.bashrc

echo export AR=””${CLFS_TARGET}-ar”” >> ~/.bashrc

echo export AS=””${CLFS_TARGET}-as”” >> ~/.bashrc

echo export LD=””${CLFS_TARGET}-ld”” >> ~/.bashrc

echo export RANLIB=””${CLFS_TARGET}-ranlib”” >> ~/.bashrc

echo export READELF=””${CLFS_TARGET}-readelf”” >> ~/.bashrc

echo export STRIP=””${CLFS_TARGET}-strip”” >> ~/.bashrc

source ~/.bashrc

[/bash]

Next, compile Busybox:

[bash]

cd $CLFS_SRC

tar -jxvf busybox-1.18.4.tar.bz2 && cd busybox-1.18.4

patch -Np1 -i ../busybox-1.18.4-config-1.patch

cp -v clfs/config .config

make oldconfig

make CROSS_COMPILE=”${CLFS_TARGET}-”

make CROSS_COMPILE=”${CLFS_TARGET}-” CONFIG_PREFIX=”${CLFS}” install

cp examples/depmod.pl ${CLFS_CROSS_TOOLS}/bin

chmod 755 ${CLFS_CROSS_TOOLS}/bin/depmod.pl

cd $CLFS_SRC && rm -rf busybox-1.18.4

[/bash]

And finally, build iana-etc:

[bash]

cd $CLFS_SRC

tar -jxvf iana-etc-2.30.tar.bz2 && cd iana-etc-2.30

patch -Np1 -i ../iana-etc-2.30-update-1.patch

make get

make

make DESTDIR=${CLFS} install

cd $CLFS_SRC && rm -rf iana-etc-2.30

[/bash]

Build the kernel

Build the Raspberry Pi specific kernel:

[bash]

# Set cross-compiler target (notice the ‘-‘ in the end)

CLFS_CROSS_COMPILE=${CLFS_CROSS_TOOLS}/bin/${CLFS_TARGET}-

# Build kernel

cd $CLFS_SRC/linux

make mrproper

ARCH=arm make bcmrpi_cutdown_defconfig

ARCH=arm CROSS_COMPILE=${CLFS_CROSS_COMPILE} make oldconfig

ARCH=arm CROSS_COMPILE=${CLFS_CROSS_COMPILE} make

ARCH=arm CROSS_COMPILE=${CLFS_CROSS_COMPILE} make modules_install INSTALL_MOD_PATH=${CLFS}/boot

cd $CLFS_SRC

# Do some magic with the Raspberry Pi kernel image creator

cd $CLFS_TOOLS/tools/mkimage

./imagetool-uncompressed.py $CLFS_SRC/linux/arch/arm/boot/Image

cp -v kernel.img $CLFS/boot/

[/bash]

Copy boot firmware

Copy the binary files provided by Broadcom to the boot directory:



# cp -v $CLFS_FW/firmware/boot/{bootcode.bin,fixup.dat,fixup_cd.dat,start.elf,start_cd.elf} $CLFS/boot/



Install bootscripts

The CLFS-Bootscripts package contains a set of scripts to start/stop the CLFS system at bootup/shutdown.

[bash]

cd $CLFS_SRC

tar -zxvf clfs-embedded-bootscripts-1.0-pre5.tar.bz2 && cd clfs-embedded-bootscripts-1.0-pre5

make DESTDIR=${CLFS} install-bootscripts

install -dv ${CLFS}/etc/init.d

ln -sv ../rc.d/startup ${CLFS}/etc/init.d/rcS

cd $CLFS_SRC && rm -rf clfs-embedded-bootscripts-1.0-pre5.tar.bz2

[/bash]

Add a few config files. Start with a /etc/mdev.conf file:

[bash]

cat > ${CLFS}/etc/mdev.conf<< "EOF" # /etc/mdev/conf # Devices: # Syntax: %s %d:%d %s # devices user:group mode # null does already exist; therefore ownership has to be changed with command null root:root 0666 @chmod 666 $MDEV zero root:root 0666 grsec root:root 0660 full root:root 0666 random root:root 0666 urandom root:root 0444 hwrandom root:root 0660 # console does already exist; therefore ownership has to be changed with command #console root:tty 0600 @chmod 600 $MDEV && mkdir -p vc && ln -sf ../$MDEV vc/0 console root:tty 0600 @mkdir -pm 755 fd && cd fd && for x in 0 1 2 3 ; do ln -sf /proc/self/fd/$x $x; done fd0 root:floppy 0660 kmem root:root 0640 mem root:root 0640 port root:root 0640 ptmx root:tty 0666 # ram.* ram([0-9]*) root:disk 0660 >rd/%1

loop([0-9]+) root:disk 0660 >loop/%1

sd[a-z].* root:disk 0660 */lib/mdev/usbdisk_link

hd[a-z][0-9]* root:disk 0660 */lib/mdev/ide_links

md[0-9] root:disk 0660

tty root:tty 0666

tty[0-9] root:root 0600

tty[0-9][0-9] root:tty 0660

ttyS[0-9]* root:tty 0660

pty.* root:tty 0660

vcs[0-9]* root:tty 0660

vcsa[0-9]* root:tty 0660

ttyLTM[0-9] root:dialout 0660 @ln -sf $MDEV modem

ttySHSF[0-9] root:dialout 0660 @ln -sf $MDEV modem

slamr root:dialout 0660 @ln -sf $MDEV slamr0

slusb root:dialout 0660 @ln -sf $MDEV slusb0

fuse root:root 0666

# dri device

card[0-9] root:video 0660 =dri/

# alsa sound devices and audio stuff

pcm.* root:audio 0660 =snd/

control.* root:audio 0660 =snd/

midi.* root:audio 0660 =snd/

seq root:audio 0660 =snd/

timer root:audio 0660 =snd/

adsp root:audio 0660 >sound/

audio root:audio 0660 >sound/

dsp root:audio 0660 >sound/

mixer root:audio 0660 >sound/

sequencer.* root:audio 0660 >sound/

# misc stuff

agpgart root:root 0660 >misc/

psaux root:root 0660 >misc/

rtc root:root 0664 >misc/

# input stuff

event[0-9]+ root:root 0640 =input/

mice root:root 0640 =input/

mouse[0-9] root:root 0640 =input/

ts[0-9] root:root 0600 =input/

# v4l stuff

vbi[0-9] root:video 0660 >v4l/

video[0-9] root:video 0660 >v4l/

# dvb stuff

dvb.* root:video 0660 */lib/mdev/dvbdev

# load drivers for usb devices

usbdev[0-9].[0-9] root:root 0660 */lib/mdev/usbdev

usbdev[0-9].[0-9]_.* root:root 0660

# net devices

tun[0-9]* root:root 0600 =net/

tap[0-9]* root:root 0600 =net/

# zaptel devices

zap(.*) root:dialout 0660 =zap/%1

dahdi!(.*) root:dialout 0660 =dahdi/%1

# raid controllers

cciss!(.*) root:disk 0660 =cciss/%1

ida!(.*) root:disk 0660 =ida/%1

rd!(.*) root:disk 0660 =rd/%1

sr[0-9] root:cdrom 0660 @ln -sf $MDEV cdrom

# hpilo

hpilo!(.*) root:root 0660 =hpilo/%1

# xen stuff

xvd[a-z] root:root 0660 */lib/mdev/xvd_links

EOF

[/bash]

And a /etc/profile file:

[bash]

cat > ${CLFS}/etc/profile<< "EOF" # /etc/profile # Set the initial path export PATH=/bin:/usr/bin if [ `id -u` -eq 0 ] ; then PATH=/bin:/sbin:/usr/bin:/usr/sbin unset HISTFILE fi # Setup some environment variables. export USER=`id -un` export LOGNAME=$USER export HOSTNAME=`/bin/hostname` export HISTSIZE=1000 export HISTFILESIZE=1000 export PAGER='/bin/more ' export EDITOR='/bin/vi' # End /etc/profile EOF [/bash] Create a softlink for the /etc/mtab file:

ln -svf ../proc/mounts ${CLFS}/etc/mtab

The passwd file allows us to login as root:

[bash]

cat > ${CLFS}/etc/passwd << "EOF" root::0:0:root:/root:/bin/ash EOF [/bash] Add a groups file too: [bash] cat > ${CLFS}/etc/group << "EOF" root:x:0: bin:x:1: sys:x:2: kmem:x:3: tty:x:4: tape:x:5: daemon:x:6: floppy:x:7: disk:x:8: lp:x:9: dialout:x:10: audio:x:11: video:x:12: utmp:x:13: usb:x:14: cdrom:x:15: EOF [/bash] Setup logs: [bash] touch ${CLFS}/var/run/utmp ${CLFS}/var/log/{btmp,lastlog,wtmp} chmod -v 664 ${CLFS}/var/run/utmp ${CLFS}/var/log/lastlog [/bash] A /etc/inittab file:

[bash]

cat > ${CLFS}/etc/inittab<< "EOF" # /etc/inittab ::sysinit:/etc/rc.d/startup tty1::respawn:/sbin/getty 38400 tty1 tty2::respawn:/sbin/getty 38400 tty2 tty3::respawn:/sbin/getty 38400 tty3 tty4::respawn:/sbin/getty 38400 tty4 tty5::respawn:/sbin/getty 38400 tty5 tty6::respawn:/sbin/getty 38400 tty6 # Put a getty on the serial line (for a terminal) # uncomment this line if your using a serial console #::respawn:/sbin/getty -L ttyS0 115200 vt100 ::shutdown:/etc/rc.d/shutdown ::ctrlaltdel:/sbin/reboot EOF [/bash] Create a /etc/HOSTNAME file:



echo "my-awesome-rasberry" > ${CLFS}/etc/HOSTNAME



And the /etc/hosts file. You might want to add additional hosts to this file:

[bash]

cat > ${CLFS}/etc/hosts << "EOF" # Begin /etc/hosts (no network card version) 127.0.0.1 my-awesome-raspberry localhost # End /etc/hosts (no network card version) EOF [/bash] Finally, setup network (this requires you to actually edit the files according to your network setup) in /etc/network.conf:

[bash]

cat > ${CLFS}/etc/network.conf << "EOF" # /etc/network.conf # Global Networking Configuration # interface configuration is in /etc/network.d/ # set to yes to enable networking NETWORKING=yes # set to yes to set default route to gateway USE_GATEWAY=no # set to gateway IP address GATEWAY=192.168.0.1 # Interfaces to add to br0 bridge # Leave commented to not setup a network bridge # Substitute br0 for eth0 in the interface.eth0 sample below to bring up br0 # instead # bcm47xx with vlans: #BRIDGE_INTERFACES="eth0.0 eth0.1 wlan0" # Other access point with a wired eth0 and a wireless wlan0 interface: #BRIDGE_INTERFACES="eth0 wlan0" EOF [/bash] And one for eth0: [bash] mkdir ${CLFS}/etc/network.d && cat > ${CLFS}/etc/network.d/interface.eth0 << "EOF" # Network Interface Configuration # network device name INTERFACE=eth0 # set to yes to use DHCP instead of the settings below DHCP=no # IP address IPADDRESS=192.168.1.2 # netmask NETMASK=255.255.255.0 # broadcast address BROADCAST=192.168.1.255 EOF [/bash] /etc/udhcpc.conf:

[bash]

cat > ${CLFS}/etc/udhcpc.conf << "EOF" #!/bin/sh # udhcpc Interface Configuration # Based on http://lists.debian.org/debian-boot/2002/11/msg00500.html # udhcpc script edited by Tim Riker

[ -z “$1” ] && echo “Error: should be called from udhcpc” && exit 1

RESOLV_CONF=”/etc/resolv.conf”

RESOLV_BAK=”/etc/resolv.bak”

[ -n “$broadcast” ] && BROADCAST=”broadcast $broadcast”

[ -n “$subnet” ] && NETMASK=”netmask $subnet”

case “$1” in

deconfig)

if [ -f “$RESOLV_BAK” ]; then

mv “$RESOLV_BAK” “$RESOLV_CONF”

fi

/sbin/ifconfig $interface 0.0.0.0

;;

renew|bound)

/sbin/ifconfig $interface $ip $BROADCAST $NETMASK

if [ -n “$router” ] ; then

while route del default gw 0.0.0.0 dev $interface ; do

true

done

for i in $router ; do

route add default gw $i dev $interface

done

fi

if [ ! -f “$RESOLV_BAK” ] && [ -f “$RESOLV_CONF” ]; then

mv “$RESOLV_CONF” “$RESOLV_BAK”

fi

echo -n > $RESOLV_CONF

[ -n “$domain” ] && echo search $domain >> $RESOLV_CONF

for i in $dns ; do

echo nameserver $i >> $RESOLV_CONF

done

;;

esac

exit 0

EOF

chmod +x ${CLFS}/etc/udhcpc.conf

[/bash]

/etc/resolve.conf:

[bash]

cat > ${CLFS}/etc/resolv.conf << "EOF" # Begin /etc/resolv.conf domain [Your Domain Name] nameserver [IP address of your primary nameserver] nameserver [IP address of your secondary nameserver] # End /etc/resolv.conf EOF [/bash]

Format SD-card

Now it’s time to format an SD-card to hold our newly created system. Since your newly created user clfs doesn’t have root access, you probably want to open a new terminal for this. Insert your SD-card and run

[bash]

# sudo fdisk -l

…

Disk /dev/mmcblk0: 1977 MB, 1977614336 bytes

4 heads, 16 sectors/track, 60352 cylinders, total 3862528 sectors

Units = sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk identifier: 0x000dbfc6

…

[/bash]

You probably have at least your /dev/sda disk showing up in the output of fdisk as well. Make sure you identify the correct device for the SD-card, in this case it is /dev/mmcblk0. One way is to unplug the SD-card and re-run fdisk -l.

Run fdisk against the newly discovered device:

[bash]

# sudo fdisk /dev/mmcblk0

[/bash]

Configure the device according to your own liking, just make sure to make the boot and root partitions sufficiently large. One suggestion is listed in the layout below. See man fdisk for more information on how to use the disk command.

[bash]

Device Boot Start End Blocks Id System

/dev/mmcblk0p1 * 2048 206847 102400 c W95 FAT32 (LBA)

/dev/mmcblk0p2 206848 2664447 1228800 83 Linux

/dev/mmcblk0p3 2664448 3862527 599040 82 Linux swap / Solaris

[/bash]

Next, format the partitions you’ve just created:

[bash]

sudo mkfs.vfat /dev/mmcblk0p1

sudo mkfs.ext4 /dev/mmcblk0p2

sudo mkswap /dev/mmcblk0p3

[/bash]

Finally, mount the newly created file systems:

[bash]

sudo mkdir -pv /mnt/clfs

sudo mount /dev/mmcblk0p2 /mnt/clfs

sudo mkdir -pv /mnt/clfs/boot

sudo mount -t vfat /dev/mmcblk0p1 /mnt/clfs/boot

[/bash]

Populate the SD-card

While still logged in as a user with root access, populate the root file system:

[bash]

# sudo cp -rv /home/clfs/build/clfs/rootfs/* /mnt/clfs

[/bash]

Create a /etc/fstab file:

[bash]

sudo sh -c ‘cat > /mnt/clfs/etc/fstab << "EOF" # Begin /etc/fstab # file system mount-point type options dump fsck # order /dev/mmcblk0p1 /boot vfat defaults 1 2 /dev/mmcblk0p2 / ext4 defaults 0 1 /dev/mmcblk0p3 none swap sw 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 devpts /dev/pts devpts gid=4,mode=620 0 0 shm /dev/shm tmpfs defaults 0 0 # End /etc/fstab EOF' [/bash] Now we need only to add one final file: [bash] sudo sh -c 'cat > /mnt/clfs/boot/cmdline.txt << "EOF" root=/dev/mmcblk0p2 rootdelay=2 EOF' [/bash] Thats it! Unmount your SD-card partitions, move the card to the Raspberry Pi and boot it up! Most file snippets are also available in this Gist.