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

我们知道 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 代码。代码中都有详细注释,具体请看代码:

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,之后就行我们都代码和功能的完善。

时间: 2024-07-30 10:12:17

tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——NAND 启动的相关文章

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

我们知道 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

tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——NAND 8位硬件ECC

这节我们实现nand的ecc,保存环境变量到nand flash 中.然后把我们之前的led灯烧写到nand flash 中,开机启动,在 tiny210.h 中定义宏 CONFIG_S5PV210_NAND_HWECC.CONFIG_SYS_NAND_ECCSIZE.CONFIG_SYS_NAND_ECCBYTES CONFIG_SYS_NAND_ECCSIZE 定义了消息长度,即每多少字节进行 1 次 ECC 校验 CONFIG_SYS_NAND_ECCBYTES 定义为 13Byte,将

tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——NAND添加分区

这里的分区只是为了操作的方便.假设有个分区 kernel,其地址区间为 0x20000~0x320000,其大小为 0x300000 在没有分区的情况下,对这块区间的操作如下: nand erase 20000 300000        擦除操作 nand write 20000000 20000 300000    写操作 nand read 20000000 20000 300000    读操作 而有了分区的情况下,操作将变得非常简单,如下(其中 kernel 为分区名) nand er

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

这节我们开始移植nand flash:通过查看帮助文档 doc/README.nand,要支持 NAND,需要配置CONFIG_CMD_NAND我们修改 tiny210.h,把 CONFIG_CMD_ONENAND 屏蔽掉,同时加上CONFIG_CMD_NAND: 编译出错 ,没有定义 CONFIG_SYS_MAX_NAND_DEVICE,最大 NAND 设备数,我们的板子只有 1 个 NAND,将其 定义为 1 再次编译,出错:未定义 NAND 的基地址,查看 S5PV210 手册, NAND

tiny210(s5pv210)移植u-boot(基于 2014.4 版本号)——移植u-boot.bin(打印串口控制台)

在之前我们移植的代码中,都没看到明显的效果,这节我们实现控制台的信息打印. 在上节.我们看到调用 relocate_code 重定位.在 u-boot 的帮助文档 doc/README.arm-relocation 中对重定位有说明. u-boot 为了生成位置无关码,在链接时指定了-pie 选项,这个选项在 u-boot-2014.04/arch/arm/config.mk 中指定: 当使用-pie 选项后.链接器会生成一个修正表(fixup  tables).在终于的二进制文件 u-boot

tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot.bin(打印串口控制台)

在之前我们移植的代码中,都没看到明显的效果,这节我们实现控制台的打印信息. 在上节,我们看到调用 relocate_code 重定位.在 u-boot 的帮助文档 doc/README.arm-relocation 中对重定位有说明.u-boot 为了生成位置无关码,在链接时指定了-pie 选项,这个选项在 u-boot-2014.04/arch/arm/config.mk 中指定: 当使用-pie 选项后,链接器会生成一个修正表(fixup  tables),在最终的二进制文件 u-boot.

s5pv210 移植 ubuntu(uboot + linux3.9.7 + ubuntu12.11 + xfce)

手里的s5pv210有两年了,性能也远远不如当下的应用处理器 但是跑比较简单的系统还是绰绰有余的 给s5pv210 移植 linaro ubuntu根文件系统 12.11 + xfce桌面系统,运行速度还是可以的,能上网. uboot + linux3.9.7 + ubuntu12.11 + xfce 可以作为远程tiny服务器. show下: 桌面 浏览器和设置界面 睡眠时的屏保界面

基于vs2005以上版本Qt程序发布的注意事项(讲了manifest的问题)

最近发现了一个非常恼人的程序deployment的问题,估计大家有可能也会遇到,特此memo. 问题的出现我觉得主要还是微软搞的花头太多, 一个不知所谓的manifest文件让本来简单的程序发布变得困难重重. 找了找关于manifest的介绍,貌似这个文件是用来描述程序或者库的依赖关系, 特别是对程序依赖的版本进行描述, 这样系统可以通过manifest的内容找到正确的库版本. 理论上讲这个dd确实是不错, 可以解决版本不兼容的问题, 保证程序运行的时候用的是指定版本的库. 不过实际操作起来麻烦

基于本博客版本中的循环缓冲的测试(Linux环境)

#include <stdlib.h> #include <stdio.h> #include <pthread.h> #include "ringbuffer.h" static int b_flag = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #define TX_LOCK(lock) pthread_mutex_lock(&lock) #define TX_UNLOCK