Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2775792
  • 博文数量: 505
  • 博客积分: 1552
  • 博客等级: 上尉
  • 技术积分: 2514
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-23 18:24
文章分类

全部博文(505)

文章存档

2019年(12)

2018年(15)

2017年(1)

2016年(17)

2015年(14)

2014年(93)

2013年(233)

2012年(108)

2011年(1)

2009年(11)

分类:

2012-03-24 10:36:22

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 禁用 codeflinger

Pixelflinger 是 Android 自带的软件 OpenGL 实现。它有个很特别的功能叫 codeflinger,可以在运行时根据需要动态生成机器指令函数。Android 自带的 codeflinger 产生 ARMv6 代码,MIPSAndroid 移植后产生 MIPS32 代码。为了能在龙芯上用,不得已禁用掉 codeflnger 功能:

  1. diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
  2. old mode 100644
  3. new mode 100755
  4. index e0a25c4..b2d864d
  5. --- a/libpixelflinger/scanline.cpp
  6. +++ b/libpixelflinger/scanline.cpp
  7. @@ -46,10 +46,11 @@

  8. #ifdef NDEBUG
  9. # define ANDROID_RELEASE
  10. -# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERATED
  11. +# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERIC
  12. #else
  13. # define ANDROID_DEBUG
  14. # define ANDROID_CODEGEN ANDROID_CODEGEN_GENERATED
  15. #endif

  16. // hack


好了,目前大致上就遇到这样一些问题。如果今后又出现再收拾。但是,不,现在还不能打 make 命令进行编译,原因是……

2.5 收拾 prebuilt 工具链/* 未完待续 */
阅读(2401) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~