如何使用busybox编译和生成最简lin

如何使用busybox编译和生成最简lin,第1张

在ubuntu系统下创建一个rootfs目录,用于存放busybox生成的根文件系统,也可设置为nfs的挂载目录,直接通过网络文件系统进行挂载,便于开发。我自己就将该目录创建在/opt/FriendlyARM/mini2440/rootfs处。并在该目录下创建一些必备的子目录:

leon@Ubuntu:/opt/FriendlyARM/mini2440/rootfs$ mkdir bin dev etc proc sbin sys tmp usr leon@Ubuntu:/opt/FriendlyARM/mini2440/rootfs$ ls bin dev etc proc sbin sys tmp usr

1、修改Makefile配置

进入busybox目录,修改Makefile文件,在文件头处加入内容如下:

ARCH ?= arm CROSS_COMPILE ?= arm-linux-

2、修改配置文件

make menuconfig

选择Busybox Settings—>

1、Build Options—>,选择[*] Build Busybox as a static binary(no shared libs); 2、Installtion Options,在busybox instantlltionprefix一栏中,输入你想要创建rootfs的目录。比如我的是/opt/FriendlyARM/mini2440/rootfs。

3、去掉Coreutils—>sync选项;

4、去掉Linux System Utilities—>nsenter选项;

保存,退出。

3、编译源码

输入make,进行编译;这其中估计会遇到一些错误,可参见我的另外一篇博客(linux(ubuntu)编译busybox遇到的问题处理办法)。编译成功后,会给出以下提示:

LINK busybox_unstripped Static linking against glibc, can't use --gc-sections Trying libraries: crypt m Library crypt is not needed, excluding it Library m is needed, can't exclude it (yet) Final link with: m DOC busybox.pod DOC BusyBox.txt DOC busybox.1 DOC BusyBox.html

编译通过之后,输入make install命令进行安装,busybox会自动将rootfs根文件系统安装到之前设置的目录下。

用busybox,一般就不用其他软件,busybox包含了很多命令,用busybox制作的根文件系统对大部分嵌入式设备来说,功能足够了

但对于普通pc用户,busybox的功能弱,扩展性差,通用性差,所以不建议用busybox作为日常使用

用ramdisk是因为,系统在启动时为了顺利加载scsi设备,或者如果有某种原因导致内核和必要工具加载失败时,启动ramdisk帮助加载和供用户修复,ramdisk一般要求精简,用busybox做ramdisk最适合了

选定 busybox-1.9.2.tar.bz2 这个版本, 以静态方式编译, 即生成的 busybox 不需要共享库的支持就能运行。这样做我们就不需要布署程序库了。缺点是自己写的 arm-linux 程序在这个根文件系统中是不能运行的,因为缺少共享程序库的支持。不过不用担心,通过在目标机里以挂接 NFS 的方式, 将宿主机的 arm-linux-gcc 编译器的库文件挂到 arm-linux 的 /lib 下, 就可完美的运行我们自己的程序了。

现在开始制作静态链接库的根文件系统。

1、准备根文件系统

首先准备制作工具BusyBox1.9.2。

准备交叉编译工具arm-linux-gcc 3.3.2。

在机器上建立rootfs的文件夹

#mkdir rootfs

在rootfs中建立linux系统中典型的文件夹

#cd rootfs

#mkdir root home bin sbin etc dev usr lib tmp mnt sys proc

#mkdir usr/lib usr/bin

#pwd

/home/su/rootfs

2、解压源码包

#tar xjf busybox-1.9.2.tar.bz2

#cd busybox-1.9.2

3、修改 Makefile,

#vi Makefile

将Makefile中的

CROSS_COMPILE ?=

改为

CROSS_COMPILE ?= /usr/local/arm/3.3.2/bin/arm-linux-

注:这个版本的 busybox 用 3.4.1 的 arm-linux-gcc 编译有些问题, 用 3.3.2 版则可顺利编译。

4、定制 busybox

选择busybox下全部的可执行程序

#make defconfig

进到配置选项

#make menuconfig

设置静态编译方式

Busybox Settings --->Build Options --->[*] Build BusyBox as a static binary (no shared libs)

Busybox Settings --->Install Options --->中输入建立根文件系统的文件所在的路径/home/su/rootfs。

其它的默认。

确保 [*] Build BusyBox as a static binary (no shared libs) 被选中,保存退出

5、执行 make 编译

#make

编译出错, 信息如下:

applets/applets.c:15:2: warning: #warning Static linking against glibc produces buggy executables

applets/applets.c:16:2: warning: #warning (glibc does not cope well with ld --gc-sections).

applets/applets.c:17:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400

applets/applets.c:18:2: warning: #warning Note that glibc is unsuitable for static linking anyway.

applets/applets.c:19:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections

applets/applets.c:20:2: warning: #warning from scripts/trylink and remove this warning.

applets/applets.c:21:2: error: #error Aborting compilation.

make[1]: *** [applets/applets.o] Error 1

按照提示,修改文件 applets/applets.c 第 21 行, 将

#error Aborting compilation.

注释掉:

执行 make 重新编译

#make

编译通过, busybox 被生成了, 然后执行

#make install

busybox 就被安装到指定的路径下了/home/su/rootfs,这时可发现rootfs下多了个liunxrc的文件,bin、sbin下也多了很多文件。用ls –l命令查看其中的一个文件,可发现其是链接到busybox的一个连接符,所以我们之后在目标机上运行的命令大多都会调用busybox这个文件的。

若之前忘了指定路径,默认生成到临时目录busybox-1.9.2/_install 下了。

6、编写配置/etc下的初始化程序(可省略)

最简单的做法是把busybox-1.9.2/examples/bootfloppy/etc下的全部文件拷到目标文件的etc目录下

#cd /home/su/busybox-1.9.2/examples/bootfloppy/etc

#cp –rf * /home/su/rootfs/etc

也可自己写这些文件。

7、把rootfs做成镜像

#mkcramfs rootfs rootfs.cramfs

8、把rootfs.cramfs烧写到目标机中。

9、运行目标机

这时会遇到一个错误信息:

Can’t open tty2

Can’t open tty3

Can’t open tty4

解决办法:把/rootfs/etc/ inittab 文件的第三行“tty2::askfirst:-bin/sh”删除掉。

返回到第7步重做。

现实中,动态编译的方法更适合工程的需要,所以一般是采用动态的方法编译根文件系统的。若选择动态编译的办法,大体方法还是一样的,存在一些不同之处是:

不同之处之一是:

进到配置选项

#make menuconfig

选择动态方式

Busybox Settings --->Build Options --->[*] Build Shared libbusybox

不同之处之二是:

上面静态编译出现的出错信息不会出现了,所以不需对程序做任何修改,但还是必须用arm-linux-gcc 3.3.2编译,否则还是会有麻烦。

不同之处之三是(最大的不同之处):

编译完成后,需进到rootfs目录的lib中,往里面添加一些库文件

#cd /home/su/rootfs/lib

这里有点麻烦,我怎么知道需要什么库文件的支持呢?

最简单的办法是把arm-linux-gcc 3.3.2下的整个lib库拷进来,简单省事。但是这么做存在一个问题,做出的根文件系统非常大。

另一个办法是:

#cd /home/su/rootfs/bin

#arm-linux-readelf busybox | grep shared

这样就可以显示出系统运行起来需要什么库文件,再把相应的库文件拷到/home/su/rootfs/lib下。一般而言,系统库用到两个:动态链接器ld-linux.so和c函数库Glibc,Glibc包括:

ld-linux:动态链接库,必需

libc: 标准c函数库,必需

libm: 数学库,一般需要

libdl: 用于动态装载共享库,较少用到

libcrypt: 加密附加库,需要认证的程序用到,较少用

libpthread: POSIX线程库,一般需要

如果需要某个函数库,我们可以将这些库和对应的符号链接拷到目标根文件系统的/lib目录下。简单起见,应该使用-d选项或-a选项调用cp命令,这样可保留完整的符号链接信息。

例:

#cp –a libc.so.6 /home/su/rootfs/lib/

为了减少运行时库的大小,我们应该使用交叉编译版本即arm-linux-gcc 3.3.2的strip工具来处理根文件系统的库文件,把二进制文件中的包含的符号表和调试信息删除掉。

例:

#arm-linux-strip /home/su/rootfs/lib/*.so

注意:

使用busybox做文件系统时,运行make命令,系统会马上显示:

没有/dev/null这个文件

但是还是能最终编译出根文件系统,问题出在重启linux系统,机器进不去了。提示出错,信息如下:

/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 200:/dev/null: read-only file system

.

.

.

***An error occured during the file system check.

***Dropping you to a shellthe system will reboot

***when you leave the shell

Give root password for maintenance

(or type Control-D to continue):

解决办法:

按提示输入root用户的密码,回车,可看到

(Repair filesystem)1#:

依次输入命令:

(Repair filesystem)1# mount -n -o remount,rw /

(Repair filesystem)1# rm -f /dev/null

(Repair filesystem)1# mknod -m 0666 /dev/null c 1 3

(Repair filesystem)1# reboot

问题解决。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/6253233.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-19
下一篇 2023-03-19

发表评论

登录后才能评论

评论列表(0条)

保存