在ARM Linux上编译helloworld时候的抓狂经历
想在我的fl2440上运行一个helloworld,在三、五个月前,我曾经编写过一个helloworld,跑在开发板上,当时编译和运行都很顺利,所以就没有把相关的操作过程记录下来。在随后的几个月里,一直在研究linux底层驱动的开发,所以一直都没有开发过上层应用程序。现在,由于想编写一个上层应用来测试一下底层驱动程序的时候,又想再编译一下helloworld,因此,也就开始了我无比挫折的开发helloworld程序的曲折历程,过程无比抓狂和令人吐血,从没想过helloworld会如此困难,因此记录下来,以便网友和我自己参考。
1,编写helloworld.c,内容包含了stdio.h头文件,并在main函数中只调用printf函数输出helloworld,如此简单,和普通helloworld没有区别。arm-linux-gcc helloworld.c -o helloworld,编译顺利完成,生成helloworld.
2,将helloworld拷贝到开发板中,直接运行:./helloworld,输出错误:permission denied. 然后调用chmod +x helloworld, ./helloworld, 然后输出错误信息“-sh ./helloworld: not found”。噩梦从此开始。
3,我认为这个not found的错误应该是开发板内缺少某些库的原因,因此赶紧去找库。查到arm-linux-elfread -a helloworld | "shared library" 可以看到程序依赖哪些库,结果查出依赖“libc.so.6”
4,libc.so.6是libc-2.8.so的链接,因此,我拷贝libc-2.8.so到开发板中,然后在开发板中手动用“ln -s libc-2.8.so libc.so.6”为库建立了链接,然后,运行./helloworld,结果发现出错信息还是“not found”。因此我再想是不是还缺少别的库。
5,进入Ubuntu调用"arm-linux-elfread -a helloworld"这回输出内容比较多,然后找来找去,好像里面说到一个"ld-linux-2.8.so.3",于是在开发板的/lib文件夹下ld-linux-2.8.so.2,改成了ld-linux-2.8.so.3。./helloworld,这回终于不说“not found”了,但是出错信息又成了“error when use library libc.so.6, can't handle TLS data”。
6,我觉得吧,以前调试helloworld真没这么麻烦,但是没办法,还要继续,我已经抓狂状态了。没办法还是老老实实地把ubuntu上交叉编译器当中的ld-2.8.so考到开发板中了,刚才没考,然后自己创建链接,然后./helloworld,这回又出现了新的错误“segmentation fault”.然后我就又开始在网络上搜这个问题的解决办法。基本上毫无头绪。
7,我回忆以前helloworld成功的时候,还没有自己修改和编译内核,而且我的内核是使用arm-linux-gcc 4.3.2编译的,但是原厂开发板应该是3.4.1编译的,而且我的文件系统也使用的是原厂提供的文件系统,我猜会不会是内核和文件系统编译版本不同造成的?所以,重新烧写了原厂内核,然后再进入文件系统,运行./helloworld,但是仍然报错,然后抓狂,然后一口黑血吐在屏幕上。
8,回到ubuntu,修改环境变量,把arm-linux-gcc 4.3.2换成 3.4.1,重新编译helloworld,然后考到开发板中,然后把我之前考到/lib目录下的所有库和相应链接都删掉,保留以前系统自带的库,然后./helloworld,结果终于显示出了挨千刀的 hello world!
9,重新烧写我自己用arm-linux-gcc 4.3.2编译的内核,然后运行helloworld,这回仍然正常,这就证明helloworld的正常运行和文件系统的编译方式紧密相关(文件系统是arm-linux-gcc3.4.1编译的),而和内核的编译器版本关系不大,起码事实证明了这点。