打印
[牛人杂谈]

NUC970(ARM9)裸机启动文件

[复制链接]
1877|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsan|  楼主 | 2021-6-5 20:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
裸机启动,初始化堆栈,用户堆,以及关闭中断等操作


        ;/***************************************************************************
    ; *                                                                         *
    ; * Copyright (c) 2020 NUC970裸机启动文件.             *
    ; *                                                                         *
    ; ***************************************************************************/
    ;


;为用户堆预留空间
Heap_Size               EQU     (512*1024)                                        ;堆大小
                                        AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base               
Heap_Mem                SPACE   Heap_Size
__heap_limit


       
;用户模式堆栈大小位所有堆栈预留空间
USR_Stack_Size                EQU                1024                                                                ;用户模式堆栈大小
OTH_Stack_Size                EQU                256                                                                        ;其他模式堆栈大小                       
                                        AREA    STACK, NOINIT, READWRITE, ALIGN=3
UND_Stack_Mem       SPACE   OTH_Stack_Size
Abort_Stack_Mem     SPACE   OTH_Stack_Size
FIQ_Stack_Mem       SPACE   OTH_Stack_Size
IRQ_Stack_Mem       SPACE   OTH_Stack_Size
SVC_Stack_Mem       SPACE   OTH_Stack_Size
USR_Stack_Mem       SPACE   USR_Stack_Size        
__initial_sp       

        PRESERVE8
    AREA NUC_INIT, CODE, READONLY

;--------------------------------------------
; Mode bits and interrupt flag (I&F) defines
;--------------------------------------------
USR_MODE    EQU     0x10
FIQ_MODE    EQU     0x11
IRQ_MODE    EQU     0x12
SVC_MODE    EQU     0x13
ABT_MODE    EQU     0x17
UDF_MODE    EQU     0x1B
SYS_MODE    EQU     0x1F

I_BIT       EQU     0x80
F_BIT       EQU     0x40
       


    ENTRY
    EXPORT  Reset_Go

        EXPORT  Vector_Table
Vector_Table
        B       Reset_Go    ; Modified to be relative jumb for external boot
        LDR     PC, Undefined_Addr
        LDR     PC, SWI_Addr
        LDR     PC, Prefetch_Addr
        LDR     PC, Abort_Addr
        DCD     0x0
        LDR     PC, IRQ_Addr
        LDR     PC, FIQ_Addr


Reset_Addr      DCD     Reset_Go
Undefined_Addr  DCD     Undefined_Handler
SWI_Addr        DCD     SWI_Handler1
Prefetch_Addr   DCD     Prefetch_Handler
Abort_Addr      DCD     Abort_Handler
                DCD     0
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler


        ; ************************
        ; Exception Handlers
        ; ************************

Reset_Go

        ;关闭中断
        MRS R0,         CPSR                       ;读取CPSR的值
        ORR R0,         R0,         #0x80        ;将IRQ中断禁止位I置1,即屏蔽IRQ中断
        MSR CPSR_c, R0                                ;设置CPSR的值


        ; Reset SCTLR Settings
        MRC     p15, 0, R0, c1, c0, 0     ; Read CP15 System Control register
        BIC     R0,  R0, #(0x1 << 12)     ; Clear I bit 12 to disable I Cache        当数据cache与指令cache是分开的,此处关闭指令cache
        BIC     R0,  R0, #(0x1 << 13)     ; Clear V bit 13 选择低端异常中断向量 0x0~0x1c
        BIC     R0,  R0, #(0x1 <<  2)     ; Clear C bit  2 to disable D Cache        关闭数据cache
        BIC     R0,  R0, #0x2             ; Clear A bit  1 to disable strict alignment 关闭地址对齐检查
        BIC     R0,  R0, #(0x1 << 11)     ; Clear Z bit 11 to disable branch prediction 关闭跳转分支预测
        BIC     R0,  R0, #0x1             ; Clear M bit  0 to disable MMU 关闭MMU
        MCR     p15, 0, R0, c1, c0, 0     ; Write value back to CP15 System Control register

    ;--------------------------------
    ; Initial Stack Pointer register
    ;--------------------------------
    ;INIT_STACK
        MSR    CPSR_c, #UDF_MODE :OR: I_BIT :OR: F_BIT
        LDR    SP, =(UND_Stack_Mem+OTH_Stack_Size)

        MSR    CPSR_c, #ABT_MODE :OR: I_BIT :OR: F_BIT
        LDR    SP, =(Abort_Stack_Mem+OTH_Stack_Size)

        MSR    CPSR_c, #IRQ_MODE :OR: I_BIT :OR: F_BIT
        LDR    SP, =(IRQ_Stack_Mem+OTH_Stack_Size)

        MSR    CPSR_c, #FIQ_MODE :OR: I_BIT :OR: F_BIT
        LDR    SP, =(FIQ_Stack_Mem+OTH_Stack_Size)

        MSR    CPSR_c, #SVC_MODE :OR: I_BIT :OR: F_BIT
        LDR    SP, =(SVC_Stack_Mem+OTH_Stack_Size)

        MSR    CPSR_c, #SYS_MODE :OR: I_BIT :OR: F_BIT
        LDR    SP, =(USR_Stack_Mem+USR_Stack_Size)

        ;初始化中断向量表位置
    ;LDR R0, =Vector_Table;
    ;MCR     p15, 0, R0, c12, c0, 0;//设置VBAR

        ;调用SystemInit()初始化系统底层,比如cache
        IMPORT SystemInit
        LDR    R0, =SystemInit     ;  初始化底层,比如cache等
    BLX    R0
       

        ;开启系统总中断=>在进入系统前请不要开启中断
;        MRS R0,                CPSR                       ;读取CPSR的值
;    BIC R0,                R0,                #0x80         ;将IRQ中断禁止位I清零,即允许IRQ中断
;    MSR CPSR_c,        R0                            ;设置CPSR的值

        IMPORT  __main
        ;-----------------------------
        ;   enter the C code
        ;-----------------------------
        B   __main

               
        ;其它中断处理
Undefined_Handler
        B       Undefined_Handler
SWI_Handler1
        B       SWI_Handler1
Prefetch_Handler
        B       Prefetch_Handler
Abort_Handler
        B       Abort_Handler
               
IRQ_Handler                ;系统中断服务程序
                IMPORT SystemIrqHandler
        PUSH    {LR}                         ; Save return address+4
        PUSH    {R0-R3, R12}                 ; Push caller save registers

        MRS     R0, SPSR                     ; Save SPRS to allow interrupt reentry
        PUSH    {R0}

        PUSH    {LR}                         ; Save Supervisor LR
        LDR     R2, =SystemIrqHandler
        BLX      R2                          ; 执行用户中断处理程序
        POP     {LR}

        POP     {R0}
        MSR     SPSR_CXSF, R0

        POP     {R0-R3, R12}
        POP     {LR}
        SUBS    PC, LR, #4
               
FIQ_Handler
        B       FIQ_Handler




                ;用户堆初始化,如果不初始化为出现异常
                EXPORT  __user_setup_stackheap
__user_setup_stackheap

                 LDR     R0, =  Heap_Mem                                                        ;r0 中的堆基址
                 LDR     R1, = (USR_Stack_Mem + USR_Stack_Size)                ;r1 中的堆栈基址,即堆栈区中的最高地址
                 LDR     R2, = (Heap_Mem +  Heap_Size)                                ;r2 中的堆限制
                 LDR     R3, = UND_Stack_Mem                                                ;r3 中的堆栈限制,即堆栈区中的最低地址。
                 BX      LR

                 ALIGN



    END




SystemInit()为用户cache aic中断等初始化操作,不用时可以屏蔽掉


使用特权

评论回复
沙发
match007| | 2021-7-20 13:36 | 只看该作者
这是要干啥?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

3426

帖子

1

粉丝