原创 软浮点的交叉编译器与arm7

2009-10-29 16:23 5866 11 11 分类: MCU/ 嵌入式

接上一篇日记:
在上一篇日记中,主要在AXD裸奔代码(bin),其实是没什么意义的,我只是想一步一个脚印把做过的事情写下来,每一个历程也许都会


打击你,但也只有这样才会触发你学习的热情。
Led_test.bin裸奔成功,考虑到com口在debug的重要,我就顺手写了一个带hello world的Led_test.bin。在ubuntu 9.04下make很顺利,


然后用AXD裸奔,一点击go马上发生一个异常!step调试确定异常发生在Uart_Init初始化过程,注意这个函数有浮点运算!以前我们用


63f19e73-f6c2-42ae-a985-8a15095400bb.JPG


IDE集成开发环境下,没留意有这个问题啊,现在用的这个交叉编译器arm-linux-编译连接过程也没报错哦。对arm7tdmi能不能进行浮点


运算心里是一点概念也没有,以下摘自google:
--------------------------------------------------------------
多数ARM Linux内核编译的文章或手册都会说
由于arm没有浮点协处理器,所以需要一个模拟浮点机制,
在配置内核时一定要选择一个浮点模拟器NWFPE,如下
--- At least one math emulation must be selected │ │
│ │  NWFPE math emulation │ │
│ │ [ ] Support extended precision │ │
│ │  FastFPE math emulation (EXPERIMENTAL)
假如没有浮点模拟器,就会出现错误。比如未定义的指令:
init (1): undefined instruction: pc="4004b020"
Code: e3a01000 00000000 00000000 00000000 (eca0420c)
实际上,即使使用了NWFPE,系统的浮点问题也并没有完全解决


NWFPE模拟浮点是利用了undefined instrction handler
即每次浮点指令操作,都会发生一次未定义指令异常(exception),
在这个异常的handler里面,用软件的方法仿真一个浮点指令
假如软件里的浮点运算比较多,那岂不是不停的请求CPU执行undefined instruction,然后产生异常?
答对了,内核模拟浮点指令事实上就是这么回事
这么做带来的后果是带来极频繁的exception,大大增加中断延迟
换句话说,降低系统实时性
另外,每发生一次浮点操作,都要陷入到exception,不难想见会带来极大的性能开销。
内核模拟浮点指令,要实现一个大的case switch
通常情况这个分支预测都会不命中,既要多浪费cpu clock
还会排空BTB,进一步降低后面分支预测命中率


怎么办???使用软浮点!


软浮点支持是由交叉工具链提供的功能,和Linux内核无关
当使用软浮点工具链编译浮点操作时,编译器会用内联的浮点库替换掉浮点操作
使得生成的机器码完全不含浮点指令,但是又能够完成正确的浮点操作
由于是在编译时优化,这种方式能够让CPU即使作浮点运算时也能够执行连续的指令,减少程式分支
使用软浮点工具链编译产生的浮点操作速度较快
比NWFPE模拟快一个数量级


我们怎么知道交叉工具链是否支持软浮点呢?
很简单,使用编译命令时加上-msoft-float这个CFLAGS就能够了,比如
arm-linux-gcc test。c -msoft-float -o test
假如工具链支持软浮点,那么就能够生成可执行文档
如出错,对不起,该工具链不支持
另一个鉴定的方法,拿到一个编译产生的文档,使用
arm-linux-readelf -e test
能够打印出elf文档头信息
在里面看到software FP就是软浮点格式,否则不是
Flags: 0x202, has entry point, GNU EABI, software FP


---------------------------------------------------------------
我简单测试下自己机子里面的arm-linux-gcc,糟糕的很,不支持软浮点,可恨的是连接过程干吗不报错哦。
只好把它卸了!重新搞一个支持软浮点的交叉编译器!
ubuntu比较麻烦,外表漂亮,但是什么也没装!


1)
保证你的Ubuntu 安装了如下的软件:
Bison flex build-essential patch libncurses5-dev
安装这些软件包:
sudo apt-get install Bison flex build-essential patch libncurese5-dev


2)
准备软件包


gcc-3.4.5.tar.gz


glibc-2.3.6.tar.gz


linux-2.6.8.tar.gz


crosstool-0.43.tar.gz


binutils-2.15.tar.gz


glibc-linuxthreads-2.3.3.tar.gz


linux-libc-headers-2.6.12.0.tar.bz2


3)
修改系统配置
Ubuntu 9.04默认安装的 gcc 版本为4.3.3,这个版本对于语法要求较高,编译会出错,目前不宜选用,于是选择了 gcc-4.1.1 ,但并不


需要卸载 gcc-4.3.3。
sudo apt-get install gcc-4.1
装好gcc4.1后
sudo rm /usr/bin/gcc (删除GCC,它只是个到gcc-4.3.3的软链接文件)
sudo ln -s /usr/bin/gcc-4.1 /usr/bin/gcc (建立GCC到gcc-4.1的软链接)
修改sh版本
如果运行ls -la /bin/sh
看到链接的是 dash ,则请运行以下命令
sudo dpkg-reconfigure dash
选择 no 以删除 dash
此处如果不改好的话,编译时会出现错误


4)解压crosstools-0.43,并进入该目录,查看重要的脚本文件。
$cd downloads
$tar –zxvf crosstool-0.43.tar.gz
$cd crosstool-0.43
选用demo-arm-softfloat.sh 就是建立目标为支持软浮点的arm交叉编译工具链。
$sudo gedit demo-arm-softfloat.sh
根据需要修改下面两句
TARBALLS_DIR=$HOME/downloads //表示下载的源码的存放目录
RESULT_TOP=/opt/crosstools //表示生成的工具链的存放目录


5)修改 gcc-3.4.5-glibc-2.3.6.dat
$ sudo gedit gcc-3.4.5-glibc-2.3.6.dat
根据需要修改内容:
BINUTILS_DIR=binutils-2.15
GCC_DIR=gcc-3.4.5
GLIBC_DIR=glibc-2.3.6
LINUX_DIR=linux-2.6.8
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.6


5.$ ./ demo-arm-softfloat.sh


痛苦的等待(半个小时左右)


6)修改环境变量


修改环境变量有多种方法
第一种方法:在当前用户目录的.bashrc中添加如下内容
$export PATH=$PATH:/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin:
第二种方法:直接修改/home/linux/.bashrc
添加如下内容:
PATH=$PATH:/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin:
然后
source .bashrc
7)执行如下命令
$ arm-softfloat-linux-gnu-gcc -v
显示
....gcc version 3.4.5
ok交叉编译环境创建成功!


8)恢复我们修改的系统配置:
恢复gcc为4.3
sudo rm /usr/bin/gcc
sudo ln -s /usr/bin/gcc-4.3 /usr/bin/gcc
重新安装dash
sudo dpkg-reconfigure dash
选择 yes 以重新安装 dash



-----------------------------------------------------------------------------------------------
一天有差不多过去了!!我们来试试支持软浮点交叉编译器。哈哈连接的时候显示找不到符号定义!


点击看大图


找了下gcc的手册,在softfloat这一
可以看到这里出错的几个符号,就是说我们这个支持softfloat的编译器没有连接上softfloat函数库。于是我们在ld里面指定这几个函数
库。


点击看大图
make正常通过,在AXD裸奔时,我们可爱的hello world终于可以say hello了,我也跟大家say goodbye了。


点击看大图
//后记,中途我用arm-elf-tool试了一下,原想它是编译uclinux给不支持mmu,fpu的arm7,没想到安装后连预处理阶段调用cpp0,竟然


找不到cpp0,哎,可能没装好。


 


 


 


 



 

文章评论0条评论)

登录后参与讨论
我要评论
0
11
关闭 站长推荐上一条 /2 下一条