【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
;---------------------------------------------------------------------------
参考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#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)
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);
......
}