ARM嵌入式linux复习心得总结(3)--2011.10.11 Evo Yang

2019-07-13 01:45发布

  2011.10.10 Evo Yang ARM嵌入式linux复习心得总结3: 一、前言:今天主要是学习了两个方面一个是内核的编译实验,另一个是交叉编译的安装,还是那句话错误与进步同在,正视错误才会有进步,本来这两个实验应该是很容易就能完成的,可是经过我的手就不是那个味儿了,几乎每一步都会出现问题,要是放在以前恐怕我就要放弃了,不过放弃这个词我已经摒弃很长时间了,不断的从未知发现新知中寻找快乐,这就是我的生活,现在做每一步比别人多走点儿弯路,以后就会少走一些弯路,现在是学习的时刻,无处不再的错误就等同于无处不在的新知识新机遇! 二、内核的编译实验: 这里我一开始使用的是从网上下载的一些内核,都是在一个网站上下的,我首先遇到的第一个问题就是解压命令的问题,由于自己的不仔细以及对Linux的不熟悉导致了自己以为Linux一般的压缩扩展名为tar、zip、tar.gz这几个因此在解压从网络上下载的内核文件是使用tar的命令解压tar.bz2文件的,现在知道了原来自己也当了一会儿井底之蛙啊~在这里我查阅了一下网上的资源,关于tar等的解压以及压缩命令其实多的令人发指啊,下面是我所查阅的tar资源(先对作者说声抱歉我忘了资源引用的地址了下次注意!) 1、tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。 -z:有gzip属性的 -j:有bz2属性的 -Z:有compress属性的 -v:显示所有过程 -O:将文件解开到标准输出   下面的参数-f是必须的 -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。   # tar -cf all.tar *.jpg 这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。 # tar -rf all.tar *.gif 这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。 # tar -uf all.tar logo.gif 这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。 # tar -tf all.tar 这条命令是列出all.tar包中所有文件,-t是列出文件的意思 # tar -xf all.tar 这条命令是解出all.tar包中所有文件,-x是解开的意思 压缩   tar –cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg tar –czf jpg.tar.gz *.jpg   //将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gz tar –cjf jpg.tar.bz2 *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2 tar –cZf jpg.tar.Z *.jpg   //将目录里所有jpg文件打包成jpg.tar后,并且将其用compress压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Z rar a jpg.rar *.jpg //rar格式的压缩,需要先下载rar for linux zip jpg.zip *.jpg //zip格式的压缩,需要先下载zip for linux   解压   tar –xvf file.tar //解压 tar包 tar -xzvf file.tar.gz //解压tar.gz tar -xjvf file.tar.bz2   //解压 tar.bz2 tar –xZvf file.tar.Z   //解压tar.Z unrar e file.rar //解压rar unzip file.zip //解压zip   总结 1、*.tar 用 tar –xvf 解压 2、*.gz 用 gzip -d或者gunzip 解压 3、*.tar.gz和*.tgz 用 tar –xzf 解压 4、*.bz2 用 bzip2 -d或者用bunzip2 解压 5、*.tar.bz2用tar –xjf 解压 6、*.Z 用 uncompress 解压 7、*.tar.Z 用tar –xZf 解压 8、*.rar 用 unrar e解压 9、*.zip 用 unzip 解压 找到相关的代码将其解压成功! 2、解压后进入内核文件夹然后执行 #make distclean     //清理内核中间文件,配置文件 3、现在选择参考配置文件、在这里当我选用我现在使用的内核配置文件的时候(我的内核是2.6.18的)然后输入 #cp /boot/config-2.6.18-53.e15 .config作为配置参考(这里我不知道是不是必须的,记录下来等明天有网的时候在查查吧!)然后出现了许多错误,同样的在其他版本的内核下也出现了很多错误,为此我十分不解,于是查看了一下内核文件发现了“x86_64”字样,于是我怀疑这些内核是64位的(不知道我的猜测对不对记录下来同样查一查)还有就是为了是错误率减小,我直接下载了和我目前使用的相同的内核,至此才完美的成功编译。 4、选择完内核配置参考后输入#make menuconfig 配置内核,这个是最常用的图形化界面内核配置的方法,比较方便,这个命令是很必要的充分实现了嵌入式系统的软件可裁减性,还有就是如果作为配置arm等嵌入式平台的内核的话就不是使用这个命令了。 5、直接编译内核,输入命令:#make bzImage    //这里要着重注意一个方面就好似bzImage这个单词第三个字母是大写的”I”  使用的时候就吃过亏没有看清楚。上面为什么说是完美成功编译呢,原因出在内核编译完毕之后的内核文件,Linux内核镜像文件应该被编译在arch/x86/boot/下的bzImage文件夹下的bzImage(使用时将bzImage镜像文件烧入arm中)但自己编译完成之后arch文件夹下并没有出现x86文件,更不用说bzImage文件了有的就是个x86_64而里面也没有,这时我从网上得知这种情况bzImage文件也有可能出现在arch/i386/boot文件下。 6、内核模块的编译使用:(内核模块的编译时间较长) #make modules 7、安装内核模块的编译使用: #make modules_install 三、交叉工具链的安装和使用,自己在这个部分学习到了许多正常情况下不能学习到的东西,首先先简单介绍一下arm-linux工具链的作用:用自己的话来说就是在x86的机器上编译arm的应用程序的工具,要知道,编译工具是根据平台的不同而不同的,因此在arm的芯片上使用就要使用arm的编译工具例如,arm-linux 4.3.2交叉工具链,正常情况是安装arm-linux 4.3.2工具链而我使用的是arm-linux 4.4.2版本工具链,我的系统是红帽的5.5服务器版,在这里就会出现问题,这个问题到后面在讨论,工具链解压的时候一般都会解压到“/usr/local/”文件下因此这里的解压命令就需要修改一下在这里我使用命令: 第一步:#tar zxvf arm-linux-gcc-4.4.2.tgz –C/  (这个命令是将文件解压到根目录里面) 第二步:#vim /root/.bashrc (修改环境变量,使这个工具链在本机的任何地方都可以直接使用)添加 export PATH=$PATH:**********************/bin    (“**”代表工具链所解压到的目录)这样我们就可以在源文件所在的目录下直接使用命令: “#arm-linux-gcc hello.c –o hello”    (假设源文件为“hello.c”) 做完这几步之后编译一个简单的源文件hello.c使用上面那个命令测试一下是否正常使用: #arm-linux-gcc hello.c –o hello 这里就会出现之前我所说的问题: “交叉编译出错提示 /opt/FriendlyARM/toolschain/4.4.3/libexec/gcc/arm-none-linux-gnueabi/4.4.3/cc1: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /opt/FriendlyARM/toolschain/4.4.3/lib/libppl_c.so.2) /opt/FriendlyARM/toolschain/4.4.3/libexec/gcc/arm-none-linux-gnueabi/4.4.3/cc1: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by    /opt/FriendlyARM/toolschain/4.4.3/lib/libppl.so.7)”          从上面看我理解的意思是在于’ GLIBCXX_3.4.9’以及“/libstdc++.so.6”这两个文件的问题,     网上也有许多出现这种情况于是我将解决方法记录下来: 原因其实就是版本的问题在之前我的电脑是Linux 红帽5.5这个版本对于现在红帽 9来说真正是老古董级别因此对于现在比较新的arm-linux-4.4.2来说是不兼容的,问题及解决方案如下: (1)       ls -l /usr/lib/libstdc++.so.6 它链接到libstdc++.so.6.0.8 不支持GLIBCXX_3.4.9 (2) 下载libstdc++.so.6.0.10   把该文件放在/usr/lib中。 (3) 删除libstdc++.so.6与libstdc++.so.6.0.8的软链接这里网上有一些方法我看大部分的人说使用直接rm 就行,我一开是信了不过我首先先cp了一下以防万一,因为我觉得软链接应该不会就这么直接删除文件就可以了应该在源代码上作修改,结果和我料想的一样rm之后我使用命令: #ls –al 结果出现了一个红 {MOD}的一行标志,这行标志显示的正是原先/usr/lib/libstdc++.so.6 -> /usr/lib/libstdc++.so.6.0.8的软链接,我首先忽略他然后直接使用命令: # ln -s /usr/lib/libstdc++.so.6.10  /usr/lib/libstdc++.so.6 这个命令是建立ibstdc++.so.6.10与/usr/lib/libstdc++.so.6的软链接命令,结果出现“文件已经存在”字样,#ls –al 后发现依然显示红 {MOD}表示,经上网调查找到了真正删除软链接的方法: #unlink libstdc++.so.6 使用unlink这个命令直接删除了这个文件的软链接然后使用链接命令问题解决! (4)小结:在安装核心程序的时候首先需要查询一下兼容的版本! 四、这里总结几种程序不能运行的例子以便今后开发时便于纠错:          1、确认平台:                    这个是作为arm程序员非常基本的东西一定要注意你编译的程序到底是运行在那个平台上的程序,否则是不能运行的,这作为开发确认的第一步,这一步主要是注意使用哪个编译工具就行比如 交叉工具链 arm-linux-gcc 而不是 gcc! 2、确认大小端!          这个是一个很让人忽略的问题因为一般人不会去想他,但是如果出现这个问题那也是无论如何也不会编译成功的,问题在于,当你做内核移植的时候这个系统是小端的系统结果你给编译成大端的程序,这样你无论如何都不会移植成功的,解决方法就是换一个小端的编译工具即可查看方法命令如下: #arm-linux-readelf –a 查看是little 还是large! 3、查看动态链接库命令: #arm-linux-readelf –d  查看动态链接库使用的是哪个Shared library: [libc.so.6] 这个命令主要是在当你编译源文件的时候明明源文件在当前目录下但是系统总会报错“没有这个源文件”这种情况就应该是当前源文件使用的动态链接库丢失,解决方法有两种: (1)可以将丢失的动态链接库拷贝一遍即可 (2)编译的时候使用命令 例如 #arm-linux-gcc hello.c –o –static hello 这样将编译成静态的文件如果现在再使用arm-linux-readelf –d命令就会提示没有发现动态链接信息。 四、总结:内核中有许多自己平常没有注意的东西,这些都需要常年的积累,庆幸自己比较笨总是出现问题,也庆幸自己比较聪明,善于解决问题。