打印
[ZLG-ARM]

给周工的bootloader瘦下身(Slim the BootLoader of ZLG)

[复制链接]
1555|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xusnwise|  楼主 | 2007-7-13 09:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Slim the BootLoader of ZLG:
Startup.s

;/*****************************************************************************
;定义堆栈大小
;初始化系统,跳转到C程序接口
;*****************************************************************************/
SVC_STACK_LENGTH    EQU        0
FIQ_STACK_LENGTH    EQU        0
IRQ_STACK_LENGTH    EQU        256
ABT_STACK_LENGTH    EQU        0
UND_STACK_LENGTH    EQU        0

NOIRQ    EQU        0x80
NOFIQ    EQU        0x40
USRMD    EQU        0x10
FIQMD    EQU        0x11
IRQMD    EQU        0x12
SVCMD    EQU        0x13
ABTMD    EQU        0x17
NDEFMD    EQU        0x1b
OSMD    EQU        0x1f


;引入要调用的全局变量或函数
 IMPORT        __use_no_semihosting_swi
 IMPORT        __main
 IMPORT        TargetINI
 IMPORT        FIQFunction

 EXPORT        __user_initial_stackheap
 EXPORT        UsrStack
 EXPORT        Reset
 EXPORT        bottom_of_heap

 CODE32
 AREA    vectors, CODE, READONLY
 ENTRY


;中断向量表
Reset
   B    RST_Handler
   B    Undef_Handler
   B    SWI_Handler
   B    PreABT_Handler
   B    DABT_Handler
   DCD    0xb9295f80
   LDR    PC,    [PC,#-0xff0]     ;PC=0x20,PC-0xff0=0xfffff030
   B    FIQ_Handler            ;既是IRQ中断的寄存器地址,加载PC
        
        
        
;RSTadr        DCD        RST_Handler
;Undefadr    DCD                 Undef_Handler
;SWIadr        DCD        SWI_Handler
;PreABTadr    DCD        PreABT_Handler
;DABTadr    DCD                 DABT_Handler
;FIQadr        DCD        FIQ_Handler
        
        
RST_Handler
            
   BL    StackINI            ;初始化系统堆栈分配
   BL  TargetINI            ;跳转C语言目标板初始化函数
   B    __main            ;跳转到C语言main函数
            
Undef_Handler
   B    Undef_Handler            
            
            
SWI_Handler
   CMP        R0,    #4        ;判断软件中断的类型号,实现跳转
   LDRLO    PC,    [PC, R0, LSL#2]
   MOVS    PC,    LR
        
        
SWIFunction
   DCD        IRQDisable        ;软件中断跳转向量表
   DCD        IRQEnable
   DCD        FIQDisable     
   DCD         FIQEnable
        
        
IRQDisable    
   MRS        R0,        SPSR    
   ORR        R0,    R0,    #NOIRQ
   MSR        SPSR_c,    R0 
   MOVS        PC,        LR
        
IRQEnable    
   MRS        R0,        SPSR    
   BIC        R0,    R0,    #NOIRQ
   MSR        SPSR_c,    R0
   MOVS        PC,        LR
        
FIQDisable
   MRS        R0,        SPSR
   ORR        R0,    R0, #NOFIQ
   MSR        SPSR_c,    R0
   MOVS        PC,        LR
        
FIQEnable
   MRS        R0,        SPSR
   BIC        R0,    R0, #NOFIQ
   MSR        SPSR_c,    R0
   MOVS        PC,        LR
        
        
PreABT_Handler
   B        PreABT_Handler
        
DABT_Handler
   B        DABT_Handler
        
;快速中断跳转处理         
FIQ_Handler
   STMFD    SP!,    {R0-R3,LR}
   BL        FIQFunction
   LDMFD    SP!,    {R0-R3,LR}
   SUBS    PC,    LR, #4                            
        
        
StackINI
        ;设置快速中断堆栈
;芯片复位后是管理模式,管理模式可以进行处理器模式切换
;但不适合运行程序,必须在用户/系统模式下运行程序,
;保存堆栈初始化子程序,因为此时的LR是管理模式下的LR
   
   MOV        R0,        LR                        
           
   MSR        CPSR_c,    #0xd1        
   LDR        SP,        Stack_fiq
        ;设置IRQ中断堆栈
   MSR        CPSR_c,    #0xd2        
   LDR        SP,        Stack_irq
   MSR        CPSR_c,    #0xd3        
   LDR        SP,        Stack_svc
   MSR        CPSR_c,    #0xd7        
   LDR        SP,        Stack_abt
   MSR        CPSR_c,    #0xdb        
   LDR        SP,        Stack_und
   MSR        CPSR_c,    #0xdf
   LDR        SP,        =UsrStack
        
        ;返回
   MOV        PC,        R0    ;加载返回地址        

;设置堆栈起始地址和长度
;R0--HEAP BASE    R1--STACK BASE
;R2--HEAP LENGTH    R3--STACK LENGTH    
__user_initial_stackheap
   LDR        R0,        =bottom_of_heap
   MOV        PC,        LR            
        
        
                

;定义堆栈空间大小
Stack_svc    DCD        SvcSpace + (SVC_STACK_LENGTH-1)*4
Stack_fiq    DCD        FiqSpace + (FIQ_STACK_LENGTH-1)*4                
Stack_irq    DCD        IrqSpace + (IRQ_STACK_LENGTH-1)*4                    
Stack_abt    DCD        AbtSpace + (ABT_STACK_LENGTH-1)*4            
Stack_und    DCD        UndSpace + (UND_STACK_LENGTH-1)*4            
                    
            
            
   AREA    mystack, DATA, NOINIT, ALIGN=2        ;分配堆栈空间
            
SvcSpace    SPACE        SVC_STACK_LENGTH*4
FiqSpace    SPACE        FIQ_STACK_LENGTH*4
IrqSpace    SPACE        IRQ_STACK_LENGTH*4
AbtSpace    SPACE        ABT_STACK_LENGTH*4
UndSpace    SPACE        UND_STACK_LENGTH*4
            

;定义堆的RAM空间
   AREA    HEAP,    DATA,    NOINIT
bottom_of_heap    SPACE    1

        
;定义栈的RAM空间            
   AREA    STACKS,    DATA,    NOINIT
UsrStack

 END            
            
            
            
            
                    
                    

相关帖子

沙发
xusnwise|  楼主 | 2007-7-13 09:56 | 只看该作者

target.c

#include    "config.h"
#define        BF_HROM        0
#define        BF_LROM        1
#define        BF_IRAM        2
#define        BF_XFLASH    3

extern        Reset(void);
/***************************************************************
IRQ函数体,编译器关键字__irq声明此函数为IRQ函数

***************************************************************/
void __irq    IRQ_Func(void)
{
    while(1);

}
/****************************************************************
FIQ函数体,在STARTUP.S汇编文件中引用,执行完后返回

****************************************************************/
void    FIQFunction(void)
{
    while(1);
    
}
/****************************************************************
系统初始化函数,在STARTUP.S文件中调用,用来实现系统的初始配置,
如:REMAP的方式,系统的时钟频率,存储器加速等
*****************************************************************/
void    TargetINI(void)
{

//中断向量表重新影射 
    #ifdef __DEBUG_IRAM
    
    MEMMAP = BF_IRAM;
    #endif
        
    #ifdef __DEBUG_REL
    
         MEMMAP = BF_LROM;
    #endif
    
    #ifdef __RELEASE
    
        MEMMAP = BF_LROM;
    #endif
    
//设置系统时钟工作在4*Fosc
    PLLCON = 0x1;            //使能PLL
//Pclk的时钟为系统时钟的1/4
    VPBDIV = 0;
    PLLCFG = 0x23;
    PLLFEED = 0xAA;
    PLLFEED = 0x55;
    while((PLLSTAT & (1<<10))==0); //判断PLL是否锁定
    PLLCFG = 3;
    PLLFEED = 0xAA;
    PLLFEED = 0x55;
    
//设置寄存器加速模块
    MAMCR =  0;
    MAMTIM = 3;            //MAM的取指周期为3*Fclk
    MAMCR = 2;            //完全使能MAM
    
//禁止中断
     VICIntEnClr = 0xffffffff;
     VICVectAddr = 0;    //IRQ中断地址寄存器
     VICIntSelect = 0;    //分配为IRQ中断
     
}
     

/*******************************************************************
重定义与semihosting相关的函数,因为这些函数是以PC操作系统为背景的
如果ARM目标板没有操作系统和文件系统等,需要重新定义这些函数。用
armlink -verbose命令来查看有哪些函数是用到但没有重定义的。只需要
重新定义verbose info 中那些,reference 是__use_no_semihosting_swi
那些函数
********************************************************************/
#include    "rt_sys.h"
#include    "stdio.h"


#pragma        import(__use_no_semihosting_swi)
    
void    _sys_exit(int    returncode)
        {
            returncode = returncode;
        }
    
        
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

使用特权

评论回复
板凳
xusnwise|  楼主 | 2007-7-13 09:57 | 只看该作者

config.h

/*******************************************************************
系统配置文件,一些宏定义声明

*******************************************************************/
#include    "LPC2294.h"

__swi(0x00)    void             SwiHandler1(int    Handle);

#define        IRQDisable()    SwiHandler1(0x0)
#define        IRQEnable()    SwiHandler1(0x1)
#define        FIQDisable()    SwiHandler1(0x2)
#define        FIQEnable()    SwiHandler1(0x3)


typedef        unsigned char    UINT8;
typedef        char        INT8;
typedef        unsigned short    UINT16;
typedef        short         INT16;
typedef        unsigned int    UINT32;
typedef        int        INT32;
typedef        float        F32;
typedef        double        F64;

使用特权

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

本版积分规则

40

主题

294

帖子

0

粉丝