以前在Freescale 的i.MX和三星的2410板子上开发Linux的时候,内存容量都是32M,甚至128M的SDRAM,想怎么用就怎么用。在移植Busybox也是采取的动态链接的方式进行编译。
可是今天遇到问题了,而57的EVB的内存只有8MB,而且我的内核还不是XIP运行的,加上为了调试内核方便,采用的是O1的编译选项,大概有2.4M内核。
编译的busybox是224K,通过readelf知道其依赖动态库位libc.so.6, 为了减小文件系统大小,只拷贝要用的库,再也不能像开发2410那样把有用没有的都拷上了。把libc.so.6符号链接及其文件libc-2.3.5.so一起放在文件系统中,通过cramfs做出的大小大概为700K。
烧至Flash中,发现在Mount RAMDISK后提示运行“Failed to execute /sbin/init. Attempting defaults...”. 要是在以前,肯定又是无从下手,到处google了,或者把库一个一个拷进去试。现在有了RVDS,直接调试内核,发现是load_elf_binary的时候运行interpreter失败:
interpreter = open_exec(elf_interpreter);
retval = PTR_ERR(interpreter);
if (IS_ERR(interpreter))
goto out_free_interp;
其中使用的interpreter为ld-linux-so.2. 将该文件拷贝至lib目录下,系统就正常boot起来了。但是又有了一个新问题。由于busybox中的每一个applet都是通过符号链接指向busybox本身,因此运行applet就相当于运行一个busybox,占用的内存就是busybox的大小加上动态库libc-2.3.5.so的大小,大概是1.8M,这样,我的内存又吃紧了:
而如果直接使用静态编译的话,busybox的大小约为1M,这样启动以后的内存占用将大为减小,而且使用cramfs的文件系统只有不到500K。
同时通过查看/proc/meminfo,在使用动态编译的时候只有大概500K的MemFree,而在使用静态编译的时候有大概1.4M的MemFree。开来动静态编译的选择标准也不是一成不变的,除了调试的时候使用静态编译以外,像这种内存少的系统也可以使用静态编译来节省内存开销。