【SAMSUNG S3C2440A 项目开发】系列之--BootLoader - 上海嵌入式家园 贺工

【SAMSUNG S3C2440A 项目开发】系列之--BootLoader(NBOOT+EBOOT)

Author: 贺工

上海嵌入式家园-开发板商城
嵌入式家园网址:www.embedclub.com
淘宝商城网址:http://embedclub.taobao.com/


软件环境: Windows CE 5.0, VS2005, ADS1.2
硬件环境: Samsung S3C2440A, JTAG, SJF2440.exe, DNW

由于本系统采用的是Nand Flash,所以,我们必须先做好一个NBoot来引导Eboot。

一、 NBoot开发

      采用ADS1.2工具来编译生成NBoot.bin 。

我觉得关键要注意的地方就是:NBoot必须将Nand Flash中包含Eboot的Blocks拷贝到SDRAM指定地址处,这个地址也就是在boot.bib中指定的:

EBOOT    8c038000  00040000  RAMIMAGE

CONFIG
    ROMSTART=8c038000
     ROMWIDTH=32
     ROMSIZE=40000
即Eboot.nb0的运行起始地址。 这个非常关键!一定要匹配!

在NBoot中表现为:
/// Eboot
void loadboot(void)
{

    ......
    dwSector=32*2;//从block:2 page:0开始存放boot2
    dwLength=32*16;//一共16个block;block2-17;256K eboot容量;如果eboot文件大于256K,需要修改该代码

    dwRAM=0x30038000;//eboot load Start address;把NAND FLASH内容拷贝到0X30038000

    ......
    
    FMD_ReadSector(dwSector,(LPBYTE)dwRAM,NULL, 1);

    ......

    Launch(0x30038000);//跳转到eboot,启动eboot,程序不会返回
}



二、 Startup.s开发

下面例举针对平台需要修改的几个主要部分。

1、 INCLUDE s3c2440a.inc

2.  可以添加LED点灯程序:

; Defines
;---------------------------------------------------------------------------
; 4 LED light function
; The LEDs are located below AMD Flash ROM

 MACRO
 LED_ON $data
 LDR     r10, =0x56000054       
 LDR     r11, =$data
 MOV     r11, r11, lsl #4
   STR     r11, [r10]
    MEND
;---------------------------------------------------------------------------
; 4 LED light function
; The LEDs are located below AMD Flash ROM

 MACRO
 VLED_ON $data
 LDR     r10, =0xB1600054       
 LDR     r11, =$data
 MOV     r11, r11, lsl #4
   STR     r11, [r10]
    MEND
;---------------------------------------------------------------------------

3、 修改
PLLVAL      EQU     (((0xa1 << 12) + (0x3 << 4) + 0x1))      ; Hanson change

4、 在 LEAF_ENTRY      StartUp   后面,也即Startup.s第一行代码处,添加下面点灯程序来确认:NBoot程序是否已经将Eboot从Nand Flash中拷入SDRAM,并成功运行至Startup.s。

; Hanson Test LED ++ 
 ; Led_Display                     
 ldr r0,=GPFCON
 ldr r1,=0x5500
 str r1,[r0]
 ldr r0,=GPFDAT
 ldr r1,=0x10
 str r1,[r0]  
  
b       .         // 注意这个死循环很关键,这样才能看到点灯的效果。
 ; Hanson Test LED --

5、 根据具体平台修改CLKDIVN
ldr     r0, = CLKDIVN
ldr     r1, = 0x7                       ; 0x0 = 1:1:1,  0x1 = 1:1:2
                                             ; 0x2 = 1:2:2,  0x3 = 1:2:4,
                                             ; 0x4 = 1:4:4,  0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6
                                             ; Hanson change

str     r1, [r0]

6、 根据具体平台修改MPLLCON 和UPLLCON                  

参考2440Spec
MPLL Control Register 计算公式:
Mpll = (2 * m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV

UPLL Control Register 计算公式:
UPLL Control Register
Upll = (m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV

代码修改如下:

ldr     r0, = MPLLCON                   ; Configure MPLL
 ldr     r1,=((0x7f<<12)+(0x2<<4)+0x1)  ;Fin=12MHz,Fout=405MHz
;ldr     r1, = PLLVAL                  ; Hanson change
str     r1, [r0]

ldr     r0, = UPLLCON                   ; Fin=12MHz, Fout=48MHz
ldr     r1, = ((0x48 << 12) + (0x3 << 4) + 0x2)   ; Hanson change
str     r1, [r0]

7、

修改Memory Control Register

参考SDRAM寄存器:HY57V561620CT-H
(1) REFRESH CONTROL REGISTER
REFEN      1 = Enable (self or CBR/auto refresh)
TREFMD     SDRAM Refresh Mode:  0 = CBR/Auto Refresh
Trp        SDRAM RAS pre-charge Time: 01 = 3CLKs
Tsrc       SDRAM Semi Row cycle time: 10 = 6 clocks
由于SDRAM Row cycle time: Trc=Tsrc+Trp, 所以:Tsrc=Trc-Trp=9CLKs - 3CLKs = 6CLKs

Refresh Counter:  
SDRAM refresh count value. Refer to chapter 6 SDRAM refresh controller bus priority section.
由于Refresh period = (2的11次方-refresh_count+1)/HCLK, 所以:refresh_count = 2048 +1 - Refresh

period * HCLK.
在HY57V561620CTH中8192个refresh cycles时间为64ms,所以,refresh cycles即Refresh period =

64ms/8192=7.8125us.
Refresh period =7.8125us, HCLK=135Mhz, refresh_count = (2048+1-7.8125*135)=995.

代码如下:
REFEN       EQU     (0x1)               ; Refresh enable
TREFMD      EQU     (0x0)               ; CBR(CAS before RAS)/Auto refresh
Trp         EQU     (0x1)               ; 3clk
Trc         EQU     (0x2)               ; 6clk
Tchr        EQU     (0x2)               ; 3clk
REFCNT  EQU     995

(2) BANK CONTROL REGISTER (BANKCON6: nGCS6):

MT     Determine the memory type for bank6:  11 = Sync. DRAM
Trcd   RAS to CAS delay  01 = 3 clocks
SCAN   Column address number 01 = 9-bit

代码如下:
; Bank 6

B6_MT       EQU     (0x3)    ; SDRAM
B6_Trcd     EQU     (0x1)    ; 3clk
B6_SCAN     EQU     (0x1)    ; 9bit

(3) SDRAM MODE REGISTER SET REGISTER (MRSRB6)
CAS latency: 011=3 clocks
Burst type : 0: Sequential (Fixed)
Burst length: 000: 1 (Fixed)

代码如下:
 DCD 0x30              ; MRSRB6
 DCD 0x30              ; MRSRB7


8、 也可以在进入main函数之前,点一次灯来判别startup.s是否已经初始化完成。

; Hanson Test LED  ++
VLED_ON 0x7            
b .
; Hanson Test LED  --

b       main

9、 根据具体平台修改 SDRAM refresh control register configuration
REFCNT  EQU     1659                ;period=7.8us, HCLK=50Mhz, (2048+1-7.8*50)    ; Hanson change

10、保险起见,在main()函数第一行代码处再次点灯来判别是否进入了main函数。
while(1)
{
     OEMWriteDebugLED(0, 0xF);
}


至此, 已经顺利地进入了main函数。


三、 Debug Port初始化 --UART0

选取UART0作为调试端口。
GPH2 and GHP3 are UART0 TXD0 and RXD0。

1. 修改C:\WINCE500\PLATFORM\SMDK2440\SRC\INC\bsp_cfg.h

#define BSP_DEVICE_PREFIX       "SMDK2440"        // Device name prefix

//------------------------------------------------------------------------------
// Board clock
//------------------------------------------------------------------------------

#define S3C2440A_FCLK           405000000           // 405MHz
#define S3C2440A_HCLK           (S3C2440A_FCLK/3)   // divisor 3
#define S3C2440A_PCLK           (S3C2440A_HCLK/2)   // divisor 6

#define BAUD_RATE               115200

//------------------------------------------------------------------------------
// Debug UART0
//------------------------------------------------------------------------------

#define BSP_UART0_ULCON         0x03                // 8 bits, 1 stop, no parity
#define BSP_UART0_UCON          0x0245              // Rx pulse interrupt, Tx level interrupt, Rx error status interrupt enabled.
#define BSP_UART0_UFCON         0x00                // disable FIFO
#define BSP_UART0_UMCON         0x00                // disable auto flow control, Inactivate nRTS
#define BSP_UART0_UBRDIV        (S3C2440A_PCLK/(BAUD_RATE*16) - 1)

2. 修改C:\WINCE500\PLATFORM\SMDK2440\SRC\KERNEL\OAL\debug.c

修改Debug Serial 初始化函数:OEMInitDebugSerial()

VOID OEMInitDebugSerial()
{
    ......
    // Configure port H for UART0.
    //
    pIOPortReg = (S3C2440A_IOPORT_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);

    // GPH2 and GHP3 are UART0 TXD0 and RXD0, respectively.
    //
    CLRREG32(&pIOPortReg->GPHCON, (3 << 4)|(3 << 6));
    SETREG32(&pIOPortReg->GPHCON, (2 << 4)|(2 << 6));

    // Disable pull-up on TXD0 and RXD0.
    //
    SETREG32(&pIOPortReg->GPHUP, (1 << 2)|(1 << 3));

    // UART0 (TXD0 & RXD0) used for debug serial.
    //
    g_pUARTReg = (S3C2440A_UART_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_UART0, FALSE);

    // Configure the UART.
    //
    OUTREG32(&g_pUARTReg->UFCON,  BSP_UART0_UFCON);
    OUTREG32(&g_pUARTReg->UMCON,  BSP_UART0_UMCON);
    OUTREG32(&g_pUARTReg->ULCON,  BSP_UART0_ULCON);
    OUTREG32(&g_pUARTReg->UCON,   BSP_UART0_UCON);
    OUTREG32(&g_pUARTReg->UBRDIV, BSP_UART0_UBRDIV);

    ......
}

3.  至此, 就可以通过串口COM0来打印调试信息了。

另外,可以通过重定义OALMSG宏来打印OAL和EBOOT中所有OALMSG消息:
// Hanson Add ++
#define OALMSG(cond, exp)   ((void)((OALLog exp), TRUE))
// Hanson Add --





你可能感兴趣的:(loader)