新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM啟動代碼研究

        ARM啟動代碼研究

        作者: 時間:2016-11-20 來源:網絡 收藏
        1.PRESERVE8:
        Reguire8和Preserve8
        C和匯編有8位對齊的要求,這兩個偽指令可以滿足此要求,存在REQUIRE8<——> PRESERVE8的對應關系,但不是說有一個REQUIRE8就要有一個 PRESERVE8,如果是一個c文件和一個匯編文件的調用,也就涉及一個PRESERVE8或者是一個REQUIRE8.
        另外,REQUIRE8和PRESERVE8并不完成8 byte 對齊的操作,對齊由ALIGN完成。
        將ADS的代碼移植到KEIL MDK上需要做的修改:
        當用戶擁有ADS遺留工程的所有源代碼時,使用MDK重新編譯鏈接全部代碼是最好的解決方法,MDK中的新版本編譯工具會重新生成滿足堆棧8BYTE對齊要求的目標文件,避免由于堆棧不對齊引起的鏈接錯誤.
        從ADS到KEIL很重要的一個修改的地方就是這里的8BYTE對齊,想要編譯通過,在startup.s里面我們必須加入PRESERVE8指令,使得寄存器8BYTE對齊.
        代碼:
        CODE32
        PRESERVE8 ;這個在KEIL里面是必須的,要求8BYTE對齊.在ADS的啟動代碼中就沒有.
        AREA vectors,CODE,READONLY
        2: ARM的處理器可工作于多種模式,下面設置個模式的一些參數.
        Mode_USR EQU 0x10 用戶模式
        Mode_FIQ EQU 0x11 快中斷模式
        Mode_IRQ EQU 0x12 中斷模式
        Mode_SVC EQU 0x13 管理模式
        Mode_ABT EQU 0x17 中止模式
        Mode_UND EQU 0x1B 未定義模式
        Mode_SYS EQU 0x1F 系統模式
        參數的由來:這里各個模式的參數是由寄存器CPSR的模式位設置M[4:0]得來的,比如這里的用戶模式,CPSR的M[4:0]設置為10000就是0x10,同理其他.詳見<嵌入式系統基礎教程>>P47頁,CPSR設置很關鍵!
        3:
        I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
        F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
        也和CPSR寄存器的設置有關,這里兩位是禁止/開啟快速中斷和一般中斷的設置.
        4: 各模式下定義的堆棧地址.
        UND_Stack_Size EQU 0x00000000
        SVC_Stack_Size EQU 0x00000100
        ABT_Stack_Size EQU 0x00000000
        FIQ_Stack_Size EQU 0x00000000
        IRQ_Stack_Size EQU 0x00000100
        USR_Stack_Size EQU 0x00000200
        設置堆棧大小
        Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size +
        FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)
        AREA STACK, NOINIT, READWRITE, ALIGN=3
        Stack_Mem SPACE Stack_Size
        Stack_Top EQU Stack_Mem + Stack_Size
        堆棧大小的設置,各公司寫的啟動代碼有所不同,但是不影響大局,可以借鑒一些你認為比較簡單的啟動代碼,然后寫自己的堆棧地址和大小設置程序.
        5:堆的設置
        Heap_Size EQU 0x00000000
        AREA HEAP, NOINIT, READWRITE, ALIGN=3
        Heap_Mem SPACE Heap_Size
        AREA Init,CODE,READONLY,ALIGN=3 //指定后面的指令為8位對齊(2的3次方)
        align n
        它的含義就是使得下面的代碼按一定規則對齊,.align n 指令的對齊值有兩種方案,n 或 2^n ,各種平臺最初的匯編器一般都不是gas,采取方案1或2的都很多,gas的目標是取代原來的匯編器,必然要保持和原來匯編器的兼容,因此在gas中如何解釋 .align指令會顯得有些混亂,原因在于保持兼容。arm-linux是按照2^n的方案對齊的. ARM的.align 5就是2的5次方(32位)對齊,也就是4字節(32位)對齊.
        6: AREA RESET, CODE, READONLY
        ARM
        下面的是ARM的代碼,不是THUMB.
        7: 中斷向量表
        Reset
        LDR PC, ResetAddr
        LDR PC, UndefinedAddr
        LDR PC, SWI_Addr
        LDR PC, PrefetchAddr
        LDR PC, DataAbortAddr
        DCD 0xb9205f80
        LDR PC, [PC, #-0xff0]
        LDR PC, FIQ_Addr

        ResetAddr DCD ResetInit
        UndefinedAddr DCD Undefined
        SWI_Addr DCD SoftwareInterrupt
        PrefetchAddr DCD PrefetchAbort
        DataAbortAddr DCD DataAbort
        Nouse DCD 0
        IRQ_Addr DCD 0
        FIQ_Addr DCD FIQ_Handler

        ;未定義指令
        Undefined
        B Undefined
        ;軟中斷
        SoftwareInterrupt
        B SoftwareInterrupt
        ;取指令中止
        PrefetchAbort
        B PrefetchAbort
        ;取數據中止
        DataAbort
        B DataAbort
        ;快速中斷
        FIQ_Handler
        STMFD SP!, {R0-R3, LR}
        BL FIQ_Exception
        LDMFD SP!, {R0-R3, LR}
        SUBS PC, LR, #4
        8: InitStack
        MOV R0, LR
        ;Build the SVC stack
        ;設置管理模式堆棧
        MSR CPSR_c, #0xd3
        LDR SP, StackSvc
        ;Build the IRQ stack
        ;設置中斷模式堆棧
        MSR CPSR_c, #0xd2
        LDR SP, StackIrq
        ;Build the FIQ stack
        ;設置快速中斷模式堆棧
        MSR CPSR_c, #0xd1
        LDR SP, StackFiq
        ;Build the DATAABORT stack
        ;設置中止模式堆棧
        MSR CPSR_c, #0xd7
        LDR SP, StackAbt
        ;Build the UDF stack
        ;設置未定義模式堆棧
        MSR CPSR_c, #0xdb
        LDR SP, StackUnd
        ;Build the SYS stack
        ;設置系統模式堆棧
        MSR CPSR_c, #0x5f ;#0xdf
        LDR SP, =StackUsr
        MOV PC, R0

        9: BL InitStack ;初始化堆棧 Initialize the stack
        BL TargetResetIni;目標板基本初始化 ;跳轉到c語言入口 Jump to the entry point of C program
        B __main

        周立功啟動代碼:
        ;

        ;define the stack size
        ;定義堆棧的大小
        SVC_STACK_LEGTH EQU 0
        FIQ_STACK_LEGTH EQU 0
        IRQ_STACK_LEGTH EQU 256
        ABT_STACK_LEGTH EQU 0
        UND_STACK_LEGTH EQU 0

        NoInt EQU 0x80

        ;定義處理器模式,用戶/管理/系統/中斷
        USR32Mode EQU 0x10
        SVC32Mode EQU 0x13
        SYS32Mode EQU 0x1f
        IRQ32Mode EQU 0x12
        FIQ32Mode EQU 0x11

        PINSEL2 EQU 0xE002C014//定義PINSEL2地址,這個地址的值一般用戶不需要改變,和芯片的加密有關
        //更改后有可能使得JTAG調試失效,進入芯片加密狀態.
        BCFG0 EQU 0xFFE00000
        BCFG1 EQU 0xFFE00004
        BCFG2 EQU 0xFFE00008
        BCFG3 EQU 0xFFE0000C//定義存儲器組配置寄存器

        BCFG_16DEF EQU 0x10000400 ;// 16Bit Bus
        BCFG_CS3 EQU (BCFG_16DEF | (0x01<<00) | (0x07<<05) | (0x07<<11)) ;// 分別是IDCY/WST1/WST2對應讀寫速率等
        ;//從第0位開始對其寫入0001,
        ;//從第5位開始寫入0111
        ;//從11位開始寫入0111(0x07)/11111(0x1f)
        IMPORT __use_no_semihosting_swi

        ;The imported labels
        ;引入的外部標號在這聲明
        IMPORT FIQ_Exception ;Fast interrupt exceptions handler 快速中斷異常處理程序
        IMPORT __main ;The entry point to the main function C語言主程序入口
        IMPORT TargetResetInit ;initialize the target board 目標板基本初始化

        ;The emported labels
        ;給外部使用的標號在這聲明
        EXPORT bottom_of_heap
        EXPORT StackUsr

        EXPORT Reset
        EXPORT __user_initial_stackheap

        CODE32

        AREA vectors,CODE,READONLY
        ENTRY

        ;interrupt vectors
        ;中斷向量表
        Reset
        LDR PC, ResetAddr
        LDR PC, UndefinedAddr
        LDR PC, SWI_Addr
        LDR PC, PrefetchAddr
        LDR PC, DataAbortAddr
        DCD 0xb9205f80
        LDR PC, [PC, #-0xff0]
        LDR PC, FIQ_Addr

        ResetAddr DCD ResetInit
        UndefinedAddr DCD Undefined
        SWI_Addr DCD SoftwareInterrupt
        PrefetchAddr DCD PrefetchAbort
        DataAbortAddr DCD DataAbort
        Nouse DCD 0
        IRQ_Addr DCD 0
        FIQ_Addr DCD FIQ_Handler

        ;未定義指令
        Undefined
        B Undefined

        ;軟中斷
        SoftwareInterrupt
        B SoftwareInterrupt

        ;取指令中止
        PrefetchAbort
        B PrefetchAbort

        ;取數據中止
        DataAbort
        B DataAbort

        ;快速中斷
        FIQ_Handler
        STMFD SP!, {R0-R3, LR}
        BL FIQ_Exception
        LDMFD SP!, {R0-R3, LR}
        SUBS PC, LR, #4

        ;
        InitStack
        MOV R0, LR
        ;Build the SVC stack
        ;設置管理模式堆棧
        MSR CPSR_c, #0xd3
        LDR SP, StackSvc
        ;Build the IRQ stack
        ;設置中斷模式堆棧
        MSR CPSR_c, #0xd2
        LDR SP, StackIrq
        ;Build the FIQ stack
        ;設置快速中斷模式堆棧
        MSR CPSR_c, #0xd1
        LDR SP, StackFiq
        ;Build the DATAABORT stack
        ;設置中止模式堆棧
        MSR CPSR_c, #0xd7
        LDR SP, StackAbt
        ;Build the UDF stack
        ;設置未定義模式堆棧
        MSR CPSR_c, #0xdb
        LDR SP, StackUnd
        ;Build the SYS stack
        ;設置系統模式堆棧
        MSR CPSR_c, #0x5f ;#0xdf
        LDR SP, =StackUsr

        MOV PC, R0

        ;
        ResetInit
        ;初始化外部總線控制器,根據目標板決定配置
        ;
        ; LDR R0, =PINSEL2
        ; IF :DEF: EN_CRP
        ; LDR R1, =0x0f814910
        ; ELSE
        ; LDR R1, =0x0f814914
        ; ENDIF
        ; STR R1, [R0]

        LDR R0, =BCFG0
        LDR R1, =0x1000ffef ;0x00001046
        STR R1, [R0]

        LDR R0, =BCFG1
        LDR R1, =BCFG_CS3 ;0x1000ffef ;0x1000ffef;;
        STR R1, [R0]

        LDR R0, =BCFG2
        LDR R1, =0x2000ffef
        STR R1, [R0]

        ; LDR R0, =BCFG3
        ; LDR R1, =0x00000CA0 ;0x2000ffef
        ; STR R1, [R0]

        BL InitStack ;初始化堆棧 Initialize the stack
        BL TargetResetInit ;目標板基本初始化 Initialize the target board
        ;跳轉到c語言入口 Jump to the entry point of C program

        B __main

        ;
        __user_initial_stackheap
        LDR r0,=bottom_of_heap
        ; LDR r1,=StackUsr
        MOV pc,lr

        StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
        StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
        StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
        StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
        StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4

        ;
        IF :DEF: EN_CRP
        IF . >= 0x1fc
        INFO 1," The data at 0x000001fc must be 0x87654321. Please delete some source before this line."
        ENDIF
        CrpData
        WHILE . < 0x1fc
        NOP
        WEND
        CrpData1
        DCD 0x87654321 ;
        ENDIF

        ;
        AREA MyStacks, DATA, NOINIT, ALIGN=2
        SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;Stack spaces for Administration Mode 管理模式堆棧空間
        IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;Stack spaces for Interrupt ReQuest Mode 中斷模式堆棧空間
        FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;Stack spaces for Fast Interrupt reQuest Mode 快速中斷模式堆棧空間
        AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;Stack spaces for Suspend Mode 中止義模式堆棧空間
        UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;Stack spaces for Undefined Mode 未定義模式堆棧

        AREA Heap, DATA, NOINIT
        bottom_of_heap SPACE 1

        AREA Stacks, DATA, NOINIT
        StackUsr

        END
        ;


        關鍵詞: ARM啟動代

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 青河县| 武汉市| 永泰县| 黎平县| 屏山县| 谷城县| 丰都县| 绥宁县| 峨边| 湄潭县| 台中市| 吴江市| 濮阳县| 合山市| 辉南县| 齐齐哈尔市| 乐都县| 沧州市| 秦皇岛市| 敖汉旗| 长治县| 志丹县| 屏山县| 九江市| 通辽市| 雅江县| 栾川县| 齐齐哈尔市| 锡林浩特市| 巴楚县| 天门市| 张家川| 来宾市| 黔东| 阳谷县| 江达县| 沙田区| 牙克石市| 博白县| 梁平县| 洪雅县|