TA的每日心情 | 开心 2019-11-20 15:05 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1 uCLinux及KVM简介3 S. P( F* Q, p. s4 F" J9 X8 O
1 z( m: c% X+ O3 s. u; UuCLinux是一款优秀的嵌入式Linux操作系统,是micro-Conrol-Linux的缩写,同时也是开放源码的嵌入式Linux的典范之作。uCLinux主要是针对目标处理器没有存储管理单元MMU(Memory Management Unit) 的嵌入式系统而设计的,它已经被成功地移植到了很多平台上。它秉承了标准Linux的优良特性,经过各方面的小型化改造,形成了一个高度优化的、代码紧凑的嵌入式Linux。虽然它的体积很小,却仍然保留了Linux的大多数优点:稳定、良好的移植性、优秀的网络功能、对各种文件系统完备的支持和标准丰富的API。它专为嵌入式系统做了许多小型化的工作,目前已支持多款CPU。其编译后的目标文件可控制在几百KB数量级,并已被成功地移植到很多平台上。9 L' s- w- _$ m+ |
]+ p' ]$ K( K) n( Q) H! s; p0 gKVM是一种专门为嵌入式设备使用的JAVA虚拟机,它主要为J2ME CLDC使用。KVM可以理解为K Virtual Machine或者是 KJava Virtual Machine。是一种精简,可移植的,专门为小设备,有内存,CPU等资源限制(例如:手机,PDA,POS机等嵌入式设备)设计的JAVA虚拟机。3 M9 J5 |- h9 J1 I4 {3 H
$ x' H* L D2 N1 uKVM的目的是创造一个尽可能小的且尽可能完整的JAVA虚拟机,使开发者不用像开发C语言一样关心硬件,而通过JAVA语言来进行开发,达到一次编译,各种平台使用的目的。! e* N2 u& X' A9 H) k
( v, `3 O; j3 t; d6 h( Q! D
2 获取并安装交叉开发工具
5 F% m; A( T. l1 g$ e! F8 F/ v4 R3 d3 {
从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以上的版本进行编译。6 G; i& N: m* _5 f! y+ d6 K
/ i* Z7 R8 ]7 D |3 i, b
3. 获取KVM源代码. {! \" ~* d' z1 W: U$ E* j
& T% \. o- w/ U r* q; p/ S从http://www.sun.com/software/communitysource/j2me/cldc/download.xml获取KVM的源代码文件。
( P4 B- T! i2 m: Z9 s& ^: |. D
+ M8 L! {* @/ b3 k- S# O! p& e 4. 修改KVM的Makefile
4 H- P% z# Z6 O2 i
3 r2 x2 _0 c3 l. N; S4 f1 h下载并且解压CLDC后,下面讲述KVM具体的移植过程:& W5 w- S) d8 v$ B: D
# w3 L# O5 p. M8 g修改j2me_cldc/kvm/VmUnix/build/Makefile文件
; n+ A$ M6 T1 G该Makefile是编译KVM所用到的,因为KVM是用C语言实现的,所以从理论上来讲,也只要使用针对不同体系结构CPU的编译器编译KVM即可,这样也就是如何实现交叉编译KVM的问题了。
. G+ v) D$ i# L* B* {( q% ?9 K3 s* P: Z4 t0 i, p7 _
修改Makefile文件需要熟悉makefile的语法规则,这里不对该语言规则详细讲述,只对修改Makefile过程中涉及的内容做解释,请读者参阅关于makefile语法规则方面的相关资料。所涉及的Makefile修改部分如下:
7 {, D6 m9 U3 w' F/ ^ k9 n9 Z' V+ vifeq ($(PLATFORM), linux)
$ ^) K4 a4 s" e* O0 V1 T# 注释掉原有LIBS = -lm -lnsl
2 u# H/ L1 U* p0 u9 C" r# LIBS = -lm –lnsl' e& g2 q5 y% o! Q6 _/ d* Y
# 添加如下一行: j* u$ Y7 N. l: Z
LIBS =
0 u* F6 ]6 b) M& C# X+ x" b# 注释掉原有CPPFLAGS = -DUNIX -DLINUX -D$(ARCH)
3 I( g& ^- Y2 m2 ?1 U7 y6 p' b# CPPFLAGS = -DUNIX -DLINUX -D$(ARCH). _ z+ m$ _# t
# 修改CPPFLAGS 定义如下:) y( K/ n9 C8 Z% o+ y4 q; s
CPPFLAGS = -D$(ARCH)& J" v4 k( U0 V7 r$ H, d, }, \
-I$(TOP)/kvm/VmCommon/h -I$(TOP)/kvm/VmUnix/h
$ J2 a+ C( s" M-I$(TOP)/kvm/VmExtra/h -I$(TOP)/jam/h -I$(TOP)/kvm/VmCommon/src
' ]$ [* |. T7 j# J! e0 [endif7 @* K$ i2 v" A' [; w, |
BUILD_ROOT=/usr/local4 W( y' P( y- r) ~$ Q+ s2 F
lib1=${BUILD_ROOT}/lib/gcc-lib/arm-elf/3.04 w$ ` u% n \7 I% [* j
lib=${BUILD_ROOT}/arm-elf/lib
% H+ P: q$ F' G/ _; ^$ F% ?0 i0 I) Ginclude=${BUILD_ROOT}/arm-elf/include/
' N1 ]! L! ]: f! i- C6 F# 用arm-elf-gcc定义CC,并指明包括的头文件路径和编译选项
, n1 f/ U* u# E! G4 h6 D( jCC=arm-elf-gcc -I$(include) -D__uClinux__ -D__USE_BSD=1
4 V2 X- _8 W3 k# 用arm-elf-ld定义LD,连接目标文件时使用
: F9 v5 d& Z8 F2 FLD=arm-elf-ld; P; L# l) q; z, U
WEC_LDFLAGS=-L./ -L${lib} -L${lib}/lib -L${lib}/libc -L${lib1} -T${lib}/elf2flt.ld
7 s. t% R7 D* ?) G$ BEXTLIBS= -lc -lgcc -lc9 h5 ^. J, g6 F3 o
LDFLAGS =6 [: p( o. C( D1 [: ]/ ?
ifeq ($(GCC), true)
2 q/ i6 L" L1 x& S- j+ ?
/ e# ^0 q- U n }( L # 注释掉CC = gcc, 事实上由于ifeq ($(GCC), true) 不成立,该处不会执行到。; H5 [5 d& O% q- Y# j8 J% v
# CC = gcc* ?! t, U; Y C' O
CFLAGS = -Wall $(CPPFLAGS) $(ROMFLAGS) $(OTHER_FLAGS)
- d: r3 `: h; B) @: k0 F$ m! iDEBUG_FLAG = -g
: h' r R$ l; t0 ~OPTIMIZE_FLAG = -O22 ?: t0 i) W9 X$ n, \1 V
else
X3 K$ D2 u ~" o# R# 注释掉CC = cc 一行,这样,系统采用CC=arm-elf-gcc 编译KVM2 j) m: V, Z' F0 O
# CC = cc
7 A! N z: A* x0 d$ CCFLAGS = -Xa $(CPPFLAGS) $(ROMFLAGS) $(OTHER_FLAGS)9 h; E" }: l& m* ~
DEBUG_FLAG = -g -xsb
/ y/ [6 r r/ K4 \# TOPTIMIZE_FLAG = -xO2$ I0 A9 ~& z! [6 H k; z2 X+ m, J
endif- X+ N7 q4 E/ c# P2 s/ m
DEBUG_FLAG += -DINCLUDEDEBUGCODE=1& H) V9 m1 t5 ?, s, p) l/ Y; P- r4 ]
$(TOP)/tools/jcc/ROMjavaUnix.c $(TOP)/tools/jcc/nativeFunctionTableUnix.c: jcc
; G L5 F+ H5 ~! \' B! i& xUnix) T+ y- m8 ~7 _, P
.PHONY: jccUnix
( E0 v" I. `/ `; n6 r0 V# djccUnix:# ~0 W! t; R; ^8 x' |. ~0 h
@(cd $(TOP)/tools/jcc; $(MAKE) unix) A4 l! `3 R" Z& g' i1 b# S
kvm$(j)$(g): obj$j$g/ $(CLEANUPXPM) $(OBJFILES)
5 p) H" ?/ {0 M@Echo "Linking ... $@"3 g: J$ G+ k: a8 Y1 V
# 注释掉@$(CC) $(OBJFILES) -o $@ $(LIBS) $(EXTLIBS) 一行% i2 a7 s; s0 l# W, F: C
# @$(CC) $(OBJFILES) -o $@ $(LIBS) $(EXTLIBS)
G+ s- b; M% H! f5 i2 x# 用arm-elf-ld连接目标文件0 O' n* \2 ]& m5 P) A$ F
$(LD) -o kvm.x $(WEC_LDFLAGS) -r -d $(OBJFILES) $(LIBS) $(EXTLIBS) -Map kvm.map% n: Y- U$ j+ ?
5 X' J. s; L3 L
5. 编译uCLinux版本的KVM
1 d; _$ d5 i/ M3 |: |7 c9 ~3 P& U
, J \7 i/ \$ a! l9 H# `: Q- N修改Makefile后,切换到j2me_cldc/build/linux目录,执行make命令编译kvm。如果不能通过编译,建议用arm-elf-gcc3.0以上版本的交叉编译工具进行编译。编译完成后,将在j2me_cldc/kvm/VmUnix/build目录下生成kvm.x文件,因为uClinux操作系统上可执行文件都必须为Flat格式,需用elf2flt工具对kvm.x进行转换。在终端提示符下执行如下命令:. z R3 \% ]. X2 z- A. W" f
elf2lft –o kvm kvm.x4 f& d g w: s/ ]9 f
生成kvm可执行文件,至此,整个kvm编译过程完成。9 S" B/ p0 c, f; ~0 h+ \* L
4 ?0 ~9 \' E; \/ @ E( a. Z
6. 测试KVM* |0 _; g7 W" Y [
, [6 Q, l* f: N. i! h; T& c1 h
这样编译出来的kvm是针对ARM体系结构的,所以在Red Hat Linux 7.3系统上无法运行,读者可以编辑“Hello World”程序。然后在终端提示符下做如下测试:: w0 Q! W# ~7 y' R; N5 n
( s* [! x# H; D: J- ^
./kvm –classpath j2me_cldc/samples/classes HelloWorld
4 }6 b9 M+ E6 [0 K/ u3 ]/ o程序报错,这说明当前编译出来的KVM不是针对X86体系结构。接下来下载kvm到运行uClinux操作系统的嵌入式设备上,再测试kvm。
5 E: e: g' e2 i' R5 K
$ S7 V4 [& W- H1 p! D拷贝kvm以及HelloWorld.class到 uClinux-dist/romfs/bin目录下执行make image,生成包含kvm及HelloWorld.class的romfs.img
% m( N, R$ O, ?下载image.ram和romfs.img到板子上uClinux系统启动后,输入如下命令测试1 u* x( j& ^1 d( d/ O7 ?- S2 U: X
./kvm –classpath /bin HelloWorld, L9 e: H. n' A! S( \/ X' s" G
: t/ r9 ~; N8 w% b& _6 @ 7. 小结; m" [2 D; z1 h' R
) j- t! J7 Z. T本文以uCLinux嵌入式操作系统为例讨论了KVM的移植过程,若读者希望在其他体系结构的嵌入式Linux(比如PPC Linux, MIPS Linux)系统上移植KVM,可以根据其编译环境修改KVM的Makefile进行编译。如果为让系统支持更多的功能,如MIDP等,则需要作进一步的研究与探索。
6 O& N0 a. M8 N3 j8 W |
|