2.3 收拾开发环境* 确保你有5G的剩余空间。
* 去 下载并安装 j2se 5.0。记住一定要5的,6不行
* 删掉本机自带的 openjdk 和 libgcj! GNU的东西会干扰 Sun JDK 的正常运行。狠狠心把 OpenOffice.org 啥的所有依赖一并全部删掉,免得留后患
* 安装 bison,gperf。其他的基本开发工具我就不一一阐述了,反正缺什么装什么,正常的发行版都会提供。
2.4 修补 froyo 源码
好了,这里开始是真正的苦活累活了。虽说C语言和Java都是移植性见长的语言,但是理想和现实是有差距的。由于种种原因 froyo 为龙芯编译会出各种错误,现在就将我遇到并解决掉的列在这里。我没遇到的只好你自己想办法了。
2.4.1 bionic libc
2.4.1.1 汇编语言实现bionic libc 是 Android 的 C库。在其 MIPS 实现中,为了提高效率 mipsandroid.com 用汇编实现了 memset 和 memcpy 两个函数。不幸的是汇编码中用到了只有 MIPS IV 才提供的 pref 指令。为了避免麻烦,这里修改 makefile,用 C 语言实现予以替代。性能肯定会受损,但无碍使用。留待将来有心人来收拾吧。
在 bionic/ 目录下可以找到 libc 目录。
diff --git a/libc/Android.mk b/libc/Android.mk
index a462a6c..f9ce848 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -354,8 +354,8 @@ libc_common_src_files +=
arch-mips/bionic/vfork.S
libc_common_src_files +=
- arch-mips/string/memset.S
- arch-mips/string/memcpy.S
+ string/memset.c
+ string/memcpy.c
arch-mips/string/strlen.c
libc_common_src_files +=
|
请自行按照这个补丁的意思动手修改。
2.4.1.2 架构与位宽
在 libc/arch-mips/include/machine/asm.h 中,有一处宏指令,逻辑是根据架构选择合适的位宽。MIPS3 被当作 64 位处理。龙芯2F是 MIPS3 没有错,可是我们的编译环境是全 32 位的。按照这个逻辑,在访问内存时将出现未按 64 位对齐的错误。我们在这里将 MIPS3 列为 32 位架构。(这显然不很合适,但我没找到更合理的方法来判断位宽)
diff --git
a/libc/arch-mips/include/machine/asm.h
b/libc/arch-mips/include/machine/asm.h
index 43dbc09..f73d03c 100644
---
a/libc/arch-mips/include/machine/asm.h
+++
b/libc/arch-mips/include/machine/asm.h
@@ -141,7 +141,7 @@
/*
* Basic register
operations based on selected ISA
*/
-#if (_MIPS_ISA ==
_MIPS_ISA_MIPS1 || _MIPS_ISA ==
_MIPS_ISA_MIPS2 || _MIPS_ISA ==
_MIPS_ISA_MIPS32)
+#if (_MIPS_ISA ==
_MIPS_ISA_MIPS1 || _MIPS_ISA ==
_MIPS_ISA_MIPS2 || _MIPS_ISA ==
_MIPS_ISA_MIPS32 || _MIPS_ISA ==
_MIPS_ISA_MIPS3)
#define REGSZ 4 /*
32 bit mode register size */
#define LOGREGSZ 2 /*
log rsize */
#define REG_S sw
@@ -151,7 +151,7 @@
#define CF_RA_OFFS 20 /* Call ra save
offset */
#endif
-#if (_MIPS_ISA ==
_MIPS_ISA_MIPS3 || _MIPS_ISA ==
_MIPS_ISA_MIPS4)
+#if (/*_MIPS_ISA == _MIPS_ISA_MIPS3 ||*/ _MIPS_ISA == _MIPS_ISA_MIPS4)
#define REGSZ 8 /*
64 bit mode register size */
#define LOGREGSZ 3 /*
log rsize */
#define REG_S sd
|
2.4.1.3 page size
龙芯的内核只支持16K的页面大小,跟通常系统4K不符,所以必须修改 bionic 的设定以符合这个页大小,否则 mmap() 会因为页边界未对齐而失败。
diff --git a/libc/kernel/arch-mips/asm/page.h b/libc/kernel/arch-mips/asm/page.h
index fd2333f..9b4d324 100644
--- a/libc/kernel/arch-mips/asm/page.h
+++ b/libc/kernel/arch-mips/asm/page.h
@@ -13,7 +13,7 @@
#define _ASM_PAGE_H
#ifndef PAGE_SHIFT
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT 14
#endif
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
|
同样,请自行手动按上文修改。
2.4.2 V8 引擎 MIPS 标志位只是置一个标志位,完全没有必要非要用到 MIPS32R2 这么高的 ISA 嘛。只是在 MIPS 科技公司眼里,世界上只有 MIPS32 这一个标准了,其他都过时了。
diff --git a/src/globals.h b/src/globals.h
index 6fbb095..5068220 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -46,7 +46,7 @@ namespace internal {
#elif defined(__ARMEL__)
#define V8_HOST_ARCH_ARM 1
#define V8_HOST_ARCH_32_BIT 1
-#elif defined(_MIPS_ARCH_MIPS32R2)
+#elif defined(__mips__)
#define V8_HOST_ARCH_MIPS 1
#define V8_HOST_ARCH_32_BIT 1
#else
|
2.4.3 opengl matrix.h 乘加指令在 framework/base 目录下,libAGL 里面的 mips 汇编代码用到了大量乘加指令。修改判断指令,使其只在 ISA 支持时才使用汇编,从而迫使之对龙芯用 C 代码来替代实现。
diff --git a/opengl/libagl/matrix.h b/opengl/libagl/matrix.h
index f26ea4c..6410a0e 100644
--- a/opengl/libagl/matrix.h
+++ b/opengl/libagl/matrix.h
@@ -74,7 +74,7 @@ GLfixed vsquare3(GLfixed a, GLfixed b, GLfixed c)
);
return r;
-#elif defined(__mips__)
+#elif defined(__mips__) && (__mips >= 4)
GLfixed res;
int32_t t1,t2,t3;
asm(
@@ -159,7 +159,7 @@ static inline GLfixed mla3a( GLfixed a0, GLfixed b0,
);
return r;
-#elif defined(__mips__)
+#elif defined(__mips__) && (__mips >= 4)
GLfixed res;
int32_t t1,t2;
@@ -214,7 +214,7 @@ static inline GLfixed mla3a16( GLfixed a0, int32_t b1b0,
);
return r;
-#elif defined(__mips__)
+#elif defined(__mips__) && (__mips >= 4)
int32_t b0,b1,res;
asm(
#ifdef _MIPS_ARCH_MIPS32R2
@@ -453,7 +453,7 @@ static inline GLfixed mla3( GLfixed a0, GLfixed b0,
: "cc"
);
return r;
-#elif defined(__mips__)
+#elif defined(__mips__) && (__mips >= 4)
GLfixed res;
int32_t t1,t2;
asm(
@@ -508,7 +508,7 @@ static inline GLfixed mla4( GLfixed a0, GLfixed b0,
);
return r;
-#elif defined(__mips__)
+#elif defined(__mips__) && (__mips >= 4)
GLfixed res;
int32_t t1,t2;
asm(
|
2.4.4 dalvik page size
dalvik 中也有地方写死了 page size。龙芯的 page size 是 16K,前面已经说过了。按例修改。
进入 dalvik/
diff --git a/libdex/SysUtil.c b/libdex/SysUtil.c index 7c6aaef..46d05f4 100644 --- a/libdex/SysUtil.c +++ b/libdex/SysUtil.c @@ -37,7 +37,7 @@ * seems appropriate, but we don't have that on the device. Some systems * have getpagesize(2), though the linux man page has some odd cautions. */ -#define DEFAULT_PAGE_SIZE 4096 +#define DEFAULT_PAGE_SIZE (16*1024) //4096 /* diff --git a/libdex/SysUtil.h b/libdex/SysUtil.h index 57959a5..8036731 100644 --- a/libdex/SysUtil.h +++ b/libdex/SysUtil.h @@ -34,7 +34,7 @@ #ifdef PAGE_SHIFT #define SYSTEM_PAGE_SIZE (1< #else -#define SYSTEM_PAGE_SIZE 4096 +#define SYSTEM_PAGE_SIZE (1<<14) /* 16K */ #endif /*
|
2.4.5 dalvik vm 汇编指令MIPS3 不支持 mul 指令。在 MIPS3 中这条指令是个宏,会被展开成多条指令。而在虚拟机的指令翻译部分,不能这样干,因为空间有限,最多只能容纳32条指令。所以用龙芯特有的 mult.g 指令代替 MIPS32 中才出现的 mul 指令,两者完全兼容:
diff --git
a/vm/mterp/out/InterpAsm-mips.S
b/vm/mterp/out/InterpAsm-mips.S
index b14c3f3..0260ed2 100644
--- a/vm/mterp/out/InterpAsm-mips.S
+++ b/vm/mterp/out/InterpAsm-mips.S @@ -6616,11 +6642,11 @@ dalvik_inst: EAS2(t1, rFP, t1) # t1<- &fp[B] LOAD64(a2, a3, t1) # vBB.low / high - mul v1,a3,a0 # v1= a3a0 + mult.g v1,a3,a0 # v1= a3a0 multu a2,a0 mfhi t1 mflo v0 # v0= a2a0 - mul t2,a2,a1 # t2= a2a1 + mult.g t2,a2,a1 # t2= a2a1 addu v1,v1,t1 # v1= a3a0 + hi(a2a0) addu v1,v1,t2 # v1= v1 + a2a1;
|
2.4.6 gralloc 与 framebuffer 驱动龙芯本的 silicon graphic 烂驱动,报告的参数不对,导致 gralloc 发生除零错。从 Android-x86 处借鉴来一个小修正,绕过这个问题。进入 hardware/libhardware/
diff --git a/modules/gralloc/framebuffer.cpp b/modules/gralloc/framebuffer.cpp
index ee4ecd9..9228ee1 100644
--- a/modules/gralloc/framebuffer.cpp
+++ b/modules/gralloc/framebuffer.cpp
@@ -208,13 +208,36 @@ int mapFrameBufferLocked(struct
private_module_t* module)
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
return -errno;
- int refreshRate = 1000000000000000LLU /
- (
- uint64_t( info.upper_margin
+ info.lower_margin + info.yres )
- * ( info.left_margin
+ info.right_margin + info.xres )
- * info.pixclock
+
+ int refreshRate = 0;
+ if (info.pixclock)
+ refreshRate = 1000000000000000LLU /
+ (
+
uint64_t( info.upper_margin +
info.lower_margin
+
* ( info.left_margin
+ info.right_margin + info
+
* info.pixclock
+ );
+
if (refreshRate == 0) {
// bleagh, bad info from
the driver
refreshRate = 60*1000; // 60 Hz
|
2.4.7 Pixelflinger 禁用 codeflingerPixelflinger 是 Android 自带的软件 OpenGL 实现。它有个很特别的功能叫 codeflinger,可以在运行时根据需要动态生成机器指令函数。Android 自带的 codeflinger 产生 ARMv6 代码,MIPSAndroid 移植后产生 MIPS32 代码。为了能在龙芯上用,不得已禁用掉 codeflnger 功能:
- diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
-
old mode 100644
-
new mode 100755
-
index e0a25c4..b2d864d
-
--- a/libpixelflinger/scanline.cpp
-
+++ b/libpixelflinger/scanline.cpp
-
@@ -46,10 +46,11 @@
-
-
#ifdef NDEBUG
-
# define ANDROID_RELEASE
-
-# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERATED
-
+# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERIC
-
#else
-
# define ANDROID_DEBUG
-
# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERATED
- #endif
-
-
// hack
好了,目前大致上就遇到这样一些问题。如果今后又出现再收拾。但是,不,现在还不能打 make 命令进行编译,原因是……
2.5 收拾 prebuilt 工具链
/* 未完待续 */
阅读(2645) | 评论(0) | 转发(1) |