Embedded linux root file system production -- busybox

busybox is the most commonly used software toolkit for constructing file systems. It is very vividly called the "Swiss Army Knife" in embedded Linux systems because it combines many commonly used Linux commands and tools into a single executable program (busybox )middle.
Although compared with the corresponding GNU tools, busybox provides slightly fewer functions and parameters, but it is sufficient in relatively small systems (such as boot disks) or embedded systems.
The design of busybox fully considers the special working environment with limited hardware resources. It uses a very clever way to reduce its size: all commands are centralized into an executable file through "plug-ins", and in the actual application process, different symbolic links are used to determine which operation is to be performed. The program code is shared to the maximum extent by means of a single execution file, and even other system resources such as file headers and program control blocks in memory are shared, which is the most suitable for systems with limited resources. During the compilation process of busybox, it is very convenient to add or subtract its "plug-ins", and the final symbolic link can also be automatically generated by the compilation system.

Purpose:

Understand the production process of the root file system. So, don't get caught up in the details here.

System environment and tools:

Operating system: Ubuntu12.04
Cross-compilation tool: arm-linux-gcc4.4.3
busybox source package: busybox-1.25.0.tar.bz2

Root file system production – busybox configuration compilation and installation:

The dynamically linked busybox is only a few hundred K, and even the statically linked one is only about 1MB.
When creating a minimal root file system, if you use busybox, you only need to create the necessary device nodes in the /dev directory and create some configuration files in the /etc directory; if busybox uses dynamic linking, you also need to The /lib directory contains library files.
Select Dynamic Links here.

Unzip the source package:

#tar -jxvf busybox-1.25.0.tar.bz2

Modify Makefile configuration

Enter the busybox-1.25.0 directory and modify the Makefile as follows:

ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/4.4.3/bin/arm-linux- (与你自己主机的arm-linux-gcc安装目录一样)

Configure BusyBox

#make menuconfig

Busybox Settings —>
Build Options —>
[*]Build shared libbusybox
[ ] Produce a binary for each applet, linked against libbusybox
[ ] Produce additional busybox binary linked against libbusybox

Busybox Settings —>
Installation Options (“make install” behavior) —>
( /nfsdir/tools/rootfs ) BusyBox installation prefix // Storage path of compiled files
Note : If you are installing busybox on a virtual machine, the installation cannot be executed directly Make INSTALL, you must create a folder under the virtual machine and point the installation path to the path of this folder. Execute make CONFIG_PREFIX=/path/from/root install again, otherwise it will destroy the system.
Others are kept at
default . Some options that need attention are described as follows:
Busybox Settings —>
Build Options —>
[ ] Build BusyBox as a static binary (no shared libs) (NEW)
This means that the library is dynamically linked only when busybox is running, which is required by busybox library wants us to provide

Busybox Settings —>
Installation Options (“make install” behavior) —>
What kind of applet links to install (as soft-links) —>
Set up various commands after busybox is generated as soft links to the main program of busybox

Busybox Settings —>
Busybox Library Tuning —>
(255) History size
[*] History saving (NEW) // support history
[*] Tab completion (NEW) // support tab completion

The option Applets is to categorize the hundreds of commands supported by busybox, and we can select the desired command under each category.

Compile and install

#make
#make install

Build the root filesystem

At this point, the installation of busubox is completed. Now check the /nfsdir/tools/rootfs folder, and you will find the following files:
bin linuxrc sbin usr
can be viewed in the bin directory, busybox is only 970K

Create other required folders (according to FHS standards)

mkdir dev etc home lib media mnt opt proc sys tmp var root

Add the corresponding library

The libraries that need to be added are copied from the cross-compilation tool used to compile busybox, but there are many library files in the cross-compilation tool, so it is not necessary to copy all of them.
So how do we know which libraries are needed?
can be determined by

[root@localhost bin]# arm-linux-readelf -d busybox 
Dynamic section at offset 0xf16b4 contains 25 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]

And ld-linux.so.3 is an inherently required library, so busybox needs at least three libraries: ld-linux.so.3, libm.so.6, libc.so.6

Next, keep your eyes open. The above libraries are all linked files. Do not copy the linked files. The real files are not copied
. [root@localhost lib]# ls -l libc.so.6
lrwxrwxrwx 1 root root 11 Apr 23 21:13 libc.so.6 -> libc-2.8.so

[root@localhost lib]# ls -l libm.so.6
lrwxrwxrwx 1 root root 11 Apr 23 21:13 libm.so.6 -> libm-2.8.so

[root@localhost lib]# ls -l ld-linux.so.3
lrwxrwxrwx 1 root root 9 Apr 23 21:13 ld-linux.so.3 -> ld-2.8.so

So copy ld-linux.so.3, libm.so.6, libc.so.6 and libc-2.8.so, libm-2.8.so, ld-2.8.so to /lib.
However, the above libraries are only the libraries needed for busybox to run. Although the system can be started at this time, the following print information will appear:

feed_wdg: error while loading shared libraries: libgcc_s.so.1: cannot open shared object file: No such file or directory

This means that the watchdog program cannot be started due to the lack of the libgcc_s.so.1 library, and then the development board restarts after seeing that it is necessary to copy libgcc_s.so and libgcc_s.so.1 for normal operation

But in actual use, it is necessary to check one by one, which is too troublesome, so generally copy all the libraries that are normally needed to /lib, so it will not be too big, including:
ld-linux: dynamic link library,
libc is required : standard c function library, required
libm: math library, generally required
libdl: used to dynamically load shared libraries, less used
libcrypt: encryption additional library, used by programs that need authentication, less used
libpthread: POSIX thread library, generally need

Add configuration files (ie files under /etc)

1. Add the inittab file:
Create an initialization configuration file /etc/inittab of /linuxrc following the example/inittab file of busybox.
The file specifies that the /etc/init.d.rcS script is run after the initialization of linuxrc is completed. Then run a shell in the console, the shell does not require login.

# /etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::once:/usr/sbin/telnetd -l /bin/login
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

2. Add the init.d/rcS file

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
#
#       Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
mount -a                            # 挂载在/etc/fstab中定义的所有挂载点
mkdir -p /dev/pts                   #为telnetd创建pts目录
mount -t devpts devpts /dev/pts     #挂载pts目录
echo /sbin/mdev > /proc/sys/kernel/hotplug # 设置热插拔事件处理程序为mdev
mdev -s                             #设备节点维护程序mdev初始化
mkdir -p /var/lock

hwclock -s
feed_wdg &

ifconfig lo 127.0.0.1           
ifconfig eth0 192.168.2.99

/bin/hostname -F /etc/HOSTNAME

3. Add the HOSTNAME file, the
content is the host name, you can set it at will, such as:
Blue
4. Add the fstab file:

#device         mount-point     type    options         dump    fsck order
proc            /proc           proc    defaults                0       0
tmpfs           /tmp            tmpfs   defaults                0       0
sysfs           /sys            sysfs   defaults                0       0
tmpfs           /dev            tmpfs   defaults                0       0
var             /dev            tmpfs   defaults                0       0
ramfs           /dev            ramfs   defaults                0       0

5. Add profile file
According to the content of the inittab file console::askfirst:-/bin/sh,
after the startup script etc/init.d/rcS is executed, a shell will be started in the terminal. During the shell startup process, the login environment is configured according to the file /etc/profile.
So you need to add a profile file with the following content:

USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]# '      # 这个显示的是命令行下的主机名和用户名格式,如:[root@Blue etc]#
PATH=$PATH

HOSTNAME=`/bin/hostname`

export USER LOGNAME PS1 PATH

6. Add group and passwd files:
The content of the group is as follows:

root:x:0:root

The contents of passwd are as follows:

root::0:0:root:/:/bin/sh

At this point /etc is configured, including the following:
HOSTNAME fstab group init.d inittab passwd profile

Create a device node under /dev/:

mknod console c 5 1
mknod null c 1 3

So far, the /nfsdir/tools/rootfs directory is a very small root file system, and the development board can directly start it as a network root file system. If you want to burn into the development board, you also need to make it into a file, called an image file.
The so-called making a file system image file is to store all the content in a directory into a file according to a certain format, and this file can be directly burned to the storage device. When the system starts, mount the device, and you can see the content consistent with the original directory.
Making different types of file system image files requires different tools.

Make a yaffs2 filesystem image file

Go to /nfsdir/tools/ (the last directory of the root file system)

[root@localhost tools]# mkyaffs2image rootfs root.bin  /* mkyaffs2image工具是交叉编译工具自带的*/

The generated root.bin image can be directly copied to the file system partition of nand flash, and then it can be started directly

Make jffs2 filesystem image file

mkfs.jffs2 -n -s 512 -e 16KiB -d rootfs -o root.jffs2

In the command, "-n" means not to add a clear flag to each erase block, "-s 512" indicates a page size of 512 bytes, "-e 16KiB" indicates an erase block size of 16KB, "-d" means the root filesystem directory, and "-o" means the output file.

The above is just the simplest file system. You can actually add startup programs, enrich your configuration and functions according to your own needs.

Compilation error resolution reference

1. The following error occurs in make:

miscutils/nandwrite.c: In function 'nandwrite_main':
miscutils/nandwrite.c:151: error: 'MTD_FILE_MODE_RAW' undeclared (first use in this?function)
miscutils/nandwrite.c:151: error: (Each undeclared identifier is reported only once
miscutils/nandwrite.c:151: error: for each function it appears in.)
scripts/Makefile.build:197: recipe for target 'miscutils/nandwrite.o' failed
make[1]: *** [miscutils/nandwrite.o] Error 1
Makefile:742: recipe for target 'miscutils' failed
make: *** [miscutils] Error 2

Solution:

MTD_FILE_MODE_RAW is defined in /usr/include/mtd/mtd-abi.h. Copy /usr/include/mtd/mtd-abi.h to the include file of busybox.

#gedit miscutils/nandwrite.c 

Modify the header file as follows:

#include "libbb.h"
#include "mtd-abi.h"
#include <mtd/mtd-user.h>

Compilation can pass.

2. Continue to make, and the following error occurs:

util-linux/blkdiscard.c: In function 'blkdiscard_main':
util-linux/blkdiscard.c:72: error: 'BLKSECDISCARD' undeclared (first use in this function)
util-linux/blkdiscard.c:72: error: (Each undeclared identifier is reported only once
util-linux/blkdiscard.c:72: error: for each function it appears in.)
scripts/Makefile.build:197: recipe for target 'util-linux/blkdiscard.o' failed
make[1]: *** [util-linux/blkdiscard.o] Error 1
Makefile:742: recipe for target 'util-linux' failed
make: *** [util-linux] Error 2

Solution:
BLKSECDISCARD is defined in /usr/include/linux/fs.h. The method is as described above. Copy /usr/include/linux/fs.h to the include file of busybox under linux.

#gedit util-linux/blkdiscard.c

The modifications are as follows:

#include <linux/fs.h>

Compiled.

At this point, the rootfs has basically been produced. If some content is required, you can add it yourself according to your own rootfs needs. Finally, after making the rootfs directory into an image, you can burn it to the development board.

postscript:

inittab file format:

<id>:<runlevels>:<action>:<process>: 在什么时间启动什么进程

When id and runlevels are empty, it will appear in the form of :: double colons
id: terminal name used by the process
runlevels: do not fill
in action: is the timing of program execution, including: sysinit, respawn, askfirst, wait, once, restart , ctrlaltdel, and shutdown.\ and other
processes: the application or script to be executed;
sysinit: when the system is initialized, put it in the first
respawn, askfirst is the same, if the process terminates unexpectedly, the system will tell it to restart
askfirst. Prompt Please press Enter to activate this console
wait: The process must be executed before the next
once can be executed. If the process terminates unexpectedly, it will not restart

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325391898&siteId=291194637