<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 消費電子 > 業(yè)界動態(tài) > Java虛擬機應用于數(shù)字電視機頂盒的研究與實現(xiàn)

          Java虛擬機應用于數(shù)字電視機頂盒的研究與實現(xiàn)

          作者: 時間:2015-03-28 來源:網(wǎng)絡 收藏

            引 言

          本文引用地址:http://www.ex-cimer.com/article/271729.htm

            隨著有線廣播電視網(wǎng)向數(shù)字化、網(wǎng)絡化、產(chǎn)業(yè)化方向發(fā)展,利用有線電視網(wǎng)絡作為傳輸平臺的數(shù)字電視機頂盒除了能夠讓用戶在現(xiàn)有模擬電視機上觀看數(shù)字電視節(jié)目之外,廣播和交互式多媒體應用功能的要求也應運而生,互動電視成為數(shù)字電視發(fā)展的方向。眾多程序員熟悉的為網(wǎng)絡廣泛運用的語言能很好地滿足機頂盒一些服務應用的要求,因此提出了包含虛擬機的數(shù)字電視機頂盒中間件的系統(tǒng)架構,該虛擬機用來執(zhí)行應用程序,并且中間件將應用程序和底層操作系統(tǒng)、硬件細節(jié)隔離開,使上層的數(shù)字電視的服務應用不必考慮過多的底層細節(jié)。本文主要介紹了J2ME中主要用于數(shù)字電視領域的的移植,其中又著重介紹了本地方法(native method)的實現(xiàn)過程。

            結構及工作原理

            Java虛擬機工作原理

            Java虛擬機處于機器和編譯程序之間,在任何平臺上都提供給編譯程序一個共同的接口。Java源程序經(jīng)過編譯器編譯后變成字節(jié)碼,字節(jié)碼由虛擬機解釋執(zhí)行,虛擬機將每一條要執(zhí)行的字節(jié)碼送給解釋器,解釋器將其翻譯成特定機器上的機器碼,然后在特定的機器上運行。

            Java虛擬機的主要任務是裝載class文件并且執(zhí)行其中的字節(jié)碼。Java虛擬機包含一個類裝載器,它可以從程序和API中裝載class文件。字節(jié)碼由執(zhí)行引擎來執(zhí)行,具體過程如圖1所示。

            

           

            圖1 Java虛擬機的工作過程

            Java虛擬機結構

            類裝載器的體系結構是Java虛擬機在安全性和網(wǎng)絡移動性上發(fā)揮重要作用的一個方面,圖中所示的類裝載器可以包含多個類裝載器的子系統(tǒng), Java應用程序能夠在運行時決定需要安裝的類,并且將被不同的類裝載器裝載的類存放在不同的命名空間。

            執(zhí)行引擎處于Java虛擬機的核心位置,它的行為由指令集所決定,其主要作用就是解釋字節(jié)碼(即運行經(jīng)過編譯后的Java程序的class文件) ,不同的執(zhí)行引擎實現(xiàn)可能非常不同。由軟件實現(xiàn)的虛擬機的執(zhí)行引擎分為一次性解釋字節(jié)碼、即時編譯器和自適應優(yōu)化器,由硬件芯片構成的虛擬機用本地方法執(zhí)行Java字節(jié)碼,它的執(zhí)行引擎是內嵌在芯片里。

            Java虛擬機相當于一個堆棧計算機,它在指令間傳送信息時不使用任何物理寄存器,而使用堆棧的幀來表示方法的狀態(tài)、字節(jié)碼的操作對象、方法的參數(shù)空間及局部變量的空間,它的“程序計數(shù)器”為一個偽寄存器,是當前所執(zhí)行指令的字節(jié)碼數(shù)組的一個指針。

            Java實現(xiàn)方法

            Java有兩種實現(xiàn)方法:Java方法和本地方法。Java方法是由Java 語言編寫,編譯成字節(jié)碼,存儲在class文件中。本地方法是由其他語言(比如C,C++,或者匯編語言)編寫的,編譯成和處理器相關的機器代碼,保存在動態(tài)連接庫中,格式是各個平臺專有的,它是聯(lián)系Java程序和底層主機操作系統(tǒng)的連接方法。Java方法與平臺無關,但是本地方法卻不是,運行中的Java程序調用本地方法時,虛擬機裝載包含這個本地方法的動態(tài)庫,并調用這個方法。通過本地方法, Java程序可以直接訪問底層操作系統(tǒng)的資源,使程序和特定的平臺相關,一個本地方法接口——Java本地接口(JNI)使得本地方法可以在特定的主機系統(tǒng)的任何一個Java平臺上運行。

            J2ME中的移植的解決方案

            我們選用的要移植的Java虛擬機是Sun公司提供的J2ME對于數(shù)字電視領域配置,該虛擬機是針對Linux的軟件實現(xiàn)(用C語言編寫的虛擬機,該虛擬機也稱為C Virtual Machine,簡稱CVM) 。Java虛擬機規(guī)范并沒有強求Java虛擬機必須支持任何特定的本地方法接口,但是Sun 公司提供了本地方法接口(Java Native Interface) ,是為移植所用。Java程序通過調用本地方法和主機交互。

            Java虛擬機

            

           

            圖2 Java虛擬機的位置

            虛擬機處于嵌入式操作系統(tǒng)OS20 上,因此Sun公司提供的Java虛擬機中與底層操作系統(tǒng)相關的操作都應該替換為OS20的內核函數(shù)。因此將Sun公司提供的CDC移植到OS20需要完成一些工作,比如: C語言中關于基本數(shù)據(jù)類型的數(shù)據(jù)位的修改,關于線程的創(chuàng)建機制(OS20為任務) ,關于線程之間的同步、互斥,關于動態(tài)連接的實現(xiàn),關于本地方法的實現(xiàn)等,本節(jié)主要介紹關于本地方法的實現(xiàn)過程。

            本地方法

            解釋器處理字節(jié)碼時,與給定字節(jié)碼有關的動作的語義、執(zhí)行字節(jié)碼的相關動作大多是從堆棧中獲得其操作數(shù),并將其結果送回堆棧中。典型的情況下字節(jié)碼是帶有參數(shù)的,這些參數(shù)在字節(jié)碼流中緊跟在字節(jié)碼自身之后。

            在虛擬機解釋字節(jié)碼過程中,執(zhí)行引擎會不時遇到請求本地方法調用的指令,虛擬機負責試著發(fā)起這個本地方法的調用。本地方法是Java虛擬機指令集的一種可編程擴展,運行這個本地方法就是Java虛擬機對這條指令的執(zhí)行。

            本地方法函數(shù)調用

            為了增加虛擬機的性能,加快其速度,解釋器在處理一些字節(jié)碼時調用的本地方法函數(shù)用匯編實現(xiàn)了將Java棧轉換為C棧,然后在C堆棧上實現(xiàn)函數(shù)的調用。Linux下是用獨立的匯編語言程序invokeNative_i386。 S實現(xiàn)函數(shù)CVMjniInvokeNative () ,我們采用在C里面嵌入?yún)R編的形式來實現(xiàn)該函數(shù)。

            該函數(shù)的形參有7個,完成的主要功能是將由實參傳遞來的部分數(shù)據(jù)通過直接或者運算后得到本地方法的參數(shù),然后壓入本地棧,通過匯編來實現(xiàn)本地的C函數(shù)調用。實參傳遞過來的7個數(shù)據(jù)包含JN I環(huán)境指針(env) 、本地方法的函數(shù)指針(native code) 、Java棧指針(args) 、本地方法的描述符(terse sig) , Java棧的參數(shù)總數(shù)(args size)表示靜態(tài)或非靜態(tài)方法的類對象標志(class object)及用于存儲返回值的一個指針變量(return value) ,其中env要作為第一個本地方法的參數(shù)傳遞,并且native code也要傳遞到本地方法來實現(xiàn)本地方法的正確調用。

            J2ME中的CDC移植

            由于Linux有多個通用寄存器,在實現(xiàn)該函數(shù)的代碼中充分運用了如esp、ebp、esi等寄存器,但是OS20提供的可操作的寄存器只有3個通用寄存器Areg、Breg、Creg和1個工作指針寄存器Wptr (相當于堆棧指針) ,在實現(xiàn)過程中,我們用在C函數(shù)中設立局部變量來代替Linux的通用寄存器,通過手動調整工作棧指針來實現(xiàn)本地方法的調用,具體實現(xiàn)過程如圖3所示。

            

           

            圖3 Java棧到本地棧的轉換

            當進入?yún)R編函數(shù)時,工作區(qū)指針為Wptr,實參、狀態(tài)寄存器和指令指針寄存器的值全部自動入棧,然后是我們定義的代替Linux寄存器的局部變量自動入棧,此時的Wptr自動移到Wptr′,利用OS20的匯編指令,手動將實參傳遞過來的參數(shù)通過計算得到本地方法參數(shù)的個數(shù),然后將本地方法所需的參數(shù)依次壓棧,最后再手動調節(jié)工作區(qū)指針實現(xiàn)本地方法的成功調用。這里我們先將本地方法函數(shù)指針和1個標志位flag(0x10101010)入棧,原因有兩個:

            ①當隨后我們手動調節(jié)工作指針Wptr′到Wptr"時,工作棧已由先前的嵌套匯編的函數(shù)進入到了要調用的本地方法的C函數(shù),因此先前的函數(shù)的局部變量在此時無效,也就是說此時如果用以前實參傳遞過來的本地函數(shù)指針調用本地的函數(shù)肯定不會成功,因此要把這個函數(shù)指針先手動保存起來。

            ②flag的設置的原因是:本地方法的參數(shù)的個數(shù)不是固定的,而OS20 所提供的用匯編調用函數(shù)在回到函數(shù)入口點時只彈出Wptr"指向的4 個單元的內容,因此多余的參數(shù)出棧操作也必須通過調節(jié)Wptr手動完成,通過向下移動Wptr查找flag標志,再調節(jié)Wp tr到Wtpr+2即可正確地回到匯編函數(shù)。當本地方法的參數(shù)完全手動入棧后就可以手動調節(jié)工作區(qū)指針Wptr而進入到調用的本地函數(shù),函數(shù)返回后的第一件事是保存在寄存器中的函數(shù)的返回值到return value,恢復工作區(qū)指針Wptr,并將本地方法的返回值類型作為嵌入?yún)R編的函數(shù)的返回值,此時就完成了由Java棧到C棧的轉換,并成功調用本地方法。

            結 論

            通過對Sun公司下載的CDC代碼的修改與編寫,對CDC中的加載的類做了一些裁減,并且將線程化的解釋器改為一次性解釋字節(jié)碼的單線程解釋器簡化程序,成功地生成了在機頂盒上可以運行簡單的Java程序的虛擬機。

          c語言相關文章:c語言教程


          c++相關文章:c++教程


          塵埃粒子計數(shù)器相關文章:塵埃粒子計數(shù)器原理
          數(shù)字濾波器相關文章:數(shù)字濾波器原理


          關鍵詞: Java CDC

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();