startup.s


;EN_CRP EQU 1  ; 定义是否加密芯片

         INCLUDE ../ARM/LPC23xx.INC

;定义堆栈的大小
SVC_STACK_LEGTH         EQU         0x0008
FIQ_STACK_LEGTH         EQU         0
IRQ_STACK_LEGTH         EQU         0x0100
ABT_STACK_LEGTH         EQU         0
UND_STACK_LEGTH         EQU         0


NoInt       EQU 0x80
NoFIQ       EQU 0x40

 

USR32Mode   EQU 0x10
SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f
IRQ32Mode   EQU 0x12
FIQ32Mode   EQU 0x11

STAY_IN_IAP       EQU 0x1234ABCD

;引入的外部标号在这声明
    IMPORT  __main                          ;C语言主程序入口
    IMPORT  RunFirst
    IMPORT  TargetResetInit                 ;目标板基本初始化
    IMPORT  g_stay_iap

         EXPORT __user_initial_stackheap

; Area Definition and Entry Point
;  Startup Code must be linked first at Address at which it expects to run.
    CODE32
    PRESERVE8
                AREA    RESET, CODE, READONLY
                ARM

; Exception Vectors
;  Mapped to Address 0.
;  Absolute addressing mode must be used.
;  Dummy Handlers are implemented as infinite loops which can be modified.

Vectors         LDR     PC, Reset_Addr
                LDR     PC, Undef_Addr
                LDR     PC, SWI_Addr
                LDR     PC, PAbt_Addr
                LDR     PC, DAbt_Addr
                NOP                            ; Reserved Vector
;               LDR     PC, IRQ_Addr
                LDR     PC, [PC, #-0x0120]     ; Vector from VicVectAddr
                LDR     PC, FIQ_Addr

Reset_Addr      DCD     Reset_Handler
Undef_Addr      DCD     Undef_Handler
SWI_Addr        DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                DCD     0                      ; Reserved Address
                DCD     0                      ; Reserved Address
FIQ_Addr        DCD     FIQ_Handler

Undef_Handler   B       Undef_Handler

SWI_Handler
        CMP     R0, #6
        LDRLO   PC, [PC, R0, LSL #2]
        MOVS    PC, LR

SwiFunction
        DCD     IRQDisable       ;0
        DCD     IRQEnable        ;1
        DCD     FIQDisable       ;2
        DCD     FIQEnable        ;3
        DCD     SoftReset        ;4  
        DCD     PowerJump        ;5

IRQDisable
        ;关IRQ中断
        MRS     R0, SPSR
        ORR     R0, R0, #NoInt
        MSR     SPSR_c, R0
        MOVS    PC, LR

IRQEnable
        ;开IRQ中断
        MRS   R0, SPSR
        BIC   R0, R0, #NoInt
        MSR   SPSR_c, R0
        MOVS    PC, LR

FIQDisable
        ;关FIQ中断
        MRS     R0, SPSR
        ORR     R0, R0, #NoFIQ
        MSR     SPSR_c, R0
        MOVS    PC, LR

FIQEnable
        ;开FIQ中断
        MRS   R0, SPSR
        BIC   R0, R0, #NoFIQ
        MSR   SPSR_c, R0
        MOVS    PC, LR

SoftReset
        ;软件复位
        B    Vectors

PowerJump
        ;将CPU转换到特权模式后跳转
        BX    R1

 

PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler
FIQ_Handler     B       FIQ_Handler


; Reset Handler

        EXPORT  Reset_Handler
Reset_Handler

; 判断是否留在IAP中执行, 通过R0中的值来判断
        LDR     R1, =STAY_IN_IAP
        CMP     R0, R1 
        LDR     R3, =g_stay_iap
        STREQ   R1, [R3] ; 为g_stay_iap赋值
        MOV     R1, #0
        STRNE  R1, [R3]

        BL      RunFirst
        BL      InitStack               ; Initialize the stack 初始化堆
        BL      TargetResetInit         ; Initialize the target board 初始化目标板
                                        ; Jump to the entry point of C p
        B      __main
        B      _sys_exit

;: 初始化堆栈
InitStack
        MOV     R0, LR
;设置管理模式堆栈
        MSR     CPSR_c, #0xd3
        LDR     SP, StackSvc
;设置中断模式堆栈
        MSR     CPSR_c, #0xd2
        LDR     SP, StackIrq
;设置快速中断模式堆栈
        MSR     CPSR_c, #0xd1
        LDR     SP, StackFiq
;设置中止模式堆栈
        MSR     CPSR_c, #0xd7
        LDR     SP, StackAbt
;设置未定义模式堆栈
        MSR     CPSR_c, #0xdb
        LDR     SP, StackUnd
;设置系统模式堆栈
        MSR     CPSR_c, #0xd0
        LDR     SP, =StackUsr

        BX       R0

        EXPORT _sys_exit
_sys_exit
    B       _sys_exit

;被0除
__rt_div0
    MOV     R0, #0
    BX      LR

;功能描述: 库函数初始化堆和栈,不能删除
__user_initial_stackheap
    LDR   R0, =bottom_of_heap
    LDR   R1, =StackUsr
    LDR   R2, =top_of_heap
    LDR   R3, =bottom_of_Stacks
    BX    LR

 

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

;encrypt the chip
   IF  . >= 0x1fc
        IF :DEF: EN_CRP
            INFO    1,"/nThe data at 0x000001fc must be 0x87654321./nPlease delete some source before this line."
        ELSE
            INFO    1,"/nThe data at 0x000001fc must be 0xffffffff./nPlease delete some source before this line."
        ENDIF
   ENDIF

CrpData
    WHILE . < 0x1fc
    NOP
    WEND

CrpData1
    IF :DEF: EN_CRP
    DCD     0x87654321          ;当此数为0x87654321时,用户程序被保护
    ELSE
    DCD     0xffffffff          ;当此数为0xffffffff时,用户程序不被保护
    ENDIF

;分配堆栈空间
        AREA    MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace           SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间
IrqStackSpace           SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
FiqStackSpace           SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间
AbtStackSpace           SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间
UndtStackSpace          SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈


        AREA    Heap, DATA, NOINIT
bottom_of_heap ;   SPACE   1
        AREA    HeapTop, DATA, NOINIT
top_of_heap

        AREA    StackBottom, DATA, NOINIT
bottom_of_Stacks ;    SPACE   1
        AREA    Stacks, DATA, NOINIT
StackUsr

    END

### startup.s 汇编文件的作用与用途 在嵌入式系统开发和操作系统内核开发中,`startup.s` 是一个非常关键的汇编文件,通常用于处理器上电或复位后的初始化过程。该文件主要负责设置处理器的初始状态,为后续的 C 语言代码或更高层次的程序执行做好准备。 #### 初始化处理器 在系统启动时,硬件无法直接运行高级语言编写的代码,因此需要一段用汇编语言编写的初始化代码来配置处理器的基本运行环境。`startup.s` 文件通常包含处理器复位后的第一条指令,负责初始化堆栈指针、中断向量表、内存映射等关键寄存器。这些操作是确保系统能够正常运行的前提条件[^1]。 #### 设置中断向量表 许多嵌入式平台要求在启动阶段定义中断向量表(Interrupt Vector Table),该表包含各种异常和中断的处理程序地址。`startup.s` 文件通常会定义这些向量,并将其放置在内存中的特定位置,以便处理器在发生中断时能够正确跳转到对应的处理函数[^2]。 #### 调用主函数 在完成基本的硬件初始化之后,`startup.s` 会调用 C 语言的入口函数(通常是 `main` 函数),从而将控制权从汇编代码转移到高级语言代码。为了实现这一点,该文件可能还会负责设置 BSS 段(未初始化数据段)和 DATA 段(已初始化数据段)的内存区域[^3]。 #### 异常处理 除了初始化功能之外,`startup.s` 还可能包含一些基本的异常处理程序,如复位处理、未定义指令异常、软件中断(SWI)等。这些处理程序可以提供最基本的系统响应能力,直到更完整的异常处理机制被加载和启用。 #### 示例代码结构 以下是一个典型的 `startup.s` 文件的简化结构(以 ARM 架构为例): ```armasm .section .text.Reset_Handler .weak Reset_Handler .type Reset_Handler, %function Reset_Handler: /* 设置堆栈指针 */ ldr sp, =_estack /* 调用系统初始化函数 */ bl SystemInit /* 跳转到 main 函数 */ bl main /* 死循环 */ b . .section .vectors .word _estack .word Reset_Handler .word NMI_Handler .word HardFault_Handler /* 更多中断向量 */ ``` #### 平台相关性 需要注意的是,`startup.s` 文件通常是高度平台相关的,不同架构(如 ARM、x86、RISC-V)和不同芯片厂商的实现方式可能有较大差异。因此,在使用或修改该文件时,必须参考具体平台的文档和技术手册。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值