您的位置:首页 > 其它

tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——NAND 启动

2014-07-29 07:37 609 查看
我们知道 s5pv210启动方式有很多种,sd卡和nand flash 启动就是其中的两种,前面我们实现的都是基于sd卡启动,这节我们开始实现从nand flash 启动:

从 NAND 启动 u-boot,需要 BL1 初始化 NAND 控制器,然后从 NAND 拷贝 BL2 到 DDR 内存。这里的BL1 即我们移植的 u-boot-spl.bin,BL2 即我们移植的 u-boot.bin。在 u-boot.bin 中的 NAND 驱动比较大,它包含了很多功能,而 u-boot-spl.bin 中只需要从 NAND 拷贝BL2 到 DDR 就行了,因此我们可以在 u-boot-spl.bin 进行简单的 NAND
控制器初始化,然后使用三星提供的带 8 位硬件 ECC 的 NAND 拷贝函数来拷贝 u-boot.bin 到 DDR 内存。我们修改 board/samsung/tiny210/tiny210.c 中的 copy_bl2_to_ram 函数,在这个函数中首先判断当前是从 SD 卡启动还是从 NAND 启动,如果是从 NAND 启动则进行 NAND 初始化,然后从 NAND 拷贝BL2 到 DDR 内存,如果是从 SD 卡启动,则从 SD 卡拷贝 BL2 到 DDR 内存。我们通过读取 OMR 寄存器来判断
S5PV210 当前是从哪个设备启动的。参考手册 Table 6-3,手册上并没有说 OM 寄存器的地址,我是参考的三星原厂的 u-boot 代码。代码中都有详细注释,具体请看代码:

[cpp] view
plaincopy

void copy_bl2_to_ram(void)

{

/*

** ch: 通道

** sb: 起始块

** bs: 块大小

** dst: 目的地

** i: 是否初始化

*/

#define CopySDMMCtoMem(ch, sb, bs, dst, i) \

(((u8(*)(int, u32, unsigned short, u32*, u8))\

(*((u32 *)0xD0037F98)))(ch, sb, bs, dst, i))

#define MP0_1CON (*(volatile u32 *)0xE02002E0)

#define MP0_3CON (*(volatile u32 *)0xE0200320)

#define MP0_6CON (*(volatile u32 *)0xE0200380)

#define NF8_ReadPage_Adv(a,b,c) (((int(*)(u32, u32, u8*))(*((u32 *)0xD0037F90)))(a,b,c))

u32 bl2Size = 250 * 1024; // 250K

u32 OM = *(volatile u32 *)(0xE0000004); // OM Register

OM &= 0x1F; // 取低5位

if (OM == 0x2) // NAND 2 KB, 5cycle 8-bit ECC

{

u32 cfg = 0;

struct s5pv210_nand *nand_reg = (struct s5pv210_nand *)(struct s5pv210_nand *)samsung_get_base_nand();

/* initialize hardware */

/* HCLK_PSYS=133MHz(7.5ns) */

cfg = (0x1 << 23) | /* Disable 1-bit and 4-bit ECC */

/* 下面3个时间参数稍微比计算出的值大些(我这里依次加1),否则读写不稳定 */

(0x3 << 12) | /* 7.5ns * 2 > 12ns tALS tCLS */

(0x2 << 8) | /* (1+1) * 7.5ns > 12ns (tWP) */

(0x1 << 4) | /* (0+1) * 7.5 > 5ns (tCLH/tALH) */

(0x0 << 3) | /* SLC NAND Flash */

(0x0 << 2) | /* 2KBytes/Page */

(0x1 << 1); /* 5 address cycle */

writel(cfg, &nand_reg->nfconf);

writel((0x1 << 1) | (0x1 << 0), &nand_reg->nfcont);

/* Disable chip select and Enable NAND Flash Controller */

/* Config GPIO */

MP0_1CON &= ~(0xFFFF << 8);

MP0_1CON |= (0x3333 << 8);

MP0_3CON = 0x22222222;

MP0_6CON = 0x22222222;

int i = 0;

int pages = bl2Size / 2048; // 多少页

int offset = 0x4000 / 2048; // u-boot.bin在NAND中的偏移地址(页地址)

u8 *p = (u8 *)CONFIG_SYS_SDRAM_BASE;

for (; i < pages; i++, p += 2048, offset += 1)

NF8_ReadPage_Adv(offset / 64, offset % 64, p);

}

else if (OM == 0xC) // SD/MMC

{

u32 V210_SDMMC_BASE = *(volatile u32 *)(0xD0037488); // V210_SDMMC_BASE

u8 ch = 0;

/* 参考S5PV210手册7.9.1 SD/MMC REGISTER MAP */

if (V210_SDMMC_BASE == 0xEB000000) // 通道0

ch = 0;

else if (V210_SDMMC_BASE == 0xEB200000) // 通道2

ch = 2;

CopySDMMCtoMem(ch, 32, bl2Size / 512, (u32 *)CONFIG_SYS_SDRAM_BASE, 0);

}

}

重新编译,但编译之前要添加nand所用的头文件:#include <asm/arch/nand_reg.h>成功生成 spl/tiny210-spl.bin 和 u-boot.bin,将它们全部拷贝到 tftp 服务器目录下,然后就可以使用上一节移植的 u-boot 来烧写最新的 u-boot 到 NAND
FLASH。

首先从 SD 卡启动开发板 ,擦除整个 NAND FLASH:



使用 tftpboot 下载 tiny210-spl.bin 到 DDR 的起始地址 0x20000000



烧写 tiny210-spl.bin 到 NAND 的 0 地址:



使用 tftpboot 下载 u-boot.bin 到 DDR 的起始地址 0x20000000



烧写 u-boot.bin 到 NAND FLASH 的 0x4000 地址(0x0~0x3FFF 预留给 tiny210-spl.bin)



拨动拨码开关,从 NAND 启动开发板,可以观察到u-boot正常启动了,现在我们的u-boot功能基本都实现了,我把代码放在这里 ,有兴趣的朋友可以看看:tiny210_u-boot_201404_v2.0,之后就行我们都代码和功能的完善。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐