busybox-1.28.1制作根文件系统

1.源码下载
Busybox的官方源码下载路径为:
http://busybox.net/downloads/
可以下载最新的busybox-1.28.1
2.解压源码

tar xvf busybox-1.28.1.tar.bz2

3.进入源码目录

cd busybox-1.28.1

4.配置busybox
Busybox官方已经对其做了大量的默认的配置(如一些常用的shell命令:ls ,cd,mkdir等默认选择),所以我们只需要做几步简单的适配即可。
首先,执行

make menuconfig

4.1 busybox运行使用的库的选择

Settings --->
 [*] Build static binary (no shared libs)   

在这里选择编译编译静态库不依赖与任何动态链接库,编译出来的可执行文件busybox会大一点但是不过也只是1M大小。
4.2 交叉编译工具链的选择

Settings --->
    ( arm-none-linux-gnueabi-) Cross compiler prefix 

根据你自己的平台选择填写自己的工具链
4.3 安装目录的选择

Settings --->
        (./_install) Destination path for 'make install'  

这里安装目录选择当前目录的_install目录
4.4 usr相关文件生成选择

Settings --->
        [ ] Don't use /usr  

4.5 配置nsenter
将选项勾掉

 Linux System Utilities--->
    					[ ]nsenter

4.6 配置sync选项
将选项勾掉

	Coreutils--->
				[  ]sync

注:此编译选择默认是选上的,我们要手动去掉,才能编译出/usr相关目录。
5.编译
执行

make 

等待几分钟即可编译完成。
6.安装
执行

make install

结果如下:

......
   ./_install//usr/sbin/svlogd -> ../../bin/busybox
  ./_install//usr/sbin/telnetd -> ../../bin/busybox
  ./_install//usr/sbin/tftpd -> ../../bin/busybox
  ./_install//usr/sbin/ubiattach -> ../../bin/busybox
  ./_install//usr/sbin/ubidetach -> ../../bin/busybox
  ./_install//usr/sbin/ubimkvol -> ../../bin/busybox
  ./_install//usr/sbin/ubirename -> ../../bin/busybox
  ./_install//usr/sbin/ubirmvol -> ../../bin/busybox
  ./_install//usr/sbin/ubirsvol -> ../../bin/busybox
  ./_install//usr/sbin/ubiupdatevol -> ../../bin/busybox
  ./_install//usr/sbin/udhcpd -> ../../bin/busybox
--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
--------------------------------------------------

7.查看编译生成的文件
进入_install目录

cd _install/
l$ ls
bin  linuxrc  sbin  usr

可以发现生成了4个文件。
可以发现:/bin下的busybox大小为1.9M,其他的命令可执行文件都是指向它的符号链接。
如执行:ls <===> busybox ls
执行

$file bin/busybox
bin/busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.38, stripped

可以看到生成了arm架构的使用静态库的可执行文件busybox,即是安装成功
下面的步骤不进行操作,直接把以上的目录拷贝到/source/rootfs下启动开发板网络挂载,可以发现也可以进入系统且可以输入shell命令(能够输入shell命名说明了shell命令本身不是动态链接的,因为我们还没有在文件系统中放入库文件)。功能一样不少(/dev下也创建出了设备节点)但是一下的功能是没有的:
1) 系统不能运行使用动态库链接的可执行文件(何况默认情况下系统编译时会链接动态库,为了减可执行文件的体积,可以使用-static选项编译和不适用此选项编译放在根文件系统中试一下?)
2)/sys目录时空的,所以我们无法通过sysfs看到总线-设备-驱动的信息
3)/proc目录是空的,我们无法看不到内核导出的一些内核和进程信息(mount命令查看系统挂载情况都看不了,ps命令也看不到信息了)
4)Init进程解析的inittab文件没有所以采用了默认的配置
5)无法运行我们的启动程序等
这对于实际应用来说是不可忍受的,所以还需要加入其它的目录文件。
8.创建其他需要的目录

mkdir dev etc lib sys proc tmp var home root mnt  

9.lib目录下添加库文件
需要拷贝交叉工具链的库拷贝到此目录下(这里拷贝的是动态库的原因是一般程序使动态编译需要板子上动态库的支持,而静态库一般在静态编译的时候用到是编译阶段,由于交叉编译的工作放在了PC上所以不需要静态库,这样还可以减小根文件系统的体积):

cp /home/linux/tool_chain/arm-2010.09/arm-none-linux-gnueabi/libc/lib/*.so* . -a

对库文件进行瘦身(去除符号表和调试信息):

arm-none-linux-strip *

查看文件类型已经被瘦身了

 $file ld-2.11.1.so
ld-2.11.1.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped

10.etc目录下添加配置文件
10.1 添加profile文件

#!/bin/sh
export HOSTNAME=liebao
export USER=root
export HOME=home
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

进入系统就显示了如下:

...
Please press Enter to activate this console.
[root@liebao:/]#
[root@liebao:/]#cd
[root@liebao:/home]#
[root@liebao:/home]#echo $PATH
/bin:/sbin:/usr/bin:/usr/sbin

可以看到我们自定义了命令提示符,cd进入了我们制定的家目录homes,导出了环境变量。
10.2 添加inittab和rcS文件
1)在 etc 下添加文件 inittab,文件内容如下:

#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# stuff to do when restarting the init process
::restart:/sbin/init
# stuff to do before rebooting
::ctrlaltdel:/sbin/reboot

这个是init进程解析的配置文件,通过这个配置文件决定执行哪个进程,何时执行。
2)创建etc/init.d目录

mkdir etc/init.d

进入 etc/init.d
创建文件rcS这是个启动脚本(里面可以放一些系统启动的时候需要执行的脚本或者程序)
写入一段语句如:

echo “welcome to linux” > rcS

加可执行权限:

chmod +x rcS

重启开发板观察打印,打印出了这句话说明配置文件配置成功,可以在里面添加自己的可执行程序。
10.3 添加fstab文件
为了让那个系统自动挂载一些文件,需要一个fstab文件,dev下创建fstab文件:

touch fstab

文件内容如下:

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

指定挂载的文件系统。
这里我们挂在的文件系统有三个proc、sysfs和tmpfs,在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要添加tmpfs的支持
修改内核配置:

$ make menuconfig
File systems --->
       Pseudo filesystems --->
              [*] Virtual memory file system support (former shm fs)
              [*] Tmpfs POSIX Access Control Lists

重新编译内核即可(实际上,我们使用的linux4.9的内核已经配置好了)。

启动脚本/etc/init.s/rcS中添加自动挂载命令:

/bin/mount -a
/bin/mkdir /dev/pts
/bin/mount -t devpts devpts /dev/pts

第一句话为:将会执行/etc/fstab文件
第二三句为:创建虚拟的devpts 文件系统用于用于伪终端设备(当我们使用telnet或者ssh等登陆系统的时候就会自动在/dev/pts/下创建/dev/pts/0,/dev/pts/1等表示这些终端设备)
重启开发板,执行mount命令:

[root@liebao:/]#mount
172.16.21.104:/source/rootfs on / type nfs (rw,relatime,vers=2,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=udp,timeo=11,retrans=3,sec=sys,mountaddr=172.16.21.104,mountvers=1,mountproto=udp,local_lock=all,addr=172.16.21.104)
devtmpfs on /dev type devtmpfs (rw,relatime,size=469156k,nr_inodes=117289,mode=755)
sysfs on /sys type sysfs (rw,relatime)
proc on /proc type proc (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)

挂载上了我们需要挂载的文件系统,这个时候查看/sys和/proc下都有了相应的文件(这时ps命令才可以从proc中读取进程相关信息)。
10.4 使能mdev功能
以上基本上实现了文件系统应该有的功能,但是我们知道“linux一切皆文件”,对于设备的访问都抽象为对文件的访问,所以就有了设备文件节点的概念,所以需要创建出设备节点后才能访问设备,手动创建不切实际,linux采用udev机制自动创建设备节点,嵌入式中使用小型的mdev来读取内核信息创建设备文件。
在/etc/init.d/rcS中添加:

/sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

第一句:为设置内核热插拔,当有设备的热插拔时调用/sbin/mdev
第二句:为在/dev下生成内核支持的所有的设备节点
重启开发板,系统mdev就会扫描/sys/dev/block 和/sys/dev/char下的文件自动创建设备节点。
11.dev目录下添加设备文件
需要创建两个设备文件:

mknod /dev/console c 5 1
mknod /dev/null c 1 3

其实,不创建这两个文件系统也能够自动创建。

现在我们的系统就完全可以使用了,功能也基本完善了。

注:有关linux4.9.9内核的移植见《移植最新的linux4.9.9内核(适配fs4412平台)》:
http://blog.csdn.net/liebao_han/article/details/79436819
文章内容持续更新。


三、编译错误解决办法

出现如下错误:

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

解决办法:

MTD_FILE_MODE_RAW在/usr/include/mtd/mtd-abi.h中定义,直接在nandwrite.c中包含<mtd/mtd-abi.h>编译仍无法通过。将/usr/include/mtd/mtd-abi.h拷贝到busybox的include文件中,然后包含该头文件:

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

编译可以通过。

继续make,出现如下错误:

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

解决办法:

BLKSECDISCARD在/usr/include/linux/fs.h中定义,方法如上所述,将/usr/include/linux/fs.h拷贝到busybox的include文件中,然后修改blkdiscard.c中头文件包含:

修改:#include <linux/fs.h>为

#include “fs.h”

继续make,编译通过,但是在链接的时候出现问题:

networking/lib.a(nslookup.o): In function print_host': nslookup.c:(.text.print_host+0x44): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking debianutils/lib.a(mktemp.o): In functionmktemp_main’:
mktemp.c:(.text.mktemp_main+0x98): warning: the use of mktemp' is dangerous, better usemkstemp’
networking/lib.a(ipcalc.o): In function ipcalc_main': ipcalc.c:(.text.ipcalc_main+0x25c): warning: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking libbb/lib.a(inet_common.o): In functionINET_resolve’:
inet_common.c:(.text.INET_resolve+0x60): warning: Using ‘gethostbyname’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
networking/lib.a(inetd.o): In function reread_config_file': inetd.c:(.text.reread_config_file+0x230): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking networking/lib.a(netstat.o): In functionip_port_str’:
netstat.c:(.text.ip_port_str+0x50): warning: Using ‘getservbyport’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
util-linux/lib.a(nsenter.o): In function nsenter_main': nsenter.c:(.text.nsenter_main+0x1b0): undefined reference tosetns’
collect2: ld returned 1 exit status
Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.
Example: CONFIG_EXTRA_LDLIBS=“pthread dl tirpc audit pam”
Makefile:717: recipe for target ‘busybox_unstripped’ failed
make: *** [busybox_unstripped] Error 1

解决办法:

make menuconfig

Linux System Utilities—>nsenter,去掉该选项,重新编译make,又出现如下错误:

networking/lib.a(nslookup.o): In function print_host': nslookup.c:(.text.print_host+0x44): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking debianutils/lib.a(mktemp.o): In functionmktemp_main’:
mktemp.c:(.text.mktemp_main+0x98): warning: the use of mktemp' is dangerous, better usemkstemp’
networking/lib.a(ipcalc.o): In function ipcalc_main': ipcalc.c:(.text.ipcalc_main+0x25c): warning: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking libbb/lib.a(inet_common.o): In functionINET_resolve’:
inet_common.c:(.text.INET_resolve+0x60): warning: Using ‘gethostbyname’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
networking/lib.a(inetd.o): In function reread_config_file': inetd.c:(.text.reread_config_file+0x230): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking networking/lib.a(netstat.o): In functionip_port_str’:
netstat.c:(.text.ip_port_str+0x50): warning: Using ‘getservbyport’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
coreutils/lib.a(sync.o): In function sync_main': sync.c:(.text.sync_main+0x7c): undefined reference tosyncfs’
collect2: ld returned 1 exit status
Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.
Example: CONFIG_EXTRA_LDLIBS=“pthread dl tirpc audit pam”
Makefile:717: recipe for target ‘busybox_unstripped’ failed
make: *** [busybox_unstripped] Error 1

解决办法:

make menuconfig

Coreutils—>sync选项去掉,重新make编译通过,生成了busybox可执行文件。

具体选项是什么意思还不太清楚,需要进一步理解。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值