It is this last option that we will experiment here thanks to this twiki written by T.I.
Our root filesystem is based on BusyBox which offers the main linux command line utilities in a single executable.
Build BusyBox
Download the latest release of busybox on the official website and extract it to your working directory.cd busybox-1.21.0Follow the instructions as detailed in the T.I. twiki to customize your binary. I have made some different choices here and there to add additional commands like fdisk. Do as you like, it does not really matter...
make menuconfig
Build ...
ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make... and install it on the second partition of your SD Card :
make CONFIG_PREFIX=/media/<path_to_your_sd_card_p2> installHere is what you should see on your partition after the last step :
bin linuxrc lost+found sbin usr
Create compulsory directories
The official rules to build a root filesystem are detailed in the Filesystem Hierarchy Standard (FHS). Here is a complete list of the top level directories :bin : essential user command binaries
boot : files used by the bootloader
dev : devices files
etc : system configuration files
home : users home directory
lib : essential libraries (C library, kernel modules,...)
media : mount points for removable medias
mnt : mount points for temporarily mounted filesystems
opt : Add-on software packages
proc : virtual filesystem for kernel and process information
root : root user's home directory
sbin : essntial system administration binaries
sys : virtual filesystem for system information and control
tmp : temporary files
usr : secondary hierarchy containing most applications and documents useful to most users
var : variable data stored by daemons and utilities
We don't need all of them as we won't provide a multi-user environment. /home, /mnt, and /opt can be ommited.
Create the directories (as root)
cd /media/<path_to_your_sd_card_p2>Optional : debug is needed by debugfs, add it if your kernel has been built with this option
sudo mkdir dev dev/pts etc etc/init.d lib mnt opt proc root sys tmp var var/log
sudo mkdir debug
Create a static node for console
Like Unix systems, every object in Linux is visible as a file (except for networking interfaces). As such, /dev contains device files (nodes) that represent the system devices. This directory needs to be populated either statically (old fashion way, every node has to be created manually with mknode) or dynamically (common way thanks to udev or mdev).In our case, we will only add a node for the console.
mknod dev/console c 5 1The rest of the nodes will be added by mdev which is part of BusyBox.
cd etc
gedit mdev.conf
audio 0:5 0666 console 0:5 0600 control.* 0:0 0660 @/bin/mv /dev/$MDEV /dev/snd/ dsp 0:5 0666 event.* 0:0 0600 @/bin/mv /dev/$MDEV /dev/input/ fb 0:5 0666 nfs 0:5 0770 null 0:0 0777 pcm.* 0:0 0660 @/bin/mv /dev/$MDEV /dev/snd/ rtc 0:0 0666 tty 0:5 0660 tty0* 0:5 0660 tty1* 0:5 0660 tty2* 0:5 0660 tty3* 0:5 0660 tty4* 0:5 0660 tty5* 0:5 0660 tty6* 0:5 0660 ttyS* 0:5 0640 urandom 0:0 0444 zero 0:0 0666
Create an fstab file to mount /proc and /dev/pts at boot
fstab is system configuration file used to list the available disks and disk partitions and describes how they are initialized. The mount command relies on this file to determine which option should be used when mounting a specific device.
# still in /etc
gedit fstab
proc /proc proc defaults 0 0 none /dev/pts devpts mode=0622 0
Login utilities
/etc must contain the files group, passwd and hosts for login. For the moment, root only needs to be defined in group and hosts only needs to have the localhost registered.
gedit group
root:x:0:root
gedit passwd
root::0:0:root:/root:/bin/ash
gedit hosts
127.0.0.1 localhost
Create inittab
Read this post for information about inittab.
gedit inittab
::sysinit:/etc/init.d/rcS # /bin/ash # # Start an "askfirst" shell on the serial port console::askfirst:-/bin/ash # Stuff to do when restarting the init process ::restart:/sbin/init # Stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a
Create init script
gedit init.d/rcS
#!/bin/sh # --------------------------------------------- # Common settings # --------------------------------------------- HOSTNAME=MYPI VERSION=1.0.0 hostname $HOSTNAME # --------------------------------------------- # Prints execution status. # # arg1 : Execution status # arg2 : Continue (0) or Abort (1) on error # --------------------------------------------- status () { if [ $1 -eq 0 ] ; then echo "[SUCCESS]" else echo "[FAILED]" if [ $2 -eq 1 ] ; then echo "... System init aborted." exit 1 fi fi } # --------------------------------------------- # Get verbose # --------------------------------------------- echo "" echo " System initialization..." echo "" echo " Hostname : $HOSTNAME" echo " Filesystem : v$VERSION" echo "" echo "" echo " Kernel release : `uname -s` `uname -r`" echo " Kernel version : `uname -v`" echo "" # --------------------------------------------- # MDEV Support # (Requires sysfs support in the kernel) # --------------------------------------------- echo -n " Mounting /proc : " mount -n -t proc /proc /proc status $? 1 echo -n " Mounting /sys : " mount -n -t sysfs sysfs /sys status $? 1 echo -n " Mounting /dev : " mount -n -t tmpfs mdev /dev status $? 1 echo -n " Mounting /dev/pts : " mkdir /dev/pts mount -t devpts devpts /dev/pts status $? 1 echo -n " Enabling hot-plug : " echo "/sbin/mdev" > /proc/sys/kernel/hotplug status $? 0 echo -n " Populating /dev : " mkdir /dev/input mkdir /dev/snd mdev -s status $? 0 # --------------------------------------------- # Disable power management # (Requires sysfs support in the kernel) # --------------------------------------------- # echo -n " Disabling Power mgmt : " # echo -n "1" > /sys/power/cpuidle_deepest_state # status $? 1 # --------------------------------------------- # Turn off LCD after 1 hour of inactivity # (Requires sysfs support in the kernel) # --------------------------------------------- # echo -n " Turn off LCD after 1 hour : " # echo -n "3600" > /sys/power/fb_timeout_value # status $? 1 # --------------------------------------------- # Mount the default file systems # --------------------------------------------- echo -n " Mounting other filesystems : " mount -a status $? 0 # --------------------------------------------- # Set PATH # --------------------------------------------- export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin # --------------------------------------------- # Start other daemons # --------------------------------------------- echo -n " Starting syslogd : " /sbin/syslogd status $? 0 echo -n " Starting telnetd : " /usr/sbin/telnetd status $? 0 # --------------------------------------------- # Done! # --------------------------------------------- echo "" echo "System initialization complete."
make it executable
chmod +x rcS
Copy the dependencies
We built BusyBox with the ARM cross toolchain as a C program without the -static option, which means that it will look for C libraries at runtime.We have to add them !Note : Use ldd to list the dependencies of a binary
cd /media/<path_to_your_sd_card_p2>/lib
# Copy the C libraries
copy -r /usr/arm-linux-gnueabi/lib/* .
# Remove the debug informations from the libraries to save space
arm-linux-gnueabi-strip
At this point, you have a valid root filesystem with the bare minimum. It does not include the kernel modules yet and if you want to add more executables, you'll also need to add their dependencies. The filesystem will get larger when these files are added.
First boot
Here is my display at first boot :
This time, there is no panic displayed. The kernel finds the init process and executes our script.
To access BusyBox press Enter :
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.