新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > S3C2440-啟動分析

        S3C2440-啟動分析

        作者: 時間:2016-12-02 來源:網絡 收藏
        本文是我對bootloader中2440init.s文件的一些理解,詳細注釋了一下,希望對大家有所幫助,下一步我準備移植一下uboot。
        ;=========================================
        ; NAME: 2440INIT.S
        ; DESC: C start up codes
        ; Configure memory, ISR ,stacks
        ; Initialize C-variables
        ; HISTORY:
        ; 2002.02.25:kwtark: ver 0.0
        ; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
        ; 2003.03.14onGo: Modified for 2440.
        ;=========================================
        GET option.inc ;GET相當于C語言中的include,也就是包含一個源文件到當文
        GET memcfg.inc ;件中,并將被包含的文件在當前位置進行匯編。
        GET 2440addr.inc
        BIT_SELFREFRESH EQU (1<<22) ;EQU相當于C語言中的define,為(1<<2)定義的符號名稱
        re-defined constants
        USERMODE EQU 0x10 ;預定義一下各種工作模式
        FIQMODE EQU 0x11
        IRQMODE EQU 0x12
        SVCMODE EQU 0x13
        ABORTMODE EQU 0x17
        UNDEFMODE EQU 0x1b
        MODEMASK EQU 0x1f
        NOINT EQU 0xc0
        ;定義了一下堆棧的地址我只用的開發板SDRAM中堆棧的地址范圍是0x33ff4800"0x33ff7fff。
        ;The location of stacks
        UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 "
        SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 "
        UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 "
        AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 "
        IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 "
        FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 "
        ;ARM有兩種工作狀態16位的Thumb和32位的Arm,編譯器有相對應的16位和32位兩種編譯方式。16位環境使用tasm.exe編譯。[|]相當于C語言中的IF ELSE ENDIF。
        ;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
        GBLL THUMBCODE
        [ {CONFIG} = 16
        THUMBCODE SETL {TRUE} ;SETL偽操作給一個全局或局部變量賦值
        CODE32 ;CODE32告訴我們下面是32位的arm指令
        |
        THUMBCODE SETL {FALSE}
        ]
        /*******************************************************************
        下面是一個宏,用來實現子程序返回的。也就是將LR(子程序鏈接寄存器)的內容放入PC中。如果是THUMBCODE為真,那么bx lr。也就是跳轉到lr所指向的位置執行。bx可以用來進行工作狀態的切換。
        *******************************************************************/
        MACRO
        MOV_PC_LR
        [ THUMBCODE
        bx lr
        |
        mov pc,lr
        ]
        MEND
        ;與上邊的類似,只是加了一個是否相等的判斷。
        MACRO
        MOVEQ_PC_LR
        [ THUMBCODE
        bxeq lr
        |
        moveq pc,lr
        ]
        MEND
        /*******************************************************************
        這個宏用來把HandlerLabel這個地址標號和HandleLabel這個地址標號綁定在一起。注意前面比后面多了一個r。在后面可以看到這樣的指令 b HandlerUndef ;這是硬件自動產生的中斷向量表,也是第一級中斷向量表。比如產生了一個ENT0中斷,如果在矢量模式下,首先是跳轉b HandlerIRQ,然后就是這個宏,進入HandleIRQ,可是到底是那個中斷呢,在HandleIRQ這個位置,硬件會自動產生跳轉到中斷處理程序的指令,也就是說是哪個中斷源由硬件自己判斷,并將跳轉指令自動送過來。如果是非矢量模式,首先跳轉到b b HandlerIRQ,然后宏展開,跳轉到HandleIRQ的位置,HandleIRQ里存放的是IsrIRQ,IsrIRQ用于找到是哪一個中斷源,并定位它在中斷向量表中的位置。這個中斷向量表在SDRAM的0x33ffff00 " 0x33ffffff,共256個字節,一個中斷向量占4個字節,即一個字,所以這個位置可以存放64個中斷源。2440只能有60個中斷源。這個位置也是SDRAM最后的地址。我的SDRAM是64M,從0x30000000"0x34000000。
        *******************************************************************/
        MACRO
        $HandlerLabel HANDLER $HandleLabel
        $HandlerLabel
        sub sp,sp,#4 ;decrement sp(to store jump address)
        stmfd sp!,{r0} USH the work register to stack(lr does t push because it return to original address)
        ldr r0,=$HandleLabel;load the address of HandleXXX to r0
        ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
        str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
        ldmfd sp!,{r0,pc} OP the work register and pc(jump to ISR)
        MEND
        ;這些符號是ADS生成的,是根據我們填的RO,RW,ZI生成的。IMPORT偽操作是導入別的文件生命的變量
        IMPORT |Image$$RO$$Base| ; Base of ROM code
        IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
        IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
        IMPORT |Image$$ZI$$Base| ; Base and limit of area
        IMPORT |Image$$ZI$$Limit| ; to zero initialise
        IMPORT MMU_SetAsyncBusMode
        IMPORT MMU_SetFastBusMode
        IMPORT Main ; The main entry of mon program
        AREA Init,CODE,READONLY
        ENTRY
        EXPORT __ENTRY
        __ENTRY
        ;========
        ;復位
        ;========
        ResetEntry
        ;1)The code, which converts to Big-endian, should be in little endian code.
        ;2)The following little endian code will be compiled in Big-Endian mode.
        ; The code byte order should be changed as the memory bus width.
        ;3)The pseudo instruction,DCD can t be used here because the linker generates error.
        /*******************************************************************
        是否進行大小端切換。ASSERT斷言錯誤偽操作,如果表達式為假就報錯,這里如果未定義ENDIAN_CHANGE就報錯,如果ENDIAN_CHANGE為true,如果未定義ENTRY_BUS_WIDTH,就報錯。根據不同的總線寬度32,16,8進行大小段的切換。andeq r14,r7,r0,lsl #20 ,streq r0,[r0,-r10,ror #1] ,與b ChangeBigEndian的作用相同。
        *******************************************************************/
        ASSERT EF:ENDIAN_CHANGE
        [ ENDIAN_CHANGE
        ASSERT EF:ENTRY_BUS_WIDTH
        [ ENTRY_BUS_WIDTH=32
        b ChangeBigEndian ;DCD 0xea000007
        ]
        [ ENTRY_BUS_WIDTH=16
        andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
        ]
        [ ENTRY_BUS_WIDTH=8
        streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
        ]
        |
        b ResetHandler
        ;這段是復位程序,先進行大小段切換,然后進入復位異常處理程序
        ]
        ;這段時異常中斷向量表
        b HandlerUndef ;handler for Undefined mode
        b HandlerSWI ;handler for SWI interrupt
        b HandlerPabort ;handler for PAbort
        b HandlerDabort ;handler for DAbort
        b . ;reserved
        b HandlerIRQ ;handler for IRQ interrupt
        b HandlerFIQ ;handler for FIQ interrupt
        ;電源管理 EnterPWDN在后面進行了實現,主要是進入IDLE模式和SLEEP模式
        ;@0x20
        b EnterPWDN ; Must be @0x20.
        ;從小端切換到大端的實現過程
        ChangeBigEndian
        ;@0x24
        [ ENTRY_BUS_WIDTH=32
        DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
        DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian
        DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
        ]
        [ ENTRY_BUS_WIDTH=16
        DCD 0x0f10ee11
        DCD 0x0080e380
        DCD 0x0f10ee01
        ]
        [ ENTRY_BUS_WIDTH=8
        DCD 0x100f11ee
        DCD 0x800080e3
        DCD 0x100f01ee
        ]
        ;相當于NOP指令,作用是等待從小端模式向大端模式切換
        DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode.
        DCD 0xffffffff
        DCD 0xffffffff
        DCD 0xffffffff
        DCD 0xffffffff
        b ResetHandler
        ;將HandlerLabel與HandleLabel進行關聯,所謂的“加載程序”
        HandlerFIQ HANDLER HandleFIQ
        HandlerIRQ HANDLER HandleIRQ
        HandlerUndef HANDLER HandleUndef
        HandlerSWI HANDLER HandleSWI
        HandlerDabort HANDLER HandleDabort
        HandlerPabort HANDLER HandlePabort
        /*******************************************************************
        下面這段代碼用于非矢量中斷。INTOFFSET中斷偏移寄存器。中斷偏移寄存器顯示了哪個IRQ中斷模式的請求在INTPND寄存器中。該位可以通過清除SRCPND和INTPND寄存器被自動清除。 在匯編中INTOFFSET等寄存器的名字是指寄存器的地址,比如INTOFFSET是INTOFFSET這個寄存器的地址,所以ldr r9 = INTOFFSET,在C語言中,INTOFFSET是INTOFFSET這個寄存器的內容。
        *******************************************************************/

        上一頁 1 2 3 4 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 政和县| 惠来县| 翼城县| 阳东县| 田阳县| 新干县| 秦安县| 临邑县| 定日县| 林西县| 苏尼特左旗| 乐清市| 南昌市| 梅州市| 民县| 永吉县| 弋阳县| 临安市| 辛集市| 广灵县| 普兰县| 广饶县| 南陵县| 同心县| 宜都市| 建昌县| 八宿县| 朝阳县| 盈江县| 茌平县| 三原县| 江山市| 凌云县| 博乐市| 信丰县| 大渡口区| 华亭县| 延庆县| 望都县| 平遥县| 霍林郭勒市|