Chinaunix首页 | 论坛 | 博客
  • 博客访问: 919055
  • 博文数量: 96
  • 博客积分: 10071
  • 博客等级: 上将
  • 技术积分: 1118
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-20 17:54
文章分类

全部博文(96)

文章存档

2011年(3)

2010年(3)

2009年(29)

2008年(54)

2007年(7)

分类: LINUX

2007-09-24 08:45:41

一直没有好好分析一个bios的启动过程,这次我分析一些mini44b0开发板的一个小型的bios的启动过程,应该和其他的bios的启动过程非常类似。
先说以下系统定义:
;存储器空间
;GCS6 64M 16bit(8MB) DRAM/SDRAM(0xc000000-0xc7fffff)
;APP    RAM=0xc000000~0xc7effff
;44BMON RAM=0xc7f0000-0xc7fffff
;STACK     =0xc7ffa00
 
 
1.       ads设定robase为:0x0c7c0000
2.       启动地址:
 
    AREA    Init,CODE,READONLY
 
    ENTRY
ResetEntry
b ResetHandler                            ;for debug
/*
关于b指令我一直认为是绝对跳转,想着link会把地址从0xc7c0000开始,那样的话,跳转不是一下跳转到那里了吗?仔细看spec发现对b指令的介绍是:
target_address:为目标跳转地址。是相对于PC的偏移值。但是有个疑问:
编译后为:
[0xea000006]   b        ResetHandler
[0xe59ff148]   ldr      pc,0x0c7c0154 ; = #0x0c000004
[0xe59ff148]   ldr      pc,0x0c7c0158 ; = #0x0c000008
[0xe59ff148]   ldr      pc,0x0c7c015c ; = #0x0c00000c
[0xe59ff148]   ldr      pc,0x0c7c0160 ; = #0x0c000010
[0xeafffffe]   b        0xc7c0014  ; (ResetEntry + 0x14)
[0xe59ff144]   ldr      pc,0x0c7c0164 ; = #0x0c000018
[0xe59ff144]   ldr      pc,0x0c7c0168 ; = #0x0c00001c
ResetHandler :[0xe59f0144]   ldr      r0,0x0c7c016c ; = #0x01d30000
 
[0xea000006] 怎么会跳转到 ResetHandler呢。
*/
    ldr   pc, =0x0c000004                 ;handlerUndef  当发生中断的时候,直接跳转到SDRAM的开头位置。
    ldr   pc, =0x0c000008                 ;SWI interrupt handler
    ldr   pc, =0x0c00000c                 ;handlerPAbort
    ldr   pc, =0x0c000010                 ;handlerDAbort
    b .                                             ;handlerReserved
    ldr   pc, =0x0c000018
ldr   pc, =0x0c00001c
ResetHandler
    ldr       r0,=WTCON      ;禁止看门狗
    ldr       r1,=0x0       
    str       r1,[r0]
 
    ldr       r0,=INTMSK
    ldr       r1,=0x07ffffff  ;禁止所有中断
    str       r1,[r0]
 
     ;以下三段设置时钟控制寄存器
    ldr          r0,=LOCKTIME
    ldr          r1,=0xfff
    str          r1,[r0]
 
       ldr          r0,=PLLCON                ;锁相环倍频设定
       ldr          r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV)         ;设定系统主时钟频率
       str          r1,[r0]
 
    ldr       r0,=CLKCON      
    ldr       r1,=0x7ff8          ;所有功能单元块时钟使能
    str       r1,[r0]
     
       ;****************************************************
       ;change BDMACON reset value for BDMA                *
       ;****************************************************
    ldr     r0,=BDIDES0     
    ldr     r1,=0x40000000   ;BDIDESn reset value should be 0x40000000     
    str     r1,[r0]
 
    ldr     r0,=BDIDES1    
    ldr     r1,=0x40000000   ;BDIDESn reset value should be 0x40000000     
    str     r1,[r0]
 
    ;****************************************************
    ;设定存储器控制寄存器                                              *   
    ;****************************************************
       adr   r0, ResetHandler     //adr是一个伪指令,产生一个相对于PC的位置。
       ldr   r1, =ResetHandler    //r1被赋值为编译后的地址。
       sub  r0, r1, r0               //如果编译后的地址和真正执行的地址一样,说明设定的链接地址也是为0,而我们的设定的为0xc7c0000.  r0就是偏移地址。
       ldr   r1, =SMRDATA      //把SMRDATA的编译地址赋值给r1
       sub  r0, r1, r0            //r0=r1-r0   是真正的地址,与编译地址无关。
       ldmia   r0, {r1-r13}      //下面的程序是把SMRDATA的内容赋值给0x1c80000开始的寄存器。SMRDATA里面主要存的是mem设定的东西。
       ldr   r0, =0x01c80000                  ;BWSCON Address
       stmia   r0, {r1-r13}   
     
    ;****************************************************
    ;修正内存大小                                                          *
    ;****************************************************
           mov r0, #0
           ldr   r1, =0x0c000000
           ldr   r2, =0x0c000200
           str   r0, [r1]
           mov r0, #-1
           str   r0, [r2]
           ldr   r0, [r1]
           cmp r0, #0
     
       ldrne       r0, =0x01c8001c
       ldrne       r1, =((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN8))
       strne      r1, [r0]
       strne    r1, [r0, #4]
 
    ;****************************************************
    ;初始化堆栈                                                              *
    ;****************************************************
    ldr       sp, =SVCStack             ;复位后位SVC模式
    bl        InitStacks
 
    ;****************************************************
    ;拷贝并粘贴 RW data/zero initialized data               *
    ;****************************************************
       adr          r0, ResetEntry
//测试执行地址是否和编译地址相同,如果相同,就直接初始化ram,开始进入main
//如果不是的话,就要把程序先从flash copy到sdram
       ldr          r1,   BaseOfROM
       cmp        r0,   r1
       ldreq       r0, TopOfROM
       beq         InitRamData
     
       ;****************************************************
       ;计算拷贝程序在flash中的实际位置                                 *
       ;****************************************************
    ;先把copyProc copy到sdram
    ;r1代表编译的地址头
       ldr          r2,   =CopyProcBeg     ;
       sub         r1, r2, r1   ;r1
       add         r0, r0, r1
       ldr          r3,   =CopyProcEnd
     
       ;****************************************************
       ;将拷贝程序复制到ram中                                                    *
       ;****************************************************
0   
       ldmia       r0!, {r4-r7}
       stmia       r2!, {r4-r7}
       cmp        r2, r3
       bcc         %B0     
     
       ;********************************************************
       ;开始用ram中的拷贝程序复本将所有剩下的代码复制到ram中   *
       ;********************************************************
       ldr          r3, TopOfROM           
       ldr          pc, =CopyProcBeg
     
       ;********************************************************
       ;本段将代码由实际烧入的地址拷贝到ro-base所指定的位置 *
       ;只拷贝CopyProcEnd以后的代码                                                *
       ;********************************************************
CopyProcBeg ;这段代码的作用是把R0地址的块copy到R2开始地址的块,copy的数量为R3-R2
0   
       ldmia       r0!, {r4-r11}   ;R4=[R0],R5=[R0+1],R6=...
       stmia       r2!, {r4-r11}   ;[R2]=R4 [R2+1] = R5,...
       cmp        r2, r3
       bcc         %B0     
CopyProcEnd
     
       sub         r1, r2, r3 ;R1 = R2-R3
       sub         r0, r0, r1 ;R0 = R0-R1 
     
InitRamData 
       ldr          r2, BaseOfBSS
       ldr          r3, BaseOfZero    
0
       cmp        r2, r3
       ldrcc       r1, [r0], #4
       strcc       r1, [r2], #4
       bcc         %B0     
 
       mov        r0,   #0
       ldr          r3,   EndOfBSS
1   
       cmp        r2,   r3
       strcc       r0, [r2], #4
       bcc         %B1                   
                                      
    [ :LNOT:THUMBCODE
       BL          Main           ;从汇编进入C语言代码空间,不要使用main()
       B     .                                       
    ]
 
    [ THUMBCODE                ;for start-up code for Thumb mode
       orr     lr,pc,#1
       bx      lr
       CODE16
       bl      Main     ;从汇编进入C语言代码空间,不要使用main()
       b       .
       CODE32
    ]
  
       LTORG
 
;***********************************************
       IMPORT |Image$$RO$$Base|       ; ROM code start 
       IMPORT |Image$$RO$$Limit|      ; RAM data starts after ROM program
       IMPORT |Image$$RW$$Base|      ; Pre-initialised variables
       IMPORT |Image$$ZI$$Base| ; uninitialised variables
       IMPORT |Image$$ZI$$Limit|       ; End of variable RAM space
 
 
BaseOfROM   DCD       |Image$$RO$$Base|      ;RO区域的起始地址
TopOfROM    DCD       |Image$$RO$$Limit|    
BaseOfBSS     DCD       |Image$$RW$$Base|
BaseOfZero    DCD       |Image$$ZI$$Base|
EndOfBSS      DCD       |Image$$ZI$$Limit|
 
       EXPORT GetBaseOfROM
       EXPORT GetEndOfROM
       EXPORT GetBaseOfBSS
       EXPORT GetBaseOfZero
       EXPORT GetEndOfBSS
     
GetBaseOfROM
       ldr          r0, BaseOfROM
       mov        pc, lr     
GetEndOfROM
       ldr          r0, TopOfROM
       mov        pc,   lr
GetBaseOfBSS
       ldr          r0,   BaseOfBSS
       mov        pc,   lr
GetBaseOfZero
       ldr          r0,   BaseOfZero
       mov        pc,   lr
GetEndOfBSS
       ldr          r0,   EndOfBSS
       mov        pc,   lr
 
;****************************************************
;*    The function for initializing stack                       *
;****************************************************
InitStacks
       ;Do not use DRAM,such as stmfd,ldmfd......
       ;SVCstack is initialized before
       ;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
 
    mrs     r0,cpsr
    bic       r0,r0,#MODEMASK
    orr       r1,r0,#UNDEFMODE|NOINT
    msr     cpsr_cxsf,r1                 ;UndefMode
    ldr       sp,=UndefStack
     
    orr       r1,r0,#ABORTMODE|NOINT
    msr     cpsr_cxsf,r1            ;AbortMode
    ldr       sp,=AbortStack
 
    orr       r1,r0,#IRQMODE|NOINT
    msr     cpsr_cxsf,r1            ;IRQMode
    ldr       sp,=IRQStack
     
    orr       r1,r0,#FIQMODE|NOINT
    msr     cpsr_cxsf,r1            ;FIQMode
    ldr       sp,=FIQStack
 
    bic       r0,r0,#MODEMASK|NOINT
    orr       r1,r0,#SVCMODE
    msr     cpsr_cxsf,r1            ;SVCMode
    ldr       sp,=SVCStack
 
       ;USER mode is not initialized.
    mov     pc,lr ;The LR register may be not valid for the mode changes.
  
 
    LTORG
 
SMRDATA DATA
;*****************************************************************
; Memory configuration has to be optimized for best performance  *
; The following parameter is not optimized.                      *
;*****************************************************************
 
;*** memory access cycle parameter strategy ***
; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock
; 2) The memory settings,here, are made the safe parameters even at 66Mhz.
; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.
; 4) DRAM refresh rate is for 40Mhz.
 
;bank0    16bit BOOT ROM SST39VF160/SST39VF320
;bank1    8bit Nand Flash K9F2808U0A/K9F5608U0A
;bank2    16bit USB1.1 PDIUSBD12
;bank3    RTL8019
;bank4    No Uesed
;bank5    No Uesed
;bank6    16bit SDRAM
;bank7    16bit SDRAM
    [ BUSWIDTH=16
;             DCD 0x11111111    ;Bank0=OM[1:0], Bank0~Bank7=16bit
              DCD 0x11111001   ;Bank0=OM[1:0]  16bit BootRomSST39VF160/SST39VF320) :0x0
;             |||||||-     Bank1=8bit Nand Flash
;             |||||---    Bank2=8bit PDIUSBD12
;             ||||----   Bank3=16bit RTL8019
;             |||-----   Bank4~5=16bit No Uesd
;             -------- Bank6~7=16bit SDRAM
    | ;BUSWIDTH=32
       DCD 0x22222220  ;Bank0=OM[1:0], Bank1~Bank7=32bit
    ]
       DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))       ;GCS0
       DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))       ;GCS1
       DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))       ;GCS2
       DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))       ;GCS3
       DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))       ;GCS4
       DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))       ;GCS5
       [ BDRAMTYPE="DRAM"
           DCD ((B6_MT<<15)+(B6_Trcd<<4)+(B6_Tcas<<3)+(B6_Tcp<<2)+(B6_CAN))    ;GCS6 check the MT value in parameter.a
           DCD ((B7_MT<<15)+(B7_Trcd<<4)+(B7_Tcas<<3)+(B7_Tcp<<2)+(B7_CAN))    ;GCS7
       | ;"SDRAM"
              DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))    ;GCS6
              DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))    ;GCS7
       ]
       DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)       ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019
       DCD 0x10                    ;SCLK power down mode, BANKSIZE 32M/32M
       DCD 0x20                    ;MRSR6 CL=2clk
       DCD 0x20                    ;MRSR7
 
       ALIGN
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;RW BEGIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       AREA RamData, DATA, READWRITE
 
       ^      (0x0c7ffb00)
                          
UserStack             #     256  ;c7ffb00
SVCStack             #     256  ;c7ffc00
UndefStack           #     256  ;c7ffd00
AbortStack            #     256  ;c7ffe00
IRQStack              #     256  ;c7fff00
FIQStack              #     0     ;c800000
 
              END
阅读(2161) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-01-04 10:39:35

请问这段代码有什么用: ;**************************************************** ;修正内存大小 * ;**************************************************** mov r0, #0 ldr r1, =0x0c000000 ldr r2, =0x0c000200 str r0, [r1] mov r0, #-1 str r0, [r2] ldr r0, [r1] cmp r0, #0 ldrne r0, =0x01c8001c ldrne r1, =((B6_MT<<15)+