TA的每日心情 | 开心 2019-11-20 15:05 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1 uCLinux及KVM简介$ U- |- m" f* F3 {* C1 c, d7 p+ ^
+ h' V) p1 L) c" I+ O
uCLinux是一款优秀的嵌入式Linux操作系统,是micro-Conrol-Linux的缩写,同时也是开放源码的嵌入式Linux的典范之作。uCLinux主要是针对目标处理器没有存储管理单元MMU(Memory Management Unit) 的嵌入式系统而设计的,它已经被成功地移植到了很多平台上。它秉承了标准Linux的优良特性,经过各方面的小型化改造,形成了一个高度优化的、代码紧凑的嵌入式Linux。虽然它的体积很小,却仍然保留了Linux的大多数优点:稳定、良好的移植性、优秀的网络功能、对各种文件系统完备的支持和标准丰富的API。它专为嵌入式系统做了许多小型化的工作,目前已支持多款CPU。其编译后的目标文件可控制在几百KB数量级,并已被成功地移植到很多平台上。% N- t: E3 u2 D3 h; H
: F( i t) J% y5 M
KVM是一种专门为嵌入式设备使用的JAVA虚拟机,它主要为J2ME CLDC使用。KVM可以理解为K Virtual Machine或者是 KJava Virtual Machine。是一种精简,可移植的,专门为小设备,有内存,CPU等资源限制(例如:手机,PDA,POS机等嵌入式设备)设计的JAVA虚拟机。+ @1 f0 z6 w0 Q$ k$ V
! A7 S" [: A/ ^/ A/ m7 F: G. ]KVM的目的是创造一个尽可能小的且尽可能完整的JAVA虚拟机,使开发者不用像开发C语言一样关心硬件,而通过JAVA语言来进行开发,达到一次编译,各种平台使用的目的。
2 E. l* h; Y1 S6 O7 w* U8 K7 Y) B7 M( @0 H2 [3 |: L- F
2 获取并安装交叉开发工具
& L* N g8 a; r/ V+ ?0 a p# o' u+ I# ]9 t/ e* }1 r- Z: j
从http://sourceforge.net/project/showfiles.php?group_id=58162&package_id=54041获取ARM-elf-tools交叉编译安装包。这里笔者曾经使用arm-elf-tools-20030314.sh编译KVM,但遇到编译错误。所以建议各位读者下载arm-elf-gcc3.0以上的版本进行编译。
- l4 y" J! i3 i
8 j) v$ I4 J, o4 \, y8 M" T 3. 获取KVM源代码1 b7 I1 `/ u2 c. F5 h& o+ r8 c$ N" L
: N0 g' g- N' V6 g& u5 ?) U从http://www.sun.com/software/communitysource/j2me/cldc/download.xml获取KVM的源代码文件。, R1 _; |1 d1 E
) Y# ]8 ]( `# R; o- P; f 4. 修改KVM的Makefile
$ q$ ^* |. Y2 E$ e; z( ]% J) W I4 E+ t* k% `. Q- r, w) N
下载并且解压CLDC后,下面讲述KVM具体的移植过程:. O% e* F6 I6 n) b2 F; |
4 u% E5 S9 D y* _
修改j2me_cldc/kvm/VmUnix/build/Makefile文件
7 k9 ~' R2 S* B* i9 k该Makefile是编译KVM所用到的,因为KVM是用C语言实现的,所以从理论上来讲,也只要使用针对不同体系结构CPU的编译器编译KVM即可,这样也就是如何实现交叉编译KVM的问题了。
" v4 `+ d/ w2 q5 A& S
5 T/ c% v* X, O n' Q& Q修改Makefile文件需要熟悉makefile的语法规则,这里不对该语言规则详细讲述,只对修改Makefile过程中涉及的内容做解释,请读者参阅关于makefile语法规则方面的相关资料。所涉及的Makefile修改部分如下:
! A' f/ b9 C7 G9 \; S2 [7 S bifeq ($(PLATFORM), linux), U0 A5 f6 E" y: ]: f
# 注释掉原有LIBS = -lm -lnsl
o1 S' U" O8 C5 p8 x# LIBS = -lm –lnsl
1 w( l1 u! U. T& `# 添加如下一行! C E- b! d: P; C3 W# V
LIBS =! ~; z9 S4 K0 c
# 注释掉原有CPPFLAGS = -DUNIX -DLINUX -D$(ARCH)3 D5 T& [+ y- Q" @
# CPPFLAGS = -DUNIX -DLINUX -D$(ARCH)
( i7 _, i2 m/ }# V# 修改CPPFLAGS 定义如下:
$ S5 r! t. I0 P2 B- cCPPFLAGS = -D$(ARCH)
6 n- f+ Z s& @7 f& c' c L+ v% N-I$(TOP)/kvm/VmCommon/h -I$(TOP)/kvm/VmUnix/h" F* X8 N, _' S% k$ G1 D, L# @! q
-I$(TOP)/kvm/VmExtra/h -I$(TOP)/jam/h -I$(TOP)/kvm/VmCommon/src1 E, [& p' A# {: N5 M, o
endif! N9 H1 F/ W1 M; b" Z
BUILD_ROOT=/usr/local; j; K0 S, n2 G0 N# j. r& h
lib1=${BUILD_ROOT}/lib/gcc-lib/arm-elf/3.0
. G) w3 t/ [- ?" `3 T3 t" k) M! H2 `lib=${BUILD_ROOT}/arm-elf/lib
4 J" u1 t8 e: Z# ^$ ^- R2 E) yinclude=${BUILD_ROOT}/arm-elf/include/$ B' d5 s- b1 w* d4 X
# 用arm-elf-gcc定义CC,并指明包括的头文件路径和编译选项# G: s. A5 n+ ~
CC=arm-elf-gcc -I$(include) -D__uClinux__ -D__USE_BSD=1
+ l2 }' b3 c' |# 用arm-elf-ld定义LD,连接目标文件时使用 c* m0 X4 ]9 n8 ?. M. {: D
LD=arm-elf-ld
/ i; F' k, W t/ ~) G1 pWEC_LDFLAGS=-L./ -L${lib} -L${lib}/lib -L${lib}/libc -L${lib1} -T${lib}/elf2flt.ld
" j- \; t) O/ N9 k* u; xEXTLIBS= -lc -lgcc -lc# [0 Q7 E& \/ m" ~7 Q
LDFLAGS =
5 @$ W, m5 c1 \ifeq ($(GCC), true)% M) o* a! X) ]5 L& w7 B" b
; |+ r5 Q7 K! x$ S1 q1 ]9 X # 注释掉CC = gcc, 事实上由于ifeq ($(GCC), true) 不成立,该处不会执行到。
! U1 z/ v& S# g. i# CC = gcc
2 T: n* L% M) P' `& z( A* yCFLAGS = -Wall $(CPPFLAGS) $(ROMFLAGS) $(OTHER_FLAGS)
6 d. ~6 Q: q. o* mDEBUG_FLAG = -g$ q8 ^. l0 Z" R8 A$ E( \3 e/ f6 I& [
OPTIMIZE_FLAG = -O2
* i) A, H- i9 |" }0 N6 velse
S0 E" q3 O# \* x4 J% H) V5 y# 注释掉CC = cc 一行,这样,系统采用CC=arm-elf-gcc 编译KVM- j2 }1 o5 ?; e* P
# CC = cc
5 M$ P5 `9 e$ e3 BCFLAGS = -Xa $(CPPFLAGS) $(ROMFLAGS) $(OTHER_FLAGS)
! f' U3 ~; z! ?$ C' |7 d. NDEBUG_FLAG = -g -xsb
3 c! g2 N( O; q' y rOPTIMIZE_FLAG = -xO2
: m& {' I v& U8 p* h& h5 Uendif
4 N9 @( C) M- K4 ]. ]2 o. bDEBUG_FLAG += -DINCLUDEDEBUGCODE=15 {- p4 b, O, S% g- s4 Y. m
$(TOP)/tools/jcc/ROMjavaUnix.c $(TOP)/tools/jcc/nativeFunctionTableUnix.c: jcc
- W) d, `. D, \1 q; @9 EUnix
y9 c5 Y4 v& Q: m! u8 Y5 l.PHONY: jccUnix& H$ s' W0 \! E2 C
jccUnix:& J7 l# w( `! x
@(cd $(TOP)/tools/jcc; $(MAKE) unix)! x' r6 _+ ]8 l t% f
kvm$(j)$(g): obj$j$g/ $(CLEANUPXPM) $(OBJFILES)" c& y$ X5 s- M
@Echo "Linking ... $@" z: H4 g" X8 g
# 注释掉@$(CC) $(OBJFILES) -o $@ $(LIBS) $(EXTLIBS) 一行
" o" \0 \0 }' v' F9 @+ Q$ W# @$(CC) $(OBJFILES) -o $@ $(LIBS) $(EXTLIBS)
: _4 y, r( ^4 ^: N2 g4 `/ |( i+ d! ^# 用arm-elf-ld连接目标文件, k. @9 O& X3 p* o7 G6 ~& R
$(LD) -o kvm.x $(WEC_LDFLAGS) -r -d $(OBJFILES) $(LIBS) $(EXTLIBS) -Map kvm.map$ k# B/ y( n6 B) |2 C2 Q# Q* m
7 s9 e: \/ \% H- X3 K/ U* i 5. 编译uCLinux版本的KVM
) x9 N l! f& U( O# O) D" G9 ]4 X9 L! v* K' S, @
修改Makefile后,切换到j2me_cldc/build/linux目录,执行make命令编译kvm。如果不能通过编译,建议用arm-elf-gcc3.0以上版本的交叉编译工具进行编译。编译完成后,将在j2me_cldc/kvm/VmUnix/build目录下生成kvm.x文件,因为uClinux操作系统上可执行文件都必须为Flat格式,需用elf2flt工具对kvm.x进行转换。在终端提示符下执行如下命令:
; [1 ?1 X% t1 p; O6 _3 P" Velf2lft –o kvm kvm.x; M; x/ O$ t5 |5 e
生成kvm可执行文件,至此,整个kvm编译过程完成。
- k5 M" f. V4 `
! h$ u! s* h: P' q& [ 6. 测试KVM
- h K! v4 v1 u1 b7 R y. l& T4 T5 U. Y# ~' T8 T* u9 p
这样编译出来的kvm是针对ARM体系结构的,所以在Red Hat Linux 7.3系统上无法运行,读者可以编辑“Hello World”程序。然后在终端提示符下做如下测试:
2 @8 m1 u4 O; f& @! p3 A$ H3 G8 K( H
./kvm –classpath j2me_cldc/samples/classes HelloWorld& c6 t' N" U, H& P
程序报错,这说明当前编译出来的KVM不是针对X86体系结构。接下来下载kvm到运行uClinux操作系统的嵌入式设备上,再测试kvm。 M8 f8 b f V
( n( J; z2 U! R3 V/ C7 \
拷贝kvm以及HelloWorld.class到 uClinux-dist/romfs/bin目录下执行make image,生成包含kvm及HelloWorld.class的romfs.img% ^- s- a& k3 a3 Z: B( b+ Y
下载image.ram和romfs.img到板子上uClinux系统启动后,输入如下命令测试+ p1 S* T( @7 U- R2 ~
./kvm –classpath /bin HelloWorld7 t" G4 _( [8 i& G9 O
; B7 P/ x6 F6 m% w5 Y+ t, G# Q
7. 小结
$ f3 g# z3 D% |" Y# Y
1 C6 D: i7 u" R( ~本文以uCLinux嵌入式操作系统为例讨论了KVM的移植过程,若读者希望在其他体系结构的嵌入式Linux(比如PPC Linux, MIPS Linux)系统上移植KVM,可以根据其编译环境修改KVM的Makefile进行编译。如果为让系统支持更多的功能,如MIDP等,则需要作进一步的研究与探索。
' Q2 q+ X! D' L; e |
|