naxiehuaer0811 发表于 2009-5-26 14:48

深度讨论

描述:模拟器与手机原有系统有按键和屏幕冲突。即发生键盘和屏幕事件时
两者都接受事件。游戏会花屏。

#!/bin/sh
export CECHOME=/mnt/cellon
export QTDIR=$CECHOME/qt
export CECDIR=$CECHOME/cec
export LD_LIBRARY_PATH=/mnt/sd/e600/lib:$CECHOME/lib:$CECDIR/lib:$QTDIR/lib:/mnt/doc/ibm/jvm/bin:$LD_LIBRARY_PATH
/mnt/doc/cec_local/bin/qnesexe 2>/mnt/sd/e600/log/qnesrunerror.txt

描述:模拟器运行一切正常。模拟器优先接受键盘和屏幕事件。

B.摩托罗拉E680运行普通的QTE程序

使用E680自带库编译:
arm-linux-g++ helloqt.cpp -o helloqtezx -fno-exceptions -fno-rtti -DQWS -Wall -g \\
-I/home/gcc/src/dev-ezx-0.2.0/include/qt -I/home/gcc/src/dev-ezx-0.2.0/include/ezx \\
-L/home/gcc/src/dev-ezx-0.2.0/lib -L/home/gcc/src/dev-ezx-0.2.0/lib/ezx/lib \\
-lezxappbase-xscale-r -lqte-mt-xscale-r \\
-lezxjpeg-xscale-r -lezxnotification-xscale-r


#!/bin/bash
export QTDIR=`pwd`
export LD_LIBRARY_PATH=$QTDIR:/usr/lib/ezx/lib
export EZX_RES_FONT_PATH=$QTDIR/fonts
exec ./helloqtezx

描述:QTE程序运行完全正常,可以拖动最大化最小化。

使用自编译的QTE(qt2.3.10)库进行编译(VFP):
arm-linux-g++ -c -I$QTDIR/include -pipe -DQWS -fno-exceptions -fno-rtti -O2 -Wall -W -DNO_DEBUG -o helloqt.o helloqt.cpp
arm-linux-g++ -L$QTDIR/lib -Wl,-rpath,$QTDIR/lib -o helloqtvfp helloqt.o -lqte -lm
#!/bin/bash
export QTDIR=`pwd`
export LD_LIBRARY_PATH=$QTDIR:/usr/lib/ezx/lib
export EZX_RES_FONT_PATH=$QTDIR/fonts
exec ./helloqtezx -qws

描述:稍微操作下菜单,QTE程序就不见了,更不用谈最大化最小化和拖动了。

[原因分析]

我们可以初步理解,基于Qte的手机系统有一个Qte Server,手机系统的每个程
序都是基于这个Qte Server,手机自带的lib文件则封装了基于Server的应用函数。
我们看A例子,如果声明了Qws相关的环境变量,系统要求必须通过独立的Qte Server
来运行Qnes,如果不加-qws参数,则提示:
QSocket::writeBlock: Socket is not open
QSocket::writeBlock: Socket is not open
QSocket::writeBlock: Socket is not open
QSocket::writeBlock: Socket is not open
No Qt/Embedded server appears to be running.
If you want to run helloqtvfp as a server,
add the \"-qws\" command-line option.

加上-qws后,以Server态运行,这样肯定于原因手机已有的Qte Server相冲突,
一旦发生按键屏幕事件,两个Server皆接受并处理,所以A例中的花屏也不难理解了。
再看B例,使用手机自带的lib文件,自然会让QTE程序运行于原先的Qte Server
上,自己编译的Qte库文件显然需要重新以Qte Server态启动,一点就没,是很正常
的。

所以写E680软件也好,写E600,968的Qte软件也好,最好能用本身的lib文件,
否则会与原有系统冲突,不能正常运行。

五、搭建编译环境
前面文章已经说过搭建交叉编译环境的要点,下面列出我实际使用的参数文件。
我使用的是cross-tools 0.42,做交叉编译环境没有比这个工具更省事的了。

主脚本 liwei.sh

#!/bin/sh
set -ex
TARBALLS_DIR=$TOOLCHAIN_DIR/crosstool-0.42/downloads
RESULT_TOP=$TOOLCHAIN_DIR
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES=\"c,c++\"
export GCC_LANGUAGES

mkdir -p $RESULT_TOP
eval `cat liwei.dat liweicmp.dat` sh all.sh --notest
echo Done.

编译参数配置 liwei.dat

KERNELCONFIG=`pwd`/arm.config
TARGET=arm-linux
TARGET_CFLAGS=\"-O\"
GCC_EXTRA_CONFIG=\" --with-float=soft --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale\"
GLIBC_EXTRA_CONFIG=\"--without-fp\"

编译源文件配置 liweicmp.dat

BINUTILS_DIR=binutils-2.15
GCC_DIR=gcc-3.4.0
GLIBC_DIR=glibc-2.2.5
LINUX_DIR=linux-2.4.19
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.2.5

gcc-3.4.0 Patch去除了一些冲突项,glibc,kernel等其余patch为cross-tool
默认自带

gcc-3.3.3h-ppc-asm-spec.patch
gcc-3.4.0-arm-softfloat.patch
gcc-3.4.0-pr14808-refix.patch
gcc-3.4.0-ultrasparc3-default64.patch
pr15647-fix.patch
pr13250-fix.patch

增加的gcc-3.4.0-arm-softfloat.patch可以去网上搜索,不过有不同的版本。
这里列出我的全部内容(比较夸张,复制建立个patch文件即可,注意要是Unix格
式):

diff -urNd gcc-3.4.0-orig/gcc/config/arm/coff.h gcc-3.4.0/gcc/config/arm/coff.h
--- gcc-3.4.0-orig/gcc/config/arm/coff.h 2004-02-24 15:25:22.000000000 +0100
+++ gcc-3.4.0/gcc/config/arm/coff.h 2004-05-01 19:07:06.059409600 +0200
@@ -31,11 +31,16 @@
#define TARGET_VERSION fputs (\" (ARM/coff)\", stderr)
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
+#define TARGET_DEFAULT \\
+ ( ARM_FLAG_SOFT_FLOAT \\
+ | ARM_FLAG_VFP \\
+ | ARM_FLAG_APCS_32 \\
+ | ARM_FLAG_APCS_FRAME \\
+ | ARM_FLAG_MMU_TRAPS )
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \\
- { \"marm\", \"mlittle-endian\", \"msoft-float\", \"mapcs-32\", \"mno-thumb-interwork\" }
+ { \"marm\", \"mlittle-endian\", \"mapcs-32\", \"mno-thumb-interwork\" }
#endif

/* This is COFF, but prefer stabs. */
diff -urNd gcc-3.4.0-orig/gcc/config/arm/elf.h gcc-3.4.0/gcc/config/arm/elf.h
--- gcc-3.4.0-orig/gcc/config/arm/elf.h 2004-02-24 15:25:22.000000000 +0100
+++ gcc-3.4.0/gcc/config/arm/elf.h 2004-05-01 19:12:16.976486400 +0200
@@ -46,7 +46,9 @@
#ifndef SUBTARGET_ASM_FLOAT_SPEC
#define SUBTARGET_ASM_FLOAT_SPEC \"\\
-%{mapcs-float:-mfloat} %{msoft-float:-mfpu=softfpa}\"
+%{mapcs-float:-mfloat} \\
+%{mhard-float:-mfpu=fpa} \\
+%{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}\"
#endif
#ifndef ASM_SPEC
@@ -106,12 +108,17 @@
#endif
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
+#define TARGET_DEFAULT \\
+ ( ARM_FLAG_SOFT_FLOAT \\
+ | ARM_FLAG_VFP \\
+ | ARM_FLAG_APCS_32 \\
+ | ARM_FLAG_APCS_FRAME \\
+ | ARM_FLAG_MMU_TRAPS )
#endif
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \\
- { \"marm\", \"mlittle-endian\", \"msoft-float\", \"mapcs-32\", \"mno-thumb-interwork\", \"fno-leading-underscore\" }
+ { \"marm\", \"mlittle-endian\", \"mapcs-32\", \"mno-thumb-interwork\", \"fno-leading-underscore\" }
#endif

#define TARGET_ASM_FILE_START_APP_OFF true
diff -urNd gcc-3.4.0-orig/gcc/config/arm/linux-elf.h gcc-3.4.0/gcc/config/arm/linux-elf.h
--- gcc-3.4.0-orig/gcc/config/arm/linux-elf.h 2004-01-31 07:18:11.000000000 +0100
+++ gcc-3.4.0/gcc/config/arm/linux-elf.h 2004-05-01 19:19:06.935979200 +0200
@@ -30,9 +30,27 @@
/* Do not assume anything about header files. */
#define NO_IMPLICIT_EXTERN_C
-/* Default is to use APCS-32 mode. */
+/*
+ * Default is to use APCS-32 mode with soft-vfp.
+ * The old Linux default for floats can be achieved with -mhard-float
+ * or with the configure --with-float=hard option.
+ * If -msoft-float or --with-float=soft is used then software float
+ * support will be used just like the default but with the legacy
+ * big endian word ordering for double float representation instead.
+ */
+
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
+#define TARGET_DEFAULT \\
+ ( ARM_FLAG_APCS_32 \\
+ | ARM_FLAG_SOFT_FLOAT \\
+ | ARM_FLAG_VFP \\
+ | ARM_FLAG_MMU_TRAPS )
+
+#undef SUBTARGET_EXTRA_ASM_SPEC
+#define SUBTARGET_EXTRA_ASM_SPEC \"\\
+%{!mcpu=*:-mcpu=xscale} \\
+%{mhard-float:-mfpu=fpa} \\
+%{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}\"
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
@@ -40,7 +58,7 @@
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \\
- { \"marm\", \"mlittle-endian\", \"mhard-float\", \"mapcs-32\", \"mno-thumb-interwork\" }
+ { \"marm\", \"mlittle-endian\", \"mapcs-32\", \"mno-thumb-interwork\" }
#define CPP_APCS_PC_DEFAULT_SPEC \"-D__APCS_32__\"
@@ -55,7 +73,7 @@
%{shared:-lc} \\
%{!shared:%{pro文件:-lc_p}%{!pro文件:-lc}}\"
-#define LIBGCC_SPEC \"%{msoft-float:-lfloat} -lgcc\"
+#define LIBGCC_SPEC \"-lgcc\"
/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
diff -urNd gcc-3.4.0-orig/gcc/config/arm/t-linux gcc-3.4.0/gcc/config/arm/t-linux
--- gcc-3.4.0-orig/gcc/config/arm/t-linux 2003-09-20 23:09:07.000000000 +0200
+++ gcc-3.4.0/gcc/config/arm/t-linux 2004-05-01 20:31:59.102846400 +0200
@@ -4,7 +4,10 @@
LIBGCC2_DEBUG_CFLAGS = -g0
LIB1ASMSRC = arm/lib1funcs.asm
-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \\
+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \\
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \\
+ _fixsfsi _fixunssfsi
# MULTILIB_OPTIONS = mhard-float/msoft-float
# MULTILIB_DIRNAMES = hard-float soft-float
diff -urNd gcc-3.4.0-orig/gcc/config/arm/unknown-elf.h gcc-3.4.0/gcc/config/arm/unknown-elf.h
--- gcc-3.4.0-orig/gcc/config/arm/unknown-elf.h 2004-02-24 15:25:22.000000000 +0100
+++ gcc-3.4.0/gcc/config/arm/unknown-elf.h 2004-05-01 19:09:09.016212800 +0200
@@ -30,7 +30,12 @@
/* Default to using APCS-32 and software floating point. */
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
+#define TARGET_DEFAULT \\
+ ( ARM_FLAG_SOFT_FLOAT \\
+ | ARM_FLAG_VFP \\
+ | ARM_FLAG_APCS_32 \\
+ | ARM_FLAG_APCS_FRAME \\
+ | ARM_FLAG_MMU_TRAPS )
#endif
/* Now we define the strings used to build the spec file. */
diff -urNd gcc-3.4.0-orig/gcc/config/arm/xscale-elf.h gcc-3.4.0/gcc/config/arm/xscale-elf.h
--- gcc-3.4.0-orig/gcc/config/arm/xscale-elf.h 2003-07-02 01:26:43.000000000 +0200
+++ gcc-3.4.0/gcc/config/arm/xscale-elf.h 2004-05-01 20:15:36.620105600 +0200
@@ -49,11 +49,12 @@
endian, regardless of the endian-ness of the memory
system. */

-#define SUBTARGET_EXTRA_ASM_SPEC \"%{!mcpu=*:-mcpu=xscale} \\
- %{mhard-float:-mfpu=fpa} \\
- %{!mhard-float: %{msoft-float:-mfpu=softfpa;:-mfpu=softvfp}}\"
+#define SUBTARGET_EXTRA_ASM_SPEC \"\\
+%{!mcpu=*:-mcpu=xscale} \\
+%{mhard-float:-mfpu=fpa} \\
+%{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}\"
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \\
- { \"mlittle-endian\", \"mno-thumb-interwork\", \"marm\", \"msoft-float\" }
+ { \"mlittle-endian\", \"mno-thumb-interwork\", \"marm\" }
#endif
六、如何测试简单的QT程序
下面是一个十分简单的QT程序,也是来自Qte的教程。

helloqt.cpp

#include <qapplication.h>
#include <qpushbutton.h>

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QPushButton hello( \"Hello world!\", 0 );
hello.resize( 100, 30 );

a.setMainWidget( &hello );
hello.show();
return a.exec();
}

下载qte-2.3.10(其他版本没有试),我们需要他的头文件,解压缩。我的
路径是/home/gcc/toolchain/qt-2.3.10,将E600或968自带libqte-mt.so.2.3.8
复制到/home/gcc/toolchain/qt-2.3.10/lib下,并做一些软连接或者干脆直接
复制(如libqte.so,libqte-mt.so ...),将自带的libjpeg.so.62.0.0复制到交
叉编译lib下,这时也需要做下类似的操作,我这里路径是/home/gcc/toolchain/gcc-3.4.0-glibc-2.2.5/arm-linux/arm-linux/lib

设置环境变量:

export TOOLCHAIN_DIR=/home/gcc/toolchain
export PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin:$TOOLCHAIN_DIR/gcc-3.4.0-glibc-2.2.5/arm-linux/bin
export QTDIR=$TOOLCHAIN_DIR/qt-2.3.10
使用以下命令编译:
arm-linux-g++ -c -I$QTDIR/include -pipe -DQWS -fno-exceptions -fno-rtti -O2 -Wall -W -DNO_DEBUG -o helloqt.o helloqt.cpp
arm-linux-g++ -L$QTDIR/lib -Wl,-rpath,$QTDIR/lib -o helloqtfpa helloqt.o -lqte -lm
这个helloqtfpa就可以在E600,968上运行了,我当时用的E600的libqte-mt.so.2.3.8
编译后放在968上也能正常运行,我个人认为E600,968这两个文件差异是在于
对键盘的处理。
另外前一阵子令人郁闷的Segmentation Fault问题是由于,我使用了以下
语句进行编译:
arm-linux-g++ -L$QTDIR/lib -I$QTDIR/include -Wl,-rpath,$QTDIR/lib -o helloqterr helloqt.cpp -lqte -lm
最重要参数是-DQWS,没有它编译后-qws运行肯定出现Segmentation Fault。
至于为何如此,我没有做过Qte开发,还是不了解。


七、总结
至此,从解决安装包,到打开Shell入口,到解除软件安装限制,再到图形化
软件移植,夏新E600和飞利浦968终于取得实质性的成果。
本文即将结束时,又听到了subtle关于telnet的重大突破,令人兴奋不已!
感兴趣的朋友可以参考E680编译Qte的方法,用E600环境编译下整个Qte,思路
是完全一样的,此外qtopia,opie等等系列软件都需要众人去挖掘。
高兴之余,也有遗憾,一个是浮点问题没有得到彻底解决,二是E600,968上层
图形化源码没有,三是E600,968自带Qte库文件内容太少。这几个问题的确是进行
实际应用软件移植的烂路虎。

--------------------------------------------------------------------------------
wheel 回复于:2006-12-06 13:58:05
夏新E600和飞利浦968手机系统是十分相近的,内核版本信息也是一致的,
不过即便这样,在模拟器移植过程中,E600使用968的QT库,都会有按键问题。
显然这是硬件有所不同的原因。
Qnes模拟器能不能在E680上用呢,事实是不太可能的,因两者硬件差异太
大。以下描述我在E680上运行Qnes的提示信息。
我将一些夏新E600本身特有lib文件加上后,仍然使用E680本地的QT库,设
置好环境变量,运行会出现:
# ./r qnes
./qnes: relocation error: /mmc/mmca1/qnes/libcec.so.0: undefined
symbol: _ZThn184_N10QPopupMenu10updateItemEi
说明自带的QT库缺少函数。我把E600的libqte-mt.so.2,和fonts复制过去,
运行倒是可以,只不过是不正常的运行,提示如下:
======== 240 x 320 x 16
Default2: Cannot open /dev/ts (No such file or directory)
==========================================================
theme config file [../Settings/theme/010Gray.conf] doesn&#39;t exist!
JPEG parameter struct mismatch: library thinks size is 376, caller expects 372
QImage::measure fail to guess image format
csmCheckLimited : csm size 0/655360
csmConstruct : csm info
start 0x40551000
size 655360
could not open for writing `/Settings/cec.conf.new&#39;
QCopChannel: no client registered for channel CEC/Desktop, not sending stopStartupAnimation()
...
QCopChannel: no client registered for channel CEC/IdleManager, not sending hideInputMethod()
...
在E680手机上倒是显示了个新界面,并有英文的Load和Back。通过提示可以
清楚看出因两者硬件的差异生成兼容性的问题。不过也证实了上篇文章的推论,
浮点格式不同,最多是浮点运算有误,但是程序还是可以链结运行的。造成什么
Segmentation Fault的错误,还是直接来源于硬件。
如我把E600的sysinfo放在E680运行会有如下提示:

======== 240 x 320 x 16
Default2: Cannot open /dev/ts (No such file or directory)
==========================================================
theme config file [../Settings/theme/010Gray.conf] doesn&#39;t exist!
QImage::measure fail to guess image format
csmCheckLimited : csm size 0/655360
create csm : exist
csmConstruct : csm info
start 0x40871000
size 655360
could not open for writing `/Settings/cec.conf.new&#39;
Can&#39;t make QGfx for null pixmap

QPainter::begin: Unable to get graphics context
Segmentation fault

这个Segmentation fault可能来自于显示设备的,具体原因不详,如做
反汇编处理,会了解更多的信息。
四、测试简单的浮点运算
编译环境:
VFP gcc-3.3.2 glibc-2.3.2 binutils-2.15 kernel 2.4.20
FPA gcc-3.4.0 glibc-2.2.5 binutils-2.15 kernel 2.4.19
先简单写个命令行程序如下:
int main()
{
float fvalueA=1.9;
float fvalueB=2.8;
int ivalueC=8;
int ivalueD=9999;
printf(\"Hello!My E680G!\\n\");
printf(\"Testvalue(4.7):%f\\n\",fvalueA+fvalueB);
printf(\"Testvalue(9.9):%f\\n\",fvalueA+ivalueC);
printf(\"Testvalue(10007):%d\\n\",ivalueC+ivalueD);
return 0;
}
1.vfp soft fp gcc-3.3.2 glibc-2.3.2 编译
arm-linux-gcc -o hellocmdvfp hello.c

2.fpa soft fp gcc-3.4.0 glibc-2.2.5 编译
(加参数 -msoft-float 也是完全一样的)
arm-linux-gcc -o hellocmdfpa hello.c

------------------------------------------------
E680运行结果:

# ./hellocmdvfp
Hello!My E680G!
Testvalue(4.7):4.700000
Testvalue(9.9):9.900000
Testvalue(10007):10007

# ./hellocmdfpa
Hello!My E680G!
Testvalue(4.7):-2.000000
Testvalue(9.9):-2.000000
Testvalue(10007):10007

FPA虽然有软浮点,但浮点运算依然出错。

------------------------------------------------
E600和968的运行结果:

#./hellocmdvfp
Hello!My E680G!
Testvalue(4.7):-2.000000
Testvalue(9.9):-2.000000
Testvalue(10007):10007

#./hellocmdfpa
Hello!My E680G!
Testvalue(4.7):-2.000000
Testvalue(9.9):-2.000000
Testvalue(10007):10007

-------------------------------------------------

出乎我的意料,在E600上,浮点运算居然全出错,后来偶然间用VFP格式
的arm-linux-g++编译:
arm-linux-g++ -o hellocmdvfp+ hello.c

#./hellocmdvfp+
Hello!My E680G!
Testvalue(4.7):4.700000
Testvalue(9.9):9.900000
Testvalue(10007):10007

在E600上居然又运行正确,这令人十分奇怪。于是我再用FPA格式这样编
译:
arm-linux-g++ -o hellocmdfpa+ hello.c

因为是gcc.3.4.0版本,会提示libstdc++6.so.0和libgcc_s.so.1缺少。
加上库文件后运行结果如下(E680,E600,968结果完全一样):

#.hellocmdfpa+
Hello!My E680G!
Testvalue(4.7):-2.000000
Testvalue(9.9):-2.000000
Testvalue(10007):10007
显然都是错误的。

五、总结
VFP格式在E600,968上运行,可以说是没有浮点BUG的。不过FPA却总
有问题。VFP编译环境在编译过程中不能兼容E600,968本身的库文件,所
以才要用FPA的编译环境。
浮点这个问题比较让人费解,还须要做进一步研究。

Mr丶locker 发表于 2009-5-26 14:52

看不懂!!!!

流星海雨 发表于 2009-5-26 14:57

这是什么?

轩皓樱 发表于 2009-5-26 14:59

没看懂……

LouisLaw 发表于 2009-5-26 15:10

大侠...请多多指教

麦田的守望者 发表于 2009-5-26 15:12

LouisLaw 发表于 2009-5-26 15:14

大侠,有V8的GCC吗???我知道有Z6的...但是目前没有找到V8的GCC

qcqwppp 发表于 2009-5-26 22:08

帮顶
页: [1]
查看完整版本: 深度讨论