• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 在ARMSYS上進行uClinux內核移植的總結

    在ARMSYS上進行uClinux內核移植的總結

    作者: 時間:2012-04-18 來源:網(wǎng)絡 收藏

    1。簡述

    本文引用地址:http://www.czjhyjcfj.com/article/149223.htm

    針對“如何在以S3C44B0X為核心的開發(fā)板上建立”的一個,其內容包括對Bootloader的功能分析和2。4。24發(fā)行版基礎上針對S3C44B0X開發(fā)板修改的重點內容的逐一列舉。

    2。Bootloader

    2。1Bootloader概述

    BootLoader就是在操作系統(tǒng)運行之前運行的一段程序。通過這段程序,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調用操作系統(tǒng)內核準備好正確的環(huán)境。因此,正確建立的前提條件是具備一個與uClinux配套、易于使用的Bootloader。

    開發(fā)板提供了這樣一個uClinux專用的Bootloader,該Bootloader程序燒錄在系統(tǒng)的地址0x0處,每次上電即運行,能夠正確完成硬件系統(tǒng)的初始化和uClinux的引導。

    理論上,uClinux引導時并非一定需要一個獨立于內核的Bootloader。然而,將Bootloader與內核分開設計能夠使軟件架構更加清晰,也有助于靈活地支持多種引導方式,實現(xiàn)一些有用的輔助功能。

    提供的Bootloader的主要任務可以概括如下:

    1.硬件初始化;

    2。從主機下載新的內核映像和文件系統(tǒng)映像;

    3。燒寫NorFlash和Nandflash;

    4。加載uClinux內核映像并啟動運行;

    5。提供串行超級終端上的人機操作界面。

    2。2存儲空間分布

    Bootloader采用默認的存儲空間分布地址來加載uClinux內核、文件系統(tǒng),并按照正確引導uClinux的運行。在ARMSYS的Bootloader中,默認的存儲空間分布如下表:

    內容起始地址存儲介質

    Bootloader程序空間0x00000000Flash

    壓縮內核映像0x00010000Flash

    ROM文件系統(tǒng)映像0x000e0000Flash

    內核運行地址0x0c008000SDRAM

    壓縮內核解壓地址0x0c100000SDRAM

    文件系統(tǒng)加載0x0c700000SDRAM

    這個存儲空間的分配方式也不是固定不變的,可以通過修改Bootloader中的相關代碼來改變。

    2。3Bootloader的工作

    完整的Bootloader引導流程可描述如下:

    硬件初始化階段一

    ◎硬件初始化;

    ◎復制二級中斷異常矢量表;

    ◎初始化各種處理器模式;

    ◎復制RO和RW,清零ZI(跳轉到C代碼入口函數(shù))。

    硬件初始化階段二

    ◎初始化本階段使用到的硬件設備;

    ◎建立人機界面;

    ◎實現(xiàn)映像文件的下載和燒錄工具;

    ◎實現(xiàn)映像文件的加載和運行工具。

    下面對上述各步驟逐一說明,并對與uClinux相關的內容詳細加以說明。

    2。3。1硬件初始化

    板子上電或復位后,程序從位于地址0x0的ResetExceptionVector處開始執(zhí)行,因此需要在這里放置Bootloader的第一條指令:bResetHandler,跳轉到標號為ResetHandler處第一階段的硬件初始化,主要內容為:關WatchdogTimer,關中斷,初始化PLL和時鐘,初始化存儲器控制器。比較重要的是PLL的輸出頻率要計算正確,ARMSYS中把它設置為64MHz;這實際上就是處理器的工作主頻,這個時間參數(shù)在第二階段計算SDRAM的刷新計數(shù)值和UART的波特率等參數(shù)時還要用到。

    2。3。2建立二級異常中斷矢量表

    異常中斷矢量表(ExceptionVectorTable)是Bootloader與uClinux內核發(fā)生聯(lián)系關鍵的地方之一。即使uClinux內核已經得到處理器的控制權運行,一旦發(fā)生中斷,處理器還是會自動跳轉到從0x0地址開始的第一級異常中斷矢量表中的某個表項(依據(jù)于中斷類型)處讀取指令運行。

    在編寫B(tài)ootloader時,地址0x0處的一級異常中斷矢量表只需簡單地包含向二級異常中斷矢量表的跳轉指令就可以。這樣,就能夠正確地將發(fā)生的事件交給uClinux的中斷處理程序來處理。對于uClinux內核,它在RAM空間中基地址為0xc000000處建立了自己的二級異常中斷矢量表,因此,Bootloader的第一級異常中斷矢量表如下所示:

    bResetHandler;ResetHandler

    ldrpc,=0x0c000004;UndefinedInstructionHandler

    ldrpc,=0x0c000008;SoftwareInterruptHandler

    ldrpc,=0x0c00000c;PrefetchAbortHandler

    ldrpc,=0x0c000010;DataAbortHandler

    b。

    ldrpc,=0x0c000018;IRQHandler

    ldrpc,=0x0c00001c;FIQHandler

    LTORG

    如果在Bootloader執(zhí)行的全過程中都不必響應中斷,那么上面的設置已能滿足要求。但在我們的ARMSYS上提供了USB下載器,需要用到中斷,那么Bootloader必須在同樣的地址(0xc000000)處配置自己的二級異常中斷矢量表,以便同uClinux兼容。這張表事先存放在FlashMemory里,引導過程中由Bootloader將其復制到RAM地址0x0C000000,存放矢量表:

    ;IRQ==theprogramputthisphraseto0xc000000

    ExceptionHanlderBegin

    b。

    ldrpc,MyHandleUndef;HandlerUndef

    ldrpc,MyHandleSWI;HandlerSWI

    ldrpc,MyHandlePabort;HandlerPabort

    ldrpc,MyHandleDabort;HandlerDAbort

    b。;HandlerReserved

    ldrpc,MyHandleIRQ;HandlerIRQ

    ldrpc,MyHandleFIQ;HandlerFIQ

    MyHandleUndefDCDHandleUndef;reserveaword(32bit)

    MyHandleSWIDCDHandleSWI

    MyHandlePabortDCDHandlePabort

    MyHandleDabortDCDHandleDabort

    MyHandleIRQDCDHandleIRQ

    MyHandleFIQDCDHandleFIQ

    ExceptionHanlderEnd

    建立二級矢量表:

    ;****************************************************

    ;*SetupIRQhandler*

    ;****************************************************

    ldrr0,=(_IRQ_BASEADDRESS+0x100)

    ldrr2,=_IRQ_BASEADDRESS

    addr3,r0,#0x100

    0

    CMPr0,r3

    STRCCr2,[r0],#4;cc:Carryclear;saveR2toR0address,R0=R0+4。

    BCC%B0

    ldrr1,=_IRQ_BASEADDRESS

    ldrr0,=ExceptionHanlderBegin;ifthereisn't'subspc,lr,#4'at0x18,0x1c

    ldrr3,=ExceptionHanlderEnd

    0

    CMPr0,r3;putthevectortableat_IRQ_BASEADDRESS(0xc000000)

    LDRCCr2,[r0],#4

    STRCCr2,[r1],#4

    BCC%B0

    ldrr1,=DIsrIRQ;puttheIRQjudgeprogramat_IRQ_BASEADDRESS+0x80(0xc000080)

    ldrr0,=IsrIRQ;ifthereisn't'subspc,lr,#4'at0x18,0x1c

    ldrr3,=IsrIRQEnd

    0

    CMPr0,r3

    LDRCCr2,[r0],#4

    STRCCr2,[r1],#4

    BCC%B0

    ldrr1,=MyHandleIRQ;MyHandleIRQpointtoDIsrIRQ

    ldrr0,=ExceptionHanlderBegin

    ldrr4,=_IRQ_BASEADDRESS;

    subr0,r1,r0

    addr0,r0,r4

    ldrr1,=DIsrIRQ

    strr1,[r0]

    定義Handlexxx:

    ^(_IRQ_BASEADDRESS)

    HandleReset#4

    HandleUndef#4

    HandleSWI#4

    HandlePabort#4

    HandleDabort#4

    HandleReserved#4

    HandleIRQ#4

    HandleFIQ#4

    ^(_IRQ_BASEADDRESS+0x80)

    DIsrIRQ#4

    ;IntVectorTable

    ^(_IRQ_BASEADDRESS+0x100)

    HandleADC#4

    HandleRTC#4

    HandleUTXD1#4

    HandleUTXD0#4

    HandleSIO#4

    HandleIIC#4

    HandleURXD1#4

    HandleURXD0#4

    HandleTIMER5#4

    HandleTIMER4#4

    HandleTIMER3#4

    HandleTIMER2#4

    HandleTIMER1#4

    HandleTIMER0#4

    HandleUERR01#4

    HandleWDT#4

    HandleBDMA1#4

    HandleBDMA0#4

    HandleZDMA1#4

    HandleZDMA0#4

    HandleTICK#4

    HandleEINT4567#4

    HandleEINT3#4

    HandleEINT2#4

    HandleEINT1#4

    HandleEINT0#4

    將異常中斷矢量重構到SDRAM,這樣的好處就是可以在其它的功能程序內對中斷處理程序的地址任意賦值。為此,我們在44b。h文件中定義:

    /*ISR*/

    #definepISR_RESET(*(unsigned*)(_IRQ_BASEADDRESS+0x0))

    #definepISR_UNDEF(*(unsigned*)(_IRQ_BASEADDRESS+0x4))

    #definepISR_SWI(*(unsigned*)(_IRQ_BASEADDRESS+0x8))

    #definepISR_PABORT(*(unsigned*)(_IRQ_BASEADDRESS+0xc))

    #definepISR_DABORT(*(unsigned*)(_IRQ_BASEADDRESS+0x10))

    #definepISR_RESERVED(*(unsigned*)(_IRQ_BASEADDRESS+0x14))

    #definepISR_IRQ(*(unsigned*)(_IRQ_BASEADDRESS+0x18))

    #definepISR_FIQ(*(unsigned*)(_IRQ_BASEADDRESS+0x1c))

    #definepISR_ADC(*(unsigned*)(_IRQ_BASEADDRESS+0x100))//0x20))

    #definepISR_RTC(*(unsigned*)(_IRQ_BASEADDRESS+0x104))//0x24))

    #definepISR_UTXD1(*(unsigned*)(_IRQ_BASEADDRESS+0x108))//0x28))

    #definepISR_UTXD0(*(unsigned*)(_IRQ_BASEADDRESS+0x10c))//0x2c))

    #definepISR_SIO(*(unsigned*)(_IRQ_BASEADDRESS+0x110))//0x30))

    #definepISR_IIC(*(unsigned*)(_IRQ_BASEADDRESS+0x114))//0x34))

    #definepISR_URXD1(*(unsigned*)(_IRQ_BASEADDRESS+0x118))//0x38))

    #definepISR_URXD0(*(unsigned*)(_IRQ_BASEADDRESS+0x11c))//0x3c))

    #definepISR_TIMER5(*(unsigned*)(_IRQ_BASEADDRESS+0x120))//0x40))

    #definepISR_TIMER4(*(unsigned*)(_IRQ_BASEADDRESS+0x124))//0x44))

    #definepISR_TIMER3(*(unsigned*)(_IRQ_BASEADDRESS+0x128))//0x48))

    #definepISR_TIMER2(*(unsigned*)(_IRQ_BASEADDRESS+0x12c))//0x4c))

    #definepISR_TIMER1(*(unsigned*)(_IRQ_BASEADDRESS+0x130))//0x50))

    #definepISR_TIMER0(*(unsigned*)(_IRQ_BASEADDRESS+0x134))//0x54))

    #definepISR_UERR01(*(unsigned*)(_IRQ_BASEADDRESS+0x138))//0x58))

    #definepISR_WDT(*(unsigned*)(_IRQ_BASEADDRESS+0x13c))//0x5c))

    #definepISR_BDMA1(*(unsigned*)(_IRQ_BASEADDRESS+0x140))//0x60))

    #definepISR_BDMA0(*(unsigned*)(_IRQ_BASEADDRESS+0x144))//0x64))

    #definepISR_ZDMA1(*(unsigned*)(_IRQ_BASEADDRESS+0x148))//0x68))

    #definepISR_ZDMA0(*(unsigned*)(_IRQ_BASEADDRESS+0x14c))//0x6c))

    #definepISR_TICK(*(unsigned*)(_IRQ_BASEADDRESS+0x150))//0x70))

    #definepISR_EINT4567(*(unsigned*)(_IRQ_BASEADDRESS+0x154))//0x74))

    #definepISR_EINT3(*(unsigned*)(_IRQ_BASEADDRESS+0x158))//0x78))

    #definepISR_EINT2(*(unsigned*)(_IRQ_BASEADDRESS+0x15c))//0x7c))

    #definepISR_EINT1(*(unsigned*)(_IRQ_BASEADDRESS+0x160))//0x80))

    #definepISR_EINT0(*(unsigned*)(_IRQ_BASEADDRESS+0x164))//0x84))

    例如,我們要使用到Exint4567中斷,定義好中斷處理程序Meint4567Isr()后,僅需要一條語句:

    pISR_EINT4567=(int)MEint4567Isr;

    就能使中斷發(fā)生后正確跳轉到我們編寫的處理程序上。

    矢量控制相關文章:矢量控制原理


    評論


    相關推薦

    技術專區(qū)

    關閉
    主站蜘蛛池模板: 温宿县| 博野县| 怀来县| 富裕县| 五原县| 新晃| 友谊县| 西安市| 南充市| 壶关县| 桓仁| 七台河市| 玉田县| 彩票| 平江县| 长汀县| 榆树市| 湾仔区| 卓资县| 安吉县| 台东市| 邹城市| 富宁县| 贺兰县| 察雅县| 日照市| 墨脱县| 徐水县| 石阡县| 洪湖市| 黄山市| 娱乐| 徐汇区| 榆中县| 安徽省| 罗田县| 玛纳斯县| 辛集市| 开封市| 新昌县| 宝山区|