ITEEDU

动态编译busybox

进入Build Options时,不要选择Build Busybox as a static binary,其他所有操作步骤跟静态编译一样,你会发现这样建立的文件系统无法启动,终端上打印出如下消息:

 Kernel  panic-not synving:No init found. Try passing init=option to kernel.

为什么会出现这种问题呢?这就得回到两种编译方式的特点上来。静态编译时是将所用到的库文件一起编译了进去,而动态编译时是在需要时才调用相应的库。我们选择动态编译后,没有添加任何库文件就运行,显然是会出错的。那么如何查看busybox可执行文件里使用的库呢。ldd和Readelf都可以显示。

ldd

下面是查看cat的库的结果,linux-gate.so.1是与内核通信的,不用管。所有程序其实都是通过ld-linux.so.2来找库文件的,它就是一个中介,必不可少。

#ldd /bin/cat
linux-gate.so.1 =>  (0x00bfe000)
libc.so.6 => /lib/libc.so.6 (0x00a4a000)
/lib/ld-linux.so.2 (0x00a28000)

readelf

下面是编译的ARM上的系统的库文件查找。

# arm-uclibc-linux-readelf -d busybox 
Dynamic section at offset 0xca014 contains 18 entries:

标记 类型 名称/值
0x00000001 (NEEDED) 共享库:[libm.so.0]
0x00000001 (NEEDED) 共享库:[libc.so.0]
0x0000000c (INIT) 0xbe24
0x0000000d (FINI) 0xb2054
0x00000004 (HASH) 0x80e8
0x00000005 (STRTAB) 0xa500
0x00000006 (SYMTAB) 0x8b70
0x0000000a (STRSZ) 3259 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0xda0cc
0x00000002 (PLTRELSZ) 3040 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0xb244
0x00000011 (REL) 0xb1bc
0x00000012 (RELSZ) 136 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000000 (NULL) 0x0

从上面的结果中,我们可以看到,busybox这个程序使用到了libm.so.0和libc.so.0两个库文件,实际上这是2个符号链接,分别指向libc-0.9.28.so和libuClibc-0.9.28.so。

将以上四个文件分别拷贝到lib目录下。按理说,这样应该就可以了,但是仍然无法正常运行。显示的错误信息和刚刚没加库之前一样。可能的原因有2种:一是库文件没有添加全,二是库文件没有正确被加载。

根据readelf显示的结果应该不是第一种原因。那么到底为什么没被正确加载呢?原来库文件的加载,还需要一个共享库加载器。找到对应的文件ld-uClibc-0.9.28.so和ld-uClibc.so.0添加到lib目录下后。运行正常。