Linux系統(tǒng)移植(第2版):第19章 JVM及其移植_第1頁(yè)
Linux系統(tǒng)移植(第2版):第19章 JVM及其移植_第2頁(yè)
Linux系統(tǒng)移植(第2版):第19章 JVM及其移植_第3頁(yè)
Linux系統(tǒng)移植(第2版):第19章 JVM及其移植_第4頁(yè)
Linux系統(tǒng)移植(第2版):第19章 JVM及其移植_第5頁(yè)
已閱讀5頁(yè),還剩52頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第19章JVM及其移植19.1JVM介紹19.2類裝載19.3垃圾回收19.4解析器19.5Java編程淺析19.6KVM執(zhí)行過(guò)程19.7PC機(jī)安裝JVM19.8KVM移植和測(cè)試19.1JVM介紹19.1.1JVM原理19.1.2JVM支持的數(shù)據(jù)類型19.1.3JVM指令系統(tǒng)19.1.4JVM寄存器19.1.5JVM棧結(jié)構(gòu)19.1.6JVM碎片回收堆19.1.7JVM異常拋出和異常捕獲19.1.1JVM原理Java語(yǔ)言的特點(diǎn)就是平臺(tái)無(wú)關(guān)性。Java程序經(jīng)過(guò)編譯后運(yùn)行在Java虛擬機(jī)上,屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼)。19.1.2

JVM支持的數(shù)據(jù)類型分

類數(shù)據(jù)類型說(shuō)

明基本的數(shù)據(jù)類型byte1字節(jié)有符號(hào)整數(shù)的補(bǔ)碼short2字節(jié)有符號(hào)整數(shù)的補(bǔ)碼int4字節(jié)有符號(hào)整數(shù)的補(bǔ)碼long8字節(jié)有符號(hào)整數(shù)的補(bǔ)碼float4字節(jié)IEEE754單精度浮點(diǎn)數(shù)double8字節(jié)IEEE754雙精度浮點(diǎn)數(shù)char2字節(jié)無(wú)符號(hào)Unicode字符其他數(shù)據(jù)類型object4字節(jié),對(duì)一個(gè)Javaobject(對(duì)象)的引用returnAddress4字節(jié),用于jsr/ret/jsr-w/ret-w指令19.1.3JVM指令系統(tǒng)Java指令也是由操作碼和操作數(shù)兩部分組成。操作碼是8位二進(jìn)制數(shù),操作數(shù)緊跟在操作碼后面,其長(zhǎng)度根據(jù)需要而不同。操作碼指定一條指令操作的功能。Java指令系統(tǒng)是專門為Java語(yǔ)言的實(shí)現(xiàn)而設(shè)計(jì)的,還包括用于調(diào)用方法和監(jiān)視多線程系統(tǒng)的指令。19.1.4

JVM寄存器JVM只設(shè)置了以下4個(gè)最為常用的寄存器:pc:程序計(jì)數(shù)器。optop:操作數(shù)棧頂指針。frame:當(dāng)前執(zhí)行環(huán)境指針。vars:指向當(dāng)前執(zhí)行環(huán)境中第一個(gè)局部變量的指針。19.1.5JVM棧結(jié)構(gòu)作為基于棧結(jié)構(gòu)的計(jì)算機(jī),Java棧是JVM存儲(chǔ)信息的主要手段。每個(gè)棧框架包括3類信息:局部變量、執(zhí)行環(huán)境和操作數(shù)棧。1.PushFrame()函數(shù)操作2.popFrame操作1.PushFrame()函數(shù)操作函數(shù)pushFrame()為當(dāng)前執(zhí)行線程創(chuàng)建一個(gè)新的棧幀。在分配幀前,所有的寄存器都必須被正確地初始化。KVM與其他JVM不同,它不為局部函數(shù)調(diào)用創(chuàng)建棧幀。2.popFrame操作函數(shù)popFrame()用于刪除一個(gè)執(zhí)行幀棧及調(diào)用當(dāng)前執(zhí)行方法時(shí)重啟執(zhí)行方法。voidpopFrame(){

/*復(fù)位虛擬機(jī)寄存器去繼續(xù)前向方法的執(zhí)行*/

POPFRAMEMACRO}19.1.6

JVM碎片回收堆Java程序中對(duì)內(nèi)存進(jìn)行釋放和回收的工作是由運(yùn)行系統(tǒng)Java承擔(dān)的,即JVM來(lái)完成。在Sun公司開(kāi)發(fā)的Java解釋器和HotJava環(huán)境中,采用后臺(tái)線程來(lái)執(zhí)行碎片回收。JVM有兩種類型的存儲(chǔ)區(qū):常量緩沖區(qū)和方法區(qū)。19.1.7

JVM異常拋出和異常捕獲異常拋出會(huì)使當(dāng)前方法異常結(jié)束。將類的異常Handler放在類文件的一個(gè)表中,當(dāng)異常發(fā)生時(shí),JVM會(huì)從存放異常Handler的表中找到合適的異常處理執(zhí)行,如果當(dāng)前方法沒(méi)有合適的處理對(duì)應(yīng)當(dāng)前異常Handler,則將當(dāng)前方法的Frame彈出,扔掉Operandstack和局部變量,返回到當(dāng)前方法的調(diào)用者中,再重復(fù)前面的過(guò)程,直到到達(dá)調(diào)用鏈表的頂端。如果最外層的方法也沒(méi)有合適的Handler,就退出當(dāng)前線程。19.2類裝載19.2.1裝載類的結(jié)構(gòu)體19.2.2裝載類的操作19.2.1裝載類的結(jié)構(gòu)體在實(shí)現(xiàn)類裝載時(shí),KVM定義了幾個(gè)數(shù)據(jù)結(jié)構(gòu)structclassStruct、structinstanceClassStruct和structarrayClassStruct,這幾個(gè)數(shù)據(jù)結(jié)構(gòu)用來(lái)保存類的相關(guān)信息。結(jié)構(gòu)體classStruct如下:structclassStruct{

COMMON_OBJECT_INFO(INSTANCE_CLASS)

UStringpackageName;

/*最后符號(hào)'/'之前的所有內(nèi)容*/

UStringbaseName;

/*最后符號(hào)'/'之后的所有內(nèi)容*/

CLASSnext;

/*哈希表的下一項(xiàng)*/

unsignedshortaccessFlags;

/*訪問(wèn)信息*/

unsignedshortkey;

/*類關(guān)鍵字*/};typedefstructclassStruct*

CLASS;19.2.1裝載類的結(jié)構(gòu)體結(jié)構(gòu)體instanceClassStruct定義如下:structinstanceClassStruct{

structclassStructclazz;

/*公共信息*/

/*

instanceclasses的專有信息*/

INSTANCE_CLASSsuperClass;

/*超類對(duì)象*/

CONSTANTPOOLconstPool;

/*常量池指針*/

FIELDTABLEfieldTable;

/*實(shí)例變量表指針*/

METHODTABLEmethodTable;

/*虛擬方法表指針*/

unsignedshort*

ifaceTable;

/*接口表指針*/

POINTERLISTstaticFields;

/*保持類的靜態(tài)域*/

shortinstSize;

/*類的實(shí)例大小*/

shortstatus;

/*類的就緒狀態(tài)*/

THREADinitThread;

/*類的初始化線程*/

NativeFuncPtrfinalizer;

/*finalizer指針*/};typedefstructinstanceClassStruct*

INSTANCE_CLASS;19.2.1裝載類的結(jié)構(gòu)體結(jié)構(gòu)體arrayClassStruct的定義如下:structarrayClassStruct{

structclassStructclazz;

/*公共信息*/

/*數(shù)組類成員專有信息*/

union{

CLASSelemClass;

/*數(shù)組對(duì)象成員類*/

longprimType;

/*原數(shù)組的成員類型*/

}u;

longitemSize;

/*單個(gè)成員的大小*/

longgcType;

/*垃圾收集的類型,GCT_ARRAY或GCT_OBJECTARRAY*/

longflags;

};typedefstructarrayClassStruct*

ARRAY_CLASS;19.2.2裝載類的操作上面介紹了類裝載保存的結(jié)構(gòu)體,下面介紹裝載類的幾個(gè)操作函數(shù)LoadClass

Locally()、LoadClassFromFile()、LoadClassFromZip(),3個(gè)函數(shù)分別從不同的方式裝載類。1.函數(shù)LoadClassFromFile()函數(shù)LoadClassFromFile()從磁盤裝載一個(gè)解析器要求的類文件(.class格式文件),通過(guò)創(chuàng)建一個(gè)類塊結(jié)構(gòu)體裝載編譯好的類。2.函數(shù)LoadClassFromZip()函數(shù)LoadClassFromZip()通過(guò)zip格式文件裝載類。函數(shù)LoadClassFromFile()與LoadClassFromZip()基本類似,只是兩者讀取的文件格式不同而已,前者為.class格式,后者為.jar格式。3.函數(shù)LoadClassLocally()函數(shù)LoadClassLocally(),輸入?yún)?shù)為指向類文件的本地路徑,其中會(huì)調(diào)用函數(shù)LoadClassFromFile()。19.3垃圾回收19.3.1mark-and-sweep回收算法19.3.2分代回收算法19.3.3增量收集19.3.1mark-and-sweep回收算法KVM中的mark-and-sweep回收算法分為兩個(gè)階段,第一階段為mark階段,垃圾收集器從rootset開(kāi)始搜索,標(biāo)記每個(gè)可達(dá)的對(duì)象。第二個(gè)階段為sweep階段,垃圾收集器從內(nèi)存空間的起始地址往后查找,回收那些沒(méi)有在第一階段標(biāo)記的對(duì)象所占有的空間,回收的空間加入到內(nèi)存可用列表中。1.垃圾收集函數(shù)garbageCollect()void

garbageCollect(intmoreMemory){

if(gcInProgress!=0){

/*不允許循環(huán)調(diào)用垃圾回收操作*/

fatalVMError(KVM_MSG_CIRCULAR_GC_INVOCATION);

}

gcInProgress++;

/*等待所有的異步I/O完成*/

RundownAsynchronousFunctions();

if(ENABLEPROFILING&&INCLUDEDEBUGCODE){

checkHeap();

}

MonitorCache=NULL;

/*清除所有臨時(shí)監(jiān)視器*/1.垃圾收集函數(shù)garbageCollect()

/*在垃圾收集前,保存當(dāng)前活動(dòng)的線程的虛擬機(jī)寄存器*/

if(CurrentThread){

storeExecutionEnvironment(CurrentThread);

}

/*該函數(shù)為mark-and-sweep回收算法實(shí)現(xiàn)核心部分,后面給出其實(shí)現(xiàn)的主要代碼*/

garbageCollectForReal(moreMemory);

/*完成垃圾收集后,載入執(zhí)行環(huán)境*/

if(CurrentThread){

loadExecutionEnvironment(CurrentThread);

}

/*允許異步I/O繼續(xù)*/

RestartAsynchronousFunctions();

/*恢復(fù)垃圾收集結(jié)束標(biāo)志*/

gcInProgress=0;}2.垃圾收集函數(shù)garbageCollectForReal()void

garbageCollectForReal(intrealSize){

CHUNKfirstFreeChunk;

longmaximumFreeSize;

/*下面是垃圾收集算法實(shí)現(xiàn)部分*/

markRootObjects();

//標(biāo)志垃圾收集的root對(duì)象

markNonRootObjects();

//查找堆棧搜索僅從其他堆棧對(duì)象可達(dá)的對(duì)象

markWeakPointerLists();

//標(biāo)志弱指針列表markWeakReferences();

//標(biāo)記弱引用對(duì)象,弱引用對(duì)象將被清除/*實(shí)現(xiàn)mark-and-sweep算法的sweep階段,釋放沒(méi)有活動(dòng)的方法所占用的堆??臻g*/firstFreeChunk=sweepTheHeap(&maximumFreeSize);

/*compact階段,通過(guò)內(nèi)存的移動(dòng)構(gòu)建較大的可用空間*/2.垃圾收集函數(shù)garbageCollectForReal()#ifENABLE_HEAP_COMPACTION

if(realSize>maximumFreeSize){

/*對(duì)堆棧實(shí)行緊縮操作,獲得可用空間*/

breakTableStructcurrentTable;

cell*

freeStart=

compactTheHeap(¤tTable,firstFreeChunk);

/*得到可用空間后,進(jìn)行更新操作,更新root對(duì)象表和堆棧對(duì)象表*/

if(currentTable.length>0){

updateRootObjects(¤tTable);

updateHeapObjects(¤tTable,freeStart);

}

if(freeStart<CurrentHeapEnd-1){

firstFreeChunk=(CHUNK)freeStart;

firstFreeChunk->size=

(CurrentHeapEnd-freeStart-HEADERSIZE)<<TYPEBITS;

firstFreeChunk->next=NULL;

}else{

/*內(nèi)存完全滿時(shí),沒(méi)有多余的空間可以通過(guò)移動(dòng)內(nèi)存來(lái)獲得*/

firstFreeChunk=NULL;

}

}#endif

FirstFreeChunk=firstFreeChunk;}19.3.2分代回收算法分代回收算法是根據(jù)對(duì)象存在時(shí)間長(zhǎng)短將對(duì)象進(jìn)行分類,每個(gè)子堆為一代。隨著對(duì)象的消亡,垃圾回收器從最年輕的子堆開(kāi)始回收對(duì)象。分代回收算法在一定程度上降低了垃圾回收給應(yīng)用帶來(lái)的負(fù)擔(dān),使應(yīng)用的吞吐量達(dá)到極限值。分代垃圾回收算法為考慮實(shí)時(shí)性要求而提供了并發(fā)回收器,支持最大暫停時(shí)間的設(shè)置,但是受到分代垃圾回收的內(nèi)存劃分模型限制,其效果并不理想。19.3.3增量收集增量收集的方式在理論上可以解決分代收集方式帶來(lái)的問(wèn)題。增量收集把堆空間劃分成一系列內(nèi)存塊,使用時(shí),先使用其中一部分,垃圾收集時(shí)把之前使用部分中的存活對(duì)象再放到后面沒(méi)有使用的空間中,因此可以實(shí)現(xiàn)邊使用邊收集的效果,避免了分代方式使用完整個(gè)內(nèi)存空間再暫?;厥盏那闆r。19.4解析器19.4.1函數(shù)Interpret()19.4.2函數(shù)FastInterpret()19.4.3函數(shù)SlowInterpret()19.4.1函數(shù)Interpret()函數(shù)Interpret()在函數(shù)KVM_Start()中被調(diào)用。在該函數(shù)的catch尾部調(diào)用END_CATCH_AND_GOTO(startTry),該函數(shù)相當(dāng)于執(zhí)行g(shù)oto功能跳轉(zhuǎn)到startTry處,因此在該函數(shù)體內(nèi)循環(huán)執(zhí)行函數(shù)FastInterpret()進(jìn)行解析工作。19.4.2函數(shù)FastInterpret()函數(shù)FastInterpret()是執(zhí)行解析的真正實(shí)體函數(shù)。下面為函數(shù)FastInterpret()的主要部分,留下函數(shù)的主干部分,便于清楚函數(shù)的整體實(shí)現(xiàn)。函數(shù)FastInterpret()的關(guān)鍵部分為switch結(jié)構(gòu)部分,該部分根據(jù)寄存器變量token的值,執(zhí)行callMethod_general部分的代碼,對(duì)Java程序中的函數(shù)進(jìn)行解析,包括將函數(shù)解析為具體平臺(tái)的本地函數(shù)。19.4.3函數(shù)SlowInterpret

()函數(shù)SlowInterpret

()在函數(shù)FastInterpret()中被調(diào)用,SlowInterpret()作為次級(jí)解析器。其完成的功能在FastInterpret()函數(shù)中基本可以完成,SlowInterpret()相當(dāng)于FastInterpret()子函數(shù),兩者的風(fēng)格也類似。19.5Java編程淺析19.5.1Java程序命令19.5.2Java構(gòu)造函數(shù)19.5.3Java主函數(shù)19.5.4Java程序編譯與運(yùn)行19.5.1Java程序命令publicclassTestKVM{

//類的定義privateStringtheStates;

//屬性的定義publicStringgetTheStates(){

//方法的定義returntheStates;}publicvoidsetTheStates(StringtheStates){this.theStates=theStates;}}在Java程序中訪問(wèn)的權(quán)限private、public都放在每個(gè)方法和屬性前進(jìn)行單獨(dú)指定,與C++有區(qū)別。19.5.2

Java構(gòu)造函數(shù)下面為構(gòu)造函數(shù)的編寫方式,繼承類在構(gòu)造函數(shù)中顯示調(diào)用父類時(shí)采用super(),示例如下:publicTestKVM(StringtheStates){

//構(gòu)造函數(shù)定義,參數(shù)為成員變量super();this.theStates=theStates;}19.5.3Java主函數(shù)publicclassTestKVM{StringtheStates;publicStringgetTheStates(){returntheStates;}publicvoidsetTheStates(StringtheStates){this.theStates=theStates;}publicTestKVM(StringtheStates){this.theStates=theStates;}/**

*注釋的編寫方式 //注釋的編寫方式

*/publicstaticvoidmain(String[]args){

//主函數(shù)的編寫方式TestKVMt=newTestKVM("kvm");

//對(duì)象實(shí)例化System.out.println(t.getTheStates());

//打印輸出}}編寫完后命名為TestKVM.java。19.5.4

Java程序編譯與運(yùn)行編譯Java程序采用Java編譯器javac,運(yùn)行Java程序也就是通過(guò)解析器執(zhí)行解析Java程序,將Java字節(jié)碼解析成具體平臺(tái)的字節(jié)碼運(yùn)行,其解析器為Java。編譯和運(yùn)行的方式如下:#javacTestKVM.java#javaTestKVM19.6KVM執(zhí)行過(guò)程19.6.1KVM啟動(dòng)過(guò)程19.6.2KVM用到的計(jì)數(shù)器清零19.6.3KVM初始化內(nèi)存管理19.6.4KVM中的哈希表初始化19.6.5KVM中的事件初始化19.6.6KVM中的資源釋放19.6.1KVM啟動(dòng)過(guò)程在了解KVM執(zhí)行過(guò)程前,讀者可以先看KVM的運(yùn)行狀態(tài)圖,在接下來(lái)的分析過(guò)程中主要圍繞該狀態(tài)圖進(jìn)行。19.6.2KVM用到的計(jì)數(shù)器清零函數(shù)InitializeProfiling()用于將KVM用到的計(jì)數(shù)器清零。該函數(shù)中列出了KVM使用的計(jì)數(shù)器19.6.3

KVM初始化內(nèi)存管理在KVM中執(zhí)行前期工作主要用于初始化一些相關(guān)的資源,初始化過(guò)程包括虛擬的硬件和軟件的初始化過(guò)程。在寫Java程序時(shí),不需要程序員釋放空間,虛擬機(jī)會(huì)自動(dòng)幫程序員進(jìn)行垃圾回收,下面分析虛擬機(jī)KVM如何初始化內(nèi)存管理部分。(1)函數(shù)InitializeMemoryManagement()用于初始化內(nèi)存管理。(2)函數(shù)InitializeHeap()用于初始化堆棧。(3)再分配堆棧函數(shù)allocateHeap(),參數(shù)sizeptr為分配堆棧空間的大小,參數(shù)realresultptr返回成功分配的堆棧指針。19.6.4KVM中的哈希表初始化KVM中創(chuàng)建了3個(gè)哈希表,表UTFStringTable用于存儲(chǔ)所有的utfC字符串,表InternStringTable存儲(chǔ)所有用到Java字符串,表ClassTable用于存儲(chǔ)Java類。voidInitializeHashtables(){if(!ROMIZING){

/*創(chuàng)建用于存儲(chǔ)utfC字符串的哈希表*/

createHashTable(&UTFStringTable,UTF_TABLE_SIZE);

/*創(chuàng)建用于存儲(chǔ)Java字符串的哈希表*/

createHashTable(&InternStringTable,INTERN_TABLE_SIZE);

/*創(chuàng)建用于存儲(chǔ)類的哈希表*/

createHashTable(&ClassTable,CLASS_TABLE_SIZE);

}}19.6.4KVM中的哈希表初始化KVM對(duì)哈希表的定義:typedefstructHashTable{

longbucketCount;

/*結(jié)點(diǎn)個(gè)數(shù)*/

long

count;

/*表中所有元素個(gè)數(shù)*/

cell*bucket[1];

/*入口指針數(shù)組*/}

*HASHTABLE;/*存儲(chǔ)Java字符串的哈希表*/externHASHTABLEInternStringTable;/*存儲(chǔ)所有的utfC字符串的哈希表*/externHASHTABLEUTFStringTable;/*存儲(chǔ)Java類*/externHASHTABLEClassTable;19.6.4KVM中的哈希表初始化創(chuàng)建哈希表函數(shù)createHashTable(),參數(shù)tablePtr用于返回創(chuàng)建哈希表的地址,參數(shù)bucketCount表示哈希表的結(jié)點(diǎn)個(gè)數(shù),用于計(jì)算哈希表的大小。void

createHashTable(HASHTABLE*tablePtr,intbucketCount){

/*通過(guò)結(jié)點(diǎn)個(gè)數(shù)計(jì)算哈希表的大小*/

intobjectSize=SIZEOF_HASHTABLE(bucketCount);

/*創(chuàng)建哈希表*/

HASHTABLEtable=(HASHTABLE)callocPermanentObject(objectSize);

/*設(shè)置創(chuàng)建的哈希表結(jié)點(diǎn)個(gè)數(shù)*/

table->bucketCount=bucketCount;

/*創(chuàng)建的哈希表賦給參數(shù)tablePtr返回*/

*tablePtr=table;}19.6.5

KVM中的事件初始化函數(shù)InitializeEvents()用于初始化虛擬機(jī)的事件系統(tǒng),方便虛擬機(jī)的關(guān)閉和重新啟動(dòng)。voidInitializeEvents(){

waitingThread=0;

/*等待線程*/

makeGlobalRoot((cell**)&waitingThread);

/*將等待線程存儲(chǔ)在全局?jǐn)?shù)組GlobalRoots中*/

eventInP=0;

eventCount=0;}19.6.6KVM中的資源釋放voidKVM_Cleanup(){

FinalizeVM();

/*結(jié)束虛擬機(jī)*/

FinalizeInlineCaching();

/*釋放cache*/

FinalizeNativeCode();

/*與InitializeNativeCode()對(duì)應(yīng)*/

FinalizeJavaSystemClasses();

/*釋放Java系統(tǒng)類*/

FinalizeClassLoading();

/*釋放載入類*/

FinalizeMemoryManagement();

/*結(jié)束內(nèi)存管理*/

DestroyROMImage();

/*銷毀ROM*/

FinalizeHashtables();

/*刪除哈希表*/}19.7PC機(jī)安裝JVM19.7.1JVM在Windows上的安裝19.7.2JVM在Linux上的安裝19.7.1JVM在Windows上的安裝在Windows和Linux上安裝JVM都比較簡(jiǎn)單,這里給出其安裝的步驟。(1)下載JDK的Windows安裝文件,安裝在指定的目錄下;(2)設(shè)置環(huán)境變量。19.7.2JVM在Linux上的安裝#tarzxvfjdk-7u25-linux-i586.tar.gz#mvjdk1.7.0_25/usr#cd$HOME#vi.bash_profile//文件.bash_profile中添加下面的內(nèi)容JAVA_HOME=/usr/jdk1.7.0_25PATH=$JAVA_HOME/bin:$PATHCLASSPATH=$JAVA_HOME/lib:/usr/JAVA:./exportJAVA_HOMEPATHCLASSPATH19.8KVM移植和測(cè)試19.8.1SDK安裝和環(huán)境變量設(shè)置19.8.2修改Makefile和代碼19.8.3KVM編譯19.8.4測(cè)試19.8.5移植19.8.1SDK安裝和環(huán)境變量設(shè)置#./

j2sdk-1_4_2_18-linux-i586.bin#y//同意license后進(jìn)行自動(dòng)安裝#vi/root/.bash_profileJAVA_HOME=/usr/j2sdk1.4.2_18PATH=$JAVA_HOME/bin:$PATHCLASSPATH=$JAVA_HOME/lib:/usr/JAVAexportJAVA_HOMEPATHCLASSPATH19.8.2修改Makefile和代碼對(duì)KVM需要進(jìn)行交叉編譯,應(yīng)對(duì)對(duì)應(yīng)的Makefile中應(yīng)該修改gcc為arm-linux-gcc。下載的源碼為j2me_cldc-1_1-fcs-src-winunix.zip,在Linux下可以直接在XWindows模式下通過(guò)右擊解壓,然后復(fù)制到/usr目錄中。1.修改kvm的Makefile進(jìn)入/usr/j2me_cldc/kvm/VmUnix/build目錄下修改Makefile,修改過(guò)程如下:#cd/usr/j2me_cldc/kvm/VmUnix/build#viMakefile增加平臺(tái)定義,可以放在所有條件之前,或者放在Makefile的開(kāi)頭。exportPLATFORM=linux1.修改kvm的Makefile修改gcc為arm-linux-gcc。ifeq($(GCC),true)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論