14
2008

[学无前后,达者为师]Xscale的软浮点问题及基于该芯片的linux上QT4编译移植过程分析详解”Xscale soft-float transplanting QT4 to linux on Xscale”

Xscale的软浮点问题及基于该芯片的linux上QT4编译移植过程分析详解

“Xscale soft-float transplanting QT4 to linux on Xscale”

update 2008-12-16

看到站长统计里有人搜索tslib1.4下载,链接到这里了,那么就在这里放一下下载链接好了。

这个其实是用svn同步下来的,trunk里面正好是1.4的版本号。

svn co svn://svn.berlios.de/tslib/trunk/tslib tslib

下载tslib1.4点这里!
又是很久没更新blog,不是因为没内容,而恰好是因为内容太多,干不过来,现在每天除了上课的时间和逃课的时间,基本上全天候呆在实验室,每天头昏脑胀(虽然很快乐很开心^_^),实在是没时间写了……不过总结写文档是个好习惯,好处有:
1)理清头绪。整理资料可以让自己发现知识遗漏点,因为做的时候忙于实现,为了避免打乱思路很多暂时无用的技术细节是被忽略的。
2)造福后人。这里的后人不是我的后人……而是实验室里在我之后想学这个的人。很多东西都缺乏中文资料,或者中文资料版本解决方案不匹配,只能适用于我当时的情况,而不能让其他人受益。资料可以让后人快速入门。
3)锻炼文笔。对于IT人士,“文笔”这个词实在有点过分了,因为技术文档讲究严谨又清晰易懂,不能太“文采”了,但是又可以有一定的幽默感,也就是写作风格可以比较随意。在实际开放中,因为必须写文档总结,测试文档,技术文档,需求文档,甚至对员工培训,文档的写作必不可少,现在可以加紧锻炼。
4)可以显得自己比较牛。^_^

来到实验室以后,并没有立即开始学习工作,而是花了很多时间和大家相识,了解大家。

先说说老师,老师很牛很牛,他们一定不介意我说出他们的名字,贾世祥老师和潘辉老师,一搜就知道,有书有论文。

成员呢有12人目前,只有我一个是07级的,奇怪的是,大三大四的学长们都很年轻,没几个比我大的……
实验室老大快毕业了,叫他老大不是因为他老,而是因为他足够牛。我很佩服他,他的简历上写的能力特长都能让你看晕了。老大掌管实验室大小事,关心学弟学妹们的工作进度,提出指导意见和方向,相当平易近人,他女友还是前学生会副主席。对我来说,他就是一个老师,太佩服了。和他聊5分钟,等于自己看一天书。

暑假的时候他们一起做了基于s2410的linux的智能家居服务系统,获得了全国QT特等奖,十分厉害,这是计算机系的首次拿奖……

女生挺多的其实,有4个,至于她们的能力水平,我还不清楚,就不多说了。

好像每次都跑题好多好多阿……不过我知道其实大多数看我blog的其实也就看看这些花边新闻,看技术的看累了一般也比较愿意看看八卦……所以我才废话比较多……

本文没有源码下载,没有诙谐的语言,没有透露隐私,也没有赏心悦目、搞笑的图片,甚至也没有美女出现。

本文只有技术……如果各位看官没有耐心,请登录www.zhetengmaomao.com.cn观看其余日志,谢谢。

我刚刚来到的时候就知道了他们的一个遗留问题,在此简单叙述:

原来他们有一些工作是基于arm9 sansung 2410s的linux的QT4的。
买来的开发板附带的光盘,提供了一个完整的根文件系统映象rootfs.img,和完整的编译好的linux 2.6内核映象,在PC上经过标准安装后,提供了经过板级配置的2.6内核源码和一套编译链toolchain。在他的根文件系统里,有很多例子,比如mplayer可以播放视频音频,qt的图形化应用程序,附带了触摸屏,闪存等的支持。
他们在该版开发了基于QT和mplayer的智能家居服务系统。

现在有一块基于Xscale的开发板,按照道理,在arm9上编译好的程序都是基于arm架构,都是linux的elf格式,直接拿到这应该就能运行,可是运行得到结果是“instruction illegality”(好像是这么写的),指令非法。

现在的目标是,如何让自己编译的mplayer和QT的库,和自己的应用程序在这里跑起来。

他们恰好大家都很忙,我又恰好没什么事做,于是我决定接手这个,因为我有linux基础、基本的gcc编译、程序动态链接知识。

原因很简单。

重要提示!

为了方便更好的理解本文,提供下面链结。
相关的重要资料的系列文档:http://www.zhetengmaomao.com.cn

浮点问题的由来
Inter Xscale这款新型高性能、低功耗的微构架兼容arm v5 te isa指令集,不过不支持浮点指令集。这是为了节省处理器芯片体积和降低运行功耗,XScale体系结构没有实现昂贵的浮点运算部件和除法部件。这些是嵌入式应用中不常用的运算。当需要这类运算时,要通过软件方法实现。浮点运算要大大复杂于整数运算,没有浮点运算单元会有什么问题?
当然有问题,难道你printf(”%f”, 0.5)都会出现指令非法的计算机能算是好用的计算机嘛?

在叙述接下来的问题之前,我提出几个名词,方便叙述。

工具链toolchain:交叉编译的一系列工具,包含编译,调试,反汇编,读elf信息,等等工具。

硬浮点toolchain:工具链的编译器gcc的glibc标准C库里的浮点计算直接使用处理器的浮点指令。

软浮点toolchain:工具链的编译器gcc的glibc标准C库里的浮点计算被不含浮点指令的整数算法替换,编译出的目标文件不含浮点指令。

事实上没有问题,解决此类问题有两种方案:

第一种,linux内核内建浮点模拟器支持,在遇到浮点指令时产生的异常会被内核捕捉,进行转换:

以下内容部分引用:

在配置内核时一定要选择一个浮点模拟器NWFPE,如下
— At least one math emulation must be selected │ │
│ │ NWFPE math emulation │ │
│ │ [ ] Support extended precision │ │
│ │ FastFPE math emulation (EXPERIMENTAL)
假如没有浮点模拟器,就会出现错误。比如:
undefined instruction
实际上,即使使用了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

假如工具链支持软浮点,那么就能够生成可执行文档,如出错,对不起,该工具链不支持。

编译链是否支持浮点-msoft-float关键在于他的glibc标准C库中是否含有浮点指令。绝大多数编译链构建的时候是不会支持该参数的。

鉴定一个应用程序或一个库是否是软浮点的方法,使用
arm-linux-readelf -e test
能够打印出elf文档头信息,在里面看到software FP就是软浮点格式,否则不是。
Flags: 0×202, has entry point, GNU EABI, software FP

我们使用的UP-TECHPXA270开发版附带的工具链完善支持软浮点,并且默认软浮点,也就是自动会加上-msoft-float选项。

这里加上一个小花絮,也许也有人遇到这样的问题,在此分享。

编译内核的时候也是需要编译链的,难道也是使用这个软浮点的编译链么?不是的。一般情况下,内核是不需要浮点运算的,浮点运算一般用于多媒体。除非人为的添加一些模块驱动中使用到了浮点运算。所以内核的编译用不到软浮点编译链。

光盘中其实附带两套编译链。一套是安装到opt文件夹中的,并将路径加到PATH环境变量里,这个arm-linux工具集就是默认使用的toolchain。

还有一套在附带的2.6源码下

/up-techpxa270/arm-linux-tools/gcc-3.4.6-glibc-2.3.6/

细心的朋友可能发现了,这两套gcc版本不同。

在编译QT4库的时候,用PATH里的那套编译链无法编译过去,而人为指定这套的时候就可以编译成功,但是在开发板上运行的时候还是指令非法。

问题来了,为什么会有两套toolchain?为什么一套不行一套行?是不是因为gcc版本原因?还是什么?

还记得刚刚分析的,内核不需要浮点运算么?

我们打开内核源码中的Makefile文件

/up-techpxa270/kernel/linux-2.6.9/Makefile

发现在195行里有

CROSS_COMPILE = /up-techpxa270/arm-linux-tools/gcc-3.4.6-glibc-2.3.6/arm-linux-

这个指定了编译内核所用的toolchain的路径,按照之前的方法,我们测试出这个toolchain是硬浮点的。

联想之前的内核分析,水到渠成。

内核使用不到浮点,所以编译内核用硬浮点编译链,人为在Makefile指定。

应用程序使用浮点,需要使用软浮点工具链编译。所以将这个软浮点编译链加在PATH里。编译时直接使用arm-linux-gcc就可以了。

浮点问题至此分析完满结束。

我们可以理解的是,使用编译内核的硬浮点编译链编译出的QT4会含有浮点指令,在Xscale运行会失败。可是为什么QT4的编译使用软浮点编译链也会失败呢?

我仔细检查了QT4的configure选项,发现有

–no-arm-fpa

这个选项,这个选项直译为:arm处理器没有浮点!那么必须打开这个选项。

我再次分析。图形库隶属于多媒体的范畴。多媒体在解码计算时一般都有两种算法,一种基于浮点,一种基于整数,一般来说,使用浮点的算法较快,所以默认使用浮点算法,QT4也不例外。但是浮点运算如果需要模拟,就绝对不会比整数快了,所以这个选项就有存在的必要。QT4里一定有算法是用汇编写的,所以才会出现这个选项。

再次编译,发现编译器提示了新的错误。

我仔细观察了出错信息,发现是在编译demo时出错,而且是与demo的源文件文件夹下的附带的隐藏的目标文件产生浮点冲突,很好理解了吧现在,将demo隐藏的目标文件用arm-linux-readelf -e 读出是硬浮点的,自然无法编译成功,至于为什么开放源代码的QT源码里会附带事先编译好的目标文件,这个就无从考证了,感兴趣的人可以看看,研究好了给我发email吧。此时编译已经到了尾声,所有的库应该都已经编译成功,所以运行应该是不成问题的。

将库复制到板子上,建立环境变量(这里略过,与本文不相关,具体的是设置库目录,字库目录,触摸屏,不懂的放狗去搜或者问我),运行example,OK,没有提示指令非法~

开香槟庆祝~~~~疑?undefine symbol asof8eq934htpwer8gusa in /……/……/lib/libQtNetwork.so.1

还是不能运行?

这次是QT4的问题了,没有定义的符号?这个错误他不是字面的意思。在vc里,出现这样的错误一般是因为没有引用一些头文件,导致该源文件里使用到的一些函数在link阶段无法连到目标文件。

对于动态库,就是运行的时候无法找到函数了。程序在运行,需要用到libQtNetwork.so里的函数,那么就去找呗,可是找了半天找不到……

为什么呢?我使用了懒办法,我去libQtNetwork.so找找,到底那个函数哪儿去了。

arm-linux-readelf –symbol libQtNetwork.so

就可以读出所有的symbol,哇,好多好多,至少几千个吧,怎么办……

arm-linux-readelf –symbol libQtNetwork.so | grep hasodifyq0384hieuhfaousef

使用管道符定向到grep程序查找函数符号,不懂?放狗去搜……

结果是,应用程序运行出错提示缺少的函数符号全部超过了25位,而读出的符号列表正好在25位被截断……这么奇怪的数字?为什么不是16个32个?原因未知。

这个问题十分奇怪……

可是天意是神奇的……让我这个绝不迷信的人也惊讶起来……

我恰好学过C++标准模板库 C++ STL。这个东西同龄人之中应该很少学过吧?首先C++没学过,就更加不会学几乎什么C++书都没提到过的STL了。

就我所知,会导致函数名灾难性的变长的就是STL,它的模板技术在经过编译器复杂的处理以后为了避免函数重名,将函数名位数变长,跟C++的编译也是转成C语言的代码时也会将重载的函数变长一个道理。

我抱着尝试的心里搜索了一下QT4 configure时的参数。

./configure –help | grep stl

发现有QT4 configure参数如下

–no-stl

我的妈呀……太巧合了,就我有限的学识……居然也会发现这个奇怪的问题根源所在……

现在想想,应该是编译链默认截断函数名25位,而且在嵌入式,使用stl模板技术应该会让程序变慢的,没有必要使用stl来加快开发进度。

好的,加上。

其实我还编译了zlib……唉,这个就不说了,还要改Makefile的……相关性不大

于是qt4编译

./configure –no-arm-fpa –no-stl 加其余选项 –arch 等等

再次复制4个so库,字库,example

运行

./example –qws

恭喜~成功拉~~~~~~~~~~~

至此,所有的分析均结束,所有的分析均水到渠成,滴水不漏!

如有不明白之处,立即提问,趁我还记得……

如果有疏漏或错误或不严谨之处,请立即发email发短信打电话等等一切措施提醒我教导我!谢谢!

全文使用创作共享协议,请移步about页面查看详情,转载请署名。
下集预告:

在实验室工作实在是很忙,压力很大,而且十分寂寞,空虚

那么我究竟干了什么呢?

下期分析基于386的linux启动分析,顺带引入Xscale开发板上BootLoader分析与设计以及其后的linux启动分析。

以及很多很多的隐私和花边新闻……嘿嘿……

Written by ChuangBo in: 嵌入式, 技术 | 标签:, , , , ,

我猜您可能还喜欢:

9 条评论 »

  • 啊!看晕了…… 你们实验室的人都那么牛吗? 555555……要努力了啊!!!

  • ChuangBo 说:

    ……阿………别别别别这么说……我故意写的显得很牛的……其实没必要

    有谁真的遇到这个问题
    又对拙文不明白,请直接问我……

  • sun 说:

    你们老大很牛啊?你的分析我直接看不懂了,和你们比起来我就是外行吧,唉

  • zougw 说:

    你好!在你的blog中看到你正在做qt的移植工作,我也正在做相同的工作,平台也是xscale270,现在已经取得了一定的成果,tslib也成功移植了,但是现在还有一些具体问题,想和你讨论一下,我的联系方式是zouguangwei@tom.com。希望你能给我一个联系方式,期待你的回信!

  • [...] 我目前已经将QT 4.4.3 embedded wince 移植到我的手机上了……比linux embedded framebuffer的版本好移植多了(看这里),什么都不用管,看来这就是闭源的好处:虽然操作系统的实现十分龌龊,但是都干干净净封装好了,出了问题也不怪应用程序。况且龌龊归龌龊,运行效率却也奇高,就好比是c++程序里一大堆全局变量啊,全局函数啊什么的,但是效率确实很高。 [...]

  • ChuangBo 说:

    将email的回复粘帖至此,以免大家以为我都不回复的……

    ——你好!可以随时与我讨论,我做过QT4的移植,也修改过QT4的触摸板部分,并且对QT以及内核的研究学习很感兴趣。很高兴认识你。

    ——你好,很高兴看到你的回信,我现在有一个问题想咨询你一下。我想问一下你编译的qt是否同时编译了webkit库?用这个webkit库在270板子上跑,是否有问题。我移植的qt没有问题,但是webkit在jscore的地方有问题,运行的时候总是自动退出,我不确定是不是我编译器的问题,所以想请问你一下是否出现了这个问题。

    ——你好,我去掉了webkit支持,不好意思。我想你可以试图调试一下,我改触摸屏的时候就是慢慢调试过来的,而且还不能用GDB,我是用printf调试的。不能帮上忙实在不好意思,不过有空我会试一下。

  • ChuangBo 说:

    他目前在北京找了个公司临时安顿了下来……才大四上学期啊,他的简历我有……要不要看看?

  • ChuangBo 说:

    wherewhere

  • [...] tslib就不说了,根据小板的触摸屏走向修改了几个xy,太久了,忘了。 [...]

RSS feed for comments on this post. TrackBack URL


Leave a Reply

Powered by WordPress | Aeros Theme | TheBuckmaker.com | 鲁ICP备08103482号