zoukankan      html  css  js  c++  java
  • 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 server文件夹下,然后就能够使用上一节移植的 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,之后即可我们都代码和功能的完好。



  • 相关阅读:
    某labs上传writeup-上传漏洞总结
    帮朋友写一个爬取地区信息的脚本
    python tab补全
    python中requests库中文乱码问题
    python中的Queue模块
    python中的ftplib模块
    ThinkSnS v4后台任意文件下载漏洞
    通过or注入py脚本
    bing查询旁站脚本
    Mysql的分页查询语句的性能分析
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4181079.html
Copyright © 2011-2022 走看看