热门关键字:  ubuntu  分区  函数  Fedora  linux系统进程

bootloader分析

来源: 作者: 时间:2008-06-22 Tag: 点击:

    @ Check if this is a wake-up from sleep
Procedure to Wake-up from Power_OFF mode
(电源从POWER-OFF MODE中wake-up需做的事,在这里主要讨论如何设置SDRAM那部分,第2,3,4、5
1. The internal reset signal will be asserted if one of the wake-up sources is issued. This reset duration is
determined by the internal 16-bit counter logic and the reset assertion time is calculated as tRST = (65535 /
XTAL_frequency).
2. Check GSTATUS2[2] in order to know whether or not the power-up is caused by the wake-up from
Power_OFF mode.
3. Release the SDRAM signal protection by setting MISCCR[19:17]=000b.
4. Configure the SDRAM memory controller.
5. Wait until the SDRAM self-refresh is released. Mostly SDRAM needs the refresh cycle of all SDRAM row.
6. The information in GSTATUS3,4 can be used for user’s own purpose because the value in GSTATUS3,4 has
been preserved during Power_OFF mode.
7. – For EINT[3:0], check the SRCPND register.
– For EINT[15:4], check the EINTPEND instead of SRCPND (SRCPND will not be set although some bits of
EINTPEND are set.).
– For alarm wake-up, check the RTC time because the RTC bit of SRCPND isn’t set at the alarm wake-up.
– If there was the nBATT_FLT assertion during POWER_OFF mode, the corresponding bit of SRCPND has
been set.
    ldr    r1, PMST_ADDR
    ldr    r0, [r1]
    tst    r0, #(PMST_SMR)
    bne    WakeupStart
2. Check GSTATUS2[1] in order to know whether or not the power-up is caused by the wake-up from
Power_OFF mode.

翻译出来就很明白这段代码在做什么。
【GENERAL STATUS REGISTER (GSTATUSn)
  通用状态寄存器】
GSTATUS2 0x560000B4 —— Reset status
OFFRST [1] Power_OFF reset. The reset after the wakeup from Power_OFF mode.
The setting is cleared by writing "1" to this bit.

如果GSTATUS2[1]=1则表示SDRAM处于wake-up状态,不等则跳转到WakeupStart
head.S定义如下:
PMST_ADDR:
.long 0x560000B4

"vivi/include/S3c2410.h"中定义如下

#define PMST_WDR (1
#endif
#ifdef CONFIG_S3C2410_SMDK
    @ All LED on
    mov    r1, #GPIO_CTL_BASE
    add    r1, r1, #oGPIO_F
    ldr    r2,=0x55aa
    str    r2, [r1, #oGPIO_CON]
    mov    r2, #0xff
    str    r2, [r1, #oGPIO_UP]
    mov    r2, #0x00
    str    r2, [r1, #oGPIO_DAT]
配置GPIO口点亮所有开发板上面的LED,具体输出IO口根据具体的开发板配置
#endif
#if 0@这段代码没执行,代码所做的事是使处理器工作在管理模式,指令arm执行
    @ SVC
    mrs    r0, cpsr
    bic    r0, r0, #0xdf
    orr    r1, r0, #0xd3
    msr    cpsr_all, r1
#endif
    @ set GPIO for UART(这段代码可选)
    mov    r1, #GPIO_CTL_BASE
GPIO_CTL_BASE=0x56000000
    add    r1, r1, #oGPIO_H
oGPIO_H=0x70
这样r1=0x56000070
GPHCON 0x56000070 R/W Configure the pins of port H
    ldr    r2, gpio_con_uart   
gpio_con_uart=vGPHCON=0x0016faaa
    str    r2, [r1, #oGPIO_CON]
oGPIO_CON=0x0 ,将r2的值载入到0x56000070
    ldr    r2, gpio_up_uart
gpio_up_uart=vGPHUP=0x000007ff
    str    r2, [r1, #oGPIO_UP]
   
oGPIO_UP=0x8,将0x7ff的值载入0x56000078
作用是使上拉电阻不起作用
    bl    InitUART
#ifdef CONFIG_DEBUG_LL
    @ Print current Program Counter
    ldr    r1, SerBase
    mov    r0, #'\r'
    bl    PrintChar
    mov    r0, #'\n'
    bl    PrintChar
    mov    r0, #'@'
    bl    PrintChar
    mov    r0, pc
    bl    PrintHexWord
#endif
#ifdef CONFIG_BOOTUP_MEMTEST
    @ simple memory test to find some DRAM flaults.
    bl    memtest
#endif
#ifdef CONFIG_S3C2410_NAND_BOOT
    bl    copy_myself
    @ jump to ram
    ldr    r1, =on_the_ram
    add    pc, r1, #0
    nop
    nop
1:    b    1b        @ infinite loop
on_the_ram:
#endif
#ifdef CONFIG_DEBUG_LL
    ldr    r1, SerBase
    ldr    r0, STR_STACK
    bl    PrintWord
    ldr    r0, DW_STACK_START
    bl    PrintHexWord
#endif
    @ get read to call C functions
    ldr    sp, DW_STACK_START    @ setup stack pointer
    mov    fp, #0            @ no previous frame, so fp=0
    mov    a2, #0            @ set argv to NULL
    bl    main            @ call main
    mov    pc, #FLASH_BASE        @ otherwise, reboot
@
@ End VIVI head
@
/*
* subroutines
*/
@
@ Wake-up codes
@
#ifdef CONFIG_PM
WakeupStart:
    @ Clear sleep reset bit
    ldr    r0, PMST_ADDR
    mov    r1, #PMST_SMR
    str    r1, [r0]
这段代码详见上面 Check if this is a wake-up from sleep
    @ Release the SDRAM signal protections
    ldr    r0, PMCTL1_ADDR
    ldr    r1, [r0]
    bic    r1, r1, #(SCLKE | SCLK1 | SCLK0)
    str    r1, [r0]
3. Release the SDRAM signal protection by setting MISCCR[19:17]=000b.在下面
“Set the SDRAM singal protections”
有详细说明
    @ Go...
    ldr    r0, PMSR0_ADDR    @ read a return address
    ldr    r1, [r0]
    mov    pc, r1
“head.S”有如下定义
PMSR0_ADDR:
.long 0x560000B8

GSTATUS3 0x560000B8 Infrom register 0x0
INFORM [31:0] Inform register. This register is cleared by nRESET or watchdog timer.
Otherwise, preserve data value.
GSTATUS3寄存器中保存了return address?没看到????
当程序转移时,转移指令执行的最终结果就是要改变PC的值,此PC值就是转去的地址,以此实现转移
    nop
    nop
1:    b    1b        @ infinite loop
设置这个死循环的作用是,假如上面的指令没实现跳转,程序将在这永远执行,不会顺序执行到下面。
SleepRamProc:
    @ SDRAM is in the self-refresh mode */
    ldr    r0, REFR_ADDR
在head.S后面有这样的定义
REFR_ADDR:
.long 0x48000024
REFRESH CONTROL REGISTER(SDRAM刷新控制寄存器)
SDRAM refresh control register
9. Let SDRAM enter the self-refresh mode by setting the REFRESH[22]=1b.
由上面这句话可知,只需设置REFRESH[22]=1b

[ vivi/include/S3c2410.h]

#define SELF_REFRESH  (1
    ldr    r1, [r0]
    orr    r1, r1, #SELF_REFRESH
使用orr语句赋值的原因是说只改变REFRESH的[22]这一位
    str    r1, [r0]

10. Wait until SDRAM self-refresh is effective.
11. Set MISCCR[19:17]=111b to make SDRAM signals(SCLK0,SCLK1 and SCKE) protected during Power_OFF
mode
12. Set the Power_OFF mode bit in the CLKCON register.

    @ wait until SDRAM into self-refresh
    mov    r1, #16
1:    subs    r1, r1, #1   
    bne    1b
10. Wait until SDRAM self-refresh is effective.

设置延时程序使SDRAM的自我刷新有效。
解释下bne    1b
意思是上面减法r1的值不为0则跳转,跳转到程序向前标号最近为1的地方执行,若指令为bne 1f则为程序向后寻找跳转
    @ Set the SDRAM singal protections
11. Set MISCCR[19:17]=111b to make SDRAM signals(SCLK0,SCLK1 and SCKE) protected during Power_OFF
mode

找出MISCCR寄存器(混杂控制寄存器):
MISCCR 0x56000080 Miscellaneous control register
Set MISCCR[19:17]=111b
nEN_SCKE [19]  0: SCKE = Normal  1:SCKE = L level
Used to protect SDRAM during the Power_OFF moe.
nEN_SCLK1 [18] 0: SCLK1= SCLK    1:SCLK1= L level
Used to protect SDRAM during the Power_OFF moe.
nEN_SCLK0 [17] 0: SCLK0= SCLK    1:SCLK0= L level
Used to protect SDRAM during the Power_OFF moe.
下面语句中
head.S中有定义如下:
PMCTL1_ADDR:
.long 0x56000080

[ vivi/include/S3c2410.h]中有如下定义:
#define SCLKE  (1
    ldr    r0, PMCTL1_ADDR
    ldr    r1, [r0]
    orr    r1, r1, #(SCLKE | SCLK1 | SCLK0)
    str    r1, [r0]
    /* Sleep... Now */
12. Set the Power_OFF mode bit in the CLKCON register.
CLOCK CONTROL REGISTER (CLKCON)
CLKCON 0x4C00000C Clock generator control register
POWER-OFF [3]
Control Power Off mode of S3C2410.
0 = Disable, 1 = Transition to Power_OFF mode
0

head.S中有定义如下:
PMCTL0_ADDR:
.long 0x4c00000c

[ vivi/include/S3c2410.h]中有如下定义:
#define SLEEP_ON (1
    ldr    r0, PMCTL0_ADDR
    ldr    r1, [r0]
    orr    r1, r1, #SLEEP_ON
    str    r1, [r0]   
1:    b    1b
上面这句代码,执行起来是一个无限循环,放在这的意思,实在迷惑。
做个大胆猜测,S3C2410进入POWER-OFF MODE,就在这跳转,直到
WAKE-UP的到来?
#ifdef CONFIG_TEST
hmi:
    ldr    r0, PMCTL0_ADDR
PMCTL0_ADDR=0x4C00000C
CLKCON 0x4C00000C R/W Clock generator control register 0x7FFF0
使用默认值
代码的具体功能?然道是测试所有设备工作状态
    ldr    r1, =0x7fff0
    str    r1, [r0]
   
    @ All LED on
    mov    r1, #GPIO_CTL_BASE
    add    r1, r1, #oGPIO_F
    ldr    r2,=0x55aa
    str    r2, [r1, #oGPIO_CON]
    mov    r2, #0xff
    str    r2, [r1, #oGPIO_UP]
    mov    r2, #0xe0
    str    r2, [r1, #oGPIO_DAT]
1:    b    1b
#endif
#endif
ENTRY(memsetup)
    @ initialise the static memory
SDRAM初始化
    @ set memory control registers
    mov    r1, #MEM_CTL_BASE
"vivi/include/S3c2410.h"
#define MEM_CTL_BASE  0x48000000
    adrl    r2, mem_cfg_val
    add    r3, r1, #52
1:    ldr    r4, [r2], #4
    str    r4, [r1], #4
    cmp    r1, r3
    bne    1b
在SDRAM设置过程中,通过一个比较循环完成13个寄存器的配置,其写入的值如下:
"head.S"有如下定义:
@ Memory configuration values
.align 4
mem_cfg_val:
.long vBWSCON
.long vBANKCON0
.long vBANKCON1
.long vBANKCON2
.long vBANKCON3
.long vBANKCON4
.long vBANKCON5
.long vBANKCON6
.long vBANKCON7
.long vREFRESH
.long vBANKSIZE
.long vMRSRB6
.long vMRSRB7

"vivi/include/Smdk2410.h"
/* initial values for DRAM */
#define vBWSCON    0x22111110
#define vBANKCON0  0x00000700
#define vBANKCON1  0x00000700
#define vBANKCON2  0x00000700
#define vBANKCON3  0x00000700
#define vBANKCON4  0x00000700
#define vBANKCON5  0x00000700
#define vBANKCON6  0x00018005
#define vBANKCON7  0x00018005
#define vREFRESH  0x008e0459
#define vBANKSIZE  0xb2
#define vMRSRB6   0x30
#define vMRSRB7   0x30




先看S3C2410的第五部分有如下一段话:
The S3C2410X has the following features:
— Little/Big endian (selectable by a software)
— Address space: 128Mbytes per bank (total 1GB/8 banks)
— Programmable access size (8/16/32-bit) for all banks except bank0 (16/32-bit)
— Total 8 memory banks
Six memory banks for ROM, SRAM, etc.
Remaining two memory banks for ROM, SRAM, SDRAM, etc .
— Seven fixed memory bank start address
— One flexible memory bank start address and programmable bank size
从这段文字我们可以知道,S3C2410支持1GB的内存寻址,一共8个BANK,8*128MB=1GB,而且只有在bank6和bank7上才能接SRAM。
从开发板datasheet可知:
在板上用了两块HY57V561620BT-H SDRAM构成动态存储器
查看HY57V561620BT-H的datesheet可知
HY57V561620BT-H 4Banks x 4Mbits x16=256Mbite=32MB
两片为64MB够成32bit位宽可以查看其寻址范围为:
[0x30000000-0x33ffffff]
由于Bank 6 and 7 must have the same memory size
bank7的内存空间为
[0x34000000-0x37ffffff]
下面介绍具体的寄存器配置:
在配置的13个寄存器中:有些是默认值,只是为了写程序方便才配置如此多


BWSCON   0x48000000  Bus width & wait status control register
32位,8个bank,除了bank0只使用了【2:1】其他四位配置一个bank。
主要配置每个bank的位宽,以bank6为例,其为32位所以选择10
DW6 [25:24] Determine data bus width for bank 6.
00 = 8-bit 01 = 16-bit, 10 = 32-bit 11 = reserved

顾配置其值为0x22111110


BANK CONTROL REGISTER (BANKCONN: nGCS0-nGCS5)
for bank0-5 control,使用默认值就可
BANKCON0 0x48000004 R/W Bank 0 control register 0x0700
BANKCON1 0x48000008 R/W Bank 1 control register 0x0700
BANKCON2 0x4800000C R/W Bank 2 control register 0x0700
BANKCON3 0x48000010 R/W Bank 3 control register 0x0700
BANKCON4 0x48000014 R/W Bank 4 control register 0x0700
BANKCON5 0x48000018 R/W Bank 5 control register 0x0700

BANK CONTROL REGISTER (BANKCONn: nGCS6-nGCS7)
BANKCON6 0x4800001C R/W Bank 6 control register
BANKCON7 0x48000020 R/W Bank 7 control register

[16:15] Determine the memory type for bank6 and bank7
00 = ROM or SRAM           01 = Reserved (Do not use)
10 = Reserved (Do not use) 11 = Sync. DRAM

很显然这里选择11
[14:4]采用默认值:
Trcd [3:2] RAS to CAS delay
00 = 2 clocks  01 = 3 clocks  10 = 4 clocks

查看datesheet Trcd的-H指标为至少20ns,而HCLK的时钟周期为10ns,所以选01
SCAN [1:0] Column address number
00 = 8-bit  01 = 9-bit  10= 10-bit

Column Address : CA0 ~ CA8, 选01
所以写入该寄存器的值为0x18005
REFRESH 0x48000024 R/W SDRAM refresh control register

    具体参考S3C2410的第五章REFRESH的datesheet
    ·REFEN[23]:开启自动模式,设为1
    ·TREFMD[22]:设为Auto refresh模式,设为0
    ·Trp[21:20]:看看RAS precharge Time,查看SDRAM手册,发现-H系列此参数至少为20ns,所以至少应该为2个clock。可以设为00
    ·Tsrc:也就是RAS Cycle Time,至少65ms,所以至少得6.5clock,按照可选值,应该设置为11
    ·Refresh[10:0]:
    公式refresh period = (2^11 - refresh_count +1)/Hclk,由此推导出refresh_count=2^11+1-refresh period*Hclk。带入数值,计算得出2^11+1-7.8125u*100M=1268=0x04f4与0459有点误差但无大碍
    ·其余的保留值,均设置为0
所以写入该寄存器的值为0x8e04f4

    mov    pc, lr
lr=R14,pc=R15,在执行带链接的分支指令时,lr得到PC的拷贝,当程序返回了,把lr返回给PC
#ifdef CONFIG_S3C2410_NAND_BOOT
@
@ copy_myself: copy vivi to ram
@
copy_myself:
    mov    r10, lr
把程序计数器的值保存在r10中
    @ reset NAND
因为前4KB自动引导到 S3C2410X 的内在SRAM buffer (“Steppingstone”)后 ,NAND FLASH 被自动禁用
提供S3C2410 NAND Flash的中文datesheet

文件:
S3C2410中文手册第六章.pdf
大小:
257KB
下载:
下载
    mov    r1, #NAND_CTL_BASE
"vivi/include/S3c2410.h"
/* NAND Flash Controller */
#define NAND_CTL_BASE  0x4E000000

#define oNFCONF   0x00
#define oNFCMD    0x04
#define oNFADDR   0x08
#define oNFDATA   0x0c
#define oNFSTAT   0x10
#define oNFECC    0x14

    ldr    r2, =0xf830        @ initial value
    str    r2, [r1, #oNFCONF]
0xf830 装载到0x4E000000
NFCONF 0x4E000000 R/W NAND Flash configuration
Enable/Disable [15]   1=Enable NAND Flash Controller
Initialize ECC [12]   1 : Initialize ECC
NAND Flash Memory chip enable  [11] NAND Flash Memory nFCE control
0 : NAND flash nFCE = L (active)
1 : NAND flash nFCE = H (inactive)

(After auto-boot, nFCE will be inactive.)
由TACLS=0, TWRPH0=1, TWRPH1=0
可设置位【10:8】=000,【6:4】=011,【2:0】=000
    ldr    r2, [r1, #oNFCONF]
    bic    r2, r2, #0x800      
使NFCONF【11】=0 0:NAND flash nFCE = L 使能芯片
这里有个问题,为什么不在上面直接写0,而是在配置好了才使能芯片???
  
    str    r2, [r1, #oNFCONF]
    mov    r2, #0xff        @ RESET command
    strb    r2, [r1, #oNFCMD]
0xff 装载到0x4E000004
    mov    r3, #0            @ wait
1:    add    r3, r3, #0x1
    cmp    r3, #0xa
    blt    1b
延时小程序,给NAND Flash准备时间,准备好
2:    ldr    r2, [r1, #oNFSTAT]    @ wait ready
NFSTAT 0x4E000010 R NAND Flash operation status
只读寄存器,这段代买测试NAND Flash 运行状态,若其值为0x00则说明NAND Flash准备好了
    tst    r2, #0x1
    beq    2b
    ldr    r2, [r1, #oNFCONF]
    orr    r2, r2, #0x800        @ disable chip
    str    r2, [r1, #oNFCONF]
    @ get read to call C functions (for nand_read())
    ldr    sp, DW_STACK_START    @ setup stack pointer
    mov    fp, #0            @ no previous frame, so fp=0
    @ copy vivi to RAM
    ldr    r0, =VIVI_RAM_BASE
    mov r1, #0x0
    mov    r2, #0x20000
    bl    nand_read_ll
    tst    r0, #0x0
    beq    ok_nand_read
#ifdef CONFIG_DEBUG_LL
bad_nand_read:
    ldr    r0, STR_FAIL
    ldr    r1, SerBase
    bl    PrintWord
1:    b    1b        @ infinite loop
#endif
   
ok_nand_read:
#ifdef CONFIG_DEBUG_LL
    ldr    r0, STR_OK
    ldr    r1, SerBase
    bl    PrintWord
#endif
    @ verify
    mov    r0, #0
    ldr    r1, =0x33f00000
    mov    r2, #0x400    @ 4 bytes * 1024 = 4K-bytes
go_next:
    ldr    r3, [r0], #4
    ldr    r4, [r1], #4
    teq    r3, r4
    bne    notmatch
    subs    r2, r2, #4
    beq    done_nand_read   
    bne    go_next
notmatch:
#ifdef CONFIG_DEBUG_LL
    sub    r0, r0, #4
    ldr    r1, SerBase
    bl    PrintHexWord
    ldr    r0, STR_FAIL
    ldr    r1, SerBase
    bl    PrintWord
#endif
1:    b    1b
done_nand_read:
#ifdef CONFIG_DEBUG_LL
    ldr    r0, STR_OK
    ldr    r1, SerBase
    bl    PrintWord
#endif
    mov    pc, r10
@ clear memory
@ r0: start address
@ r1: length
mem_clear:
    mov    r2, #0
    mov    r3, r2
    mov    r4, r2
    mov    r5, r2
    mov    r6, r2
    mov    r7, r2
    mov    r8, r2
    mov    r9, r2
clear_loop:
    stmia     {r2-r9}
    subs    r1, r1, #(8 * 4)
    bne    clear_loop
    mov    pc, lr
#endif @ CONFIG_S3C2410_NAND_BOOT
#ifdef CONFIG_BOOTUP_MEMTEST
@
@ Simple memory test function
@
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册