导读:
MOTO LINUX系MOBILEPHONE的EZX库解读
一般性猜测及实现
by ppllxx
引言
通常,程序是在一台计算机上编译,然后再分布到将要使用的其他计算机上。当主机系统(运行编译器的系统)和目标系统(产生的程序将在其上运行的系统)不兼容时,该过程就叫做交叉编译。 在这篇文章中,我将使用MOTOROLA的LINUX 系列手机E680I作为焦点,介绍其底层库的猜测解读,以及解读底层库的原因和猜测的一般性方法及猜测验证,而对交叉编译环境的搭建和对具体实现的细节及基础知识不做过多介绍。如果您曾有过交叉编译的经历(笔者还有关于SONY PSP以及IPOD NANO的交叉编译经验),那么阅读本文将会使您加深一些对嵌入式操作系统的认识。若无交叉编译经历的话,按照文章的组织顺序阅读,您也将会从本文中受益,因为本文类似于一个教程,每一步都以逻辑顺序相连。
必要
JAVA程序通常使用非常小的一部分时间运行所编写的程序,而将大部分时间用在运行JAVA开发包所提供的库文件中,也就是JAVA通过提供各类平台的虚拟机程序来实现平台无关性,这样也很大的牺牲了执行效率;而C/C++程序主要特点就是接近低层,可根据不同处理器生成高效的机器代码。适合做复杂的运算和实时的控制,所以针对C语言,会有很多不同平台的编译器负责将代码直接编译成高效的机器指令(构造一个能兼容ARM的GCC)。
测量程序的运行速度,最好的标准就是在相同条件下,计算程序不同编写方式下的运行时间,
一般来说,在循环中向下计算比向上计算快,虽然在小的循环体中影响几乎为零,但是如果循环次数到达万次以上,则影响非常明显:
测试一个绘制心状图形的计算量,使用笛卡儿公式:r=a(1-sin(a)),其核心计算为将空间的每个点投影到XY平面,其计算量分别在下面两段程序显现
经过分别5次测试,运算时间分别是385MS和85MS
性能对比一目了然。
猜测
在一般采用Qt嵌入式操作系统的架构如下:
Linux Embedded Kernel + Framebuffer + Qte + Qtopia
MOTO LINUX系操作系统的架构:
MontaVista Linux Kernel + Framebuffer + Qte + ezx图形库
而Java号称Compile once,run everywhere。,Java编译生成的是字节代码,然后由各个平台的Java虚拟机解释执行。实际上在E680G(测试用机)上,J2ME的JAR包是由/usr/SYSjava/kvm解释执行的。运行KVM会出现以下提示:# ./kvm
{0} AMSInterface.cpp:91 946920014 : 624426 - KVM: Main() entrance, kvm's main Function starts here
{0} J2ME_JAM_Main.cpp:93 argv[0] = ./kvm
FS_lock_init: sem id 32769, NOT mine
FS_init shm @ addr 0xbeaf6000, size 163840, NOT mine
{0}AMSInterface.cpp:91 946920014 : 859533 - KVM: finished ZApplication's initialization
{1}笔者这样猜想KVM应该建立在EZX层上如下:
可以看出JAVA执行效率低的原因,那么要制作执行效率高的程序,最好是在EZX层上来做,然而MOTO官方并未给出EZX的SDK,这就要自己来完成这部分工作。因为MontaVista Linux采用的是2.4.20内核(如下图所示),且是支持telnet的(从手机导出的库文件可以看出),可以从手机
中导出ezx库文件,使用如下方法
Tar –czvf /mmc/mmca1/lib.tar.gz /usr/lib
拷贝出lib.tar.gz并在cygwin(笔者所使用的开发环境)下打解压打开查看所有库文件(部分)
从libqte-mt-xscale-r.so.2.3.6该库文件可以看出其所使用的qte版本为2.3.6,这里笔者对libezxappbase-xscale-r.so.1.0.0该ezx库进行反编译(从其名字可以猜测出它的含义是EZX_APPLICATION_BASE)使用工具arm-linux-nm(该命令为对应该系的ARM指令集CPU的反编译命令,需要自己在本机上自行编译)参数选择-D(含义为动态库),其反编译后效果如下(笔者在此以解读ezxutiprogressbar为例,故只列出了该库反编译后涉及utiprogressbar的部分)
结合QT语法规范,上面反编译后的结果可以猜测如下(部分)
418c402c T UTIL_ProgressBar::setProgress(int)
418c3f0c T UTIL_ProgressBar::reset()
418c3f6c T UTIL_ProgressBar::setTotalSteps(int)
418c3a10 T UTIL_ProgressBar::UTIL_ProgressBar(QWidget*, char const*, unsigned int)
再猜测各函数的返回值及参数,写成规范头文件(部分)如下
public:
UTIL_ProgressBar(QWidget*, char const*, unsigned int);//定义一个//UTIL_ProgressBar
public slots:
void reset();//清零
virtual void setProgress( int progress );//设置UTIL_ProgressBar初始值
virtual void setTotalSteps( int totalSteps );设置UTIL_ProgressBar最大活动范围
最后进行猜测,把自己定义的头文件ezxutiprogressbar.h用在代码中(测试部分代码),
#include “ezxutiprogressbar.h”//包含自定义头文件
UTIL_ProgressBar *upb = new UTIL_ProgressBar( this, "ppllxx", 0 );//声//明一个UTIL_ProgressBar
upb->setProgress( 20 );// UTIL_ProgressBar初始值设为20
upb->setTotalSteps( 99 );// UTIL_ProgressBar最大活动范围设为99
connect( slider, SIGNAL(valueChanged(int)), upb, SLOT(setProgress(int)) );//该//处将一个已经定义好的滑动条slider的数值改变作为信号和作为槽的upb的进度条改变进行连//接
编译时需要连接libezxappbase-xscale-r.so.1.0.0库,
也就是在在Makefile需要有这样的连接
LIBS=-lezxappbase-xscale-r
最终生成目标文件,在手机上运行效果如下:
读者可以清晰的看到UTIL_ProgressBar,并且通过和slider 的SIGNAL(valueChanged(int)), 与其自身的SLOT(setProgress(int))交互实现了了进度条的增减。
结语
很多开发者还在尝试解读出剩余的大概几十个库文件,而作者在这里只是说自己的理解以及可能性尝试,其中肯定有很多不足的地方,读者均可以发电子邮件
[email protected] 和作者联系。本文从开发EZX非官方SDK的原因说起,到最后成功解读UTIL_ProgressBar,希望能够起到抛砖引玉的效果。本文提供了一些例子,读者均可以在作者的BLOG下到,最后还要说声,开源精神万岁。
参考书目
C++ GUI Programming with Qt 3 By Jasmin Blanchette , Mark Summerfield Publisher: Prentice Hall PTR Pub Date:January 15 ,2004 ;
Cross-Platform GUI Programming with wxWidgets BY Julian Smart, Kevin Hock, Stefan Csomor Publisher: Prentice Hall PTR Pub Date: July 25, 2005;
Building Embedded Linux Systems By Karim Yaghmour
Publisher: O’Reilly Pub Date: April 2003
QT Reference Documentation By Trolltech
EZX From CourvilleWiki By de Courville
[email protected] David Bateman
[email protected] from “http://www.courville.org/mediawiki/index.php/EZX”
Linux与UNIX_Shell编程 BY China.pub.com
LINUX应用程序开发指南:使用GTK+ GNOME库BY China.pub.com
精通JAVA手机游戏与应用程序设计 陈立伟 张克非黎秀红/编著 中国青年出版社2005年5月第一版
推荐投诉
本文转自
http://blog.chinaunix.net/u/19423/showart_371420.html