logo资料库

移植u-boot到2410实现nor和nand双启动.pdf

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
移植 u-boot1.1.6 从 nand 和 nor 启动选择 2012 年 2 月 27 日 23:29 By Ct 前几天移植在重新研究 uboot 的移植和 linux 的移植,移植没有成功将 uboot 移植到 nor 和 nand 双启动,具体可以看我的日记,今天晚上,我又重新搞了一 遍,终于搞成功了,现在把记录记录如下: 参考文献: 1、http://blog.csdn.net/flytreeleft/article/details/6793126 2、 <> 3、http://www.embedu.org/Column/Column319.htm 4、完全手册 系统环境 编译器版本:gcc3.4.5(针对对于低版本 uboot 移植,久的版本交叉编译器可能会好 点) Uboot 版本:1.1.6 linux:ubuntu11.04 首先参考 smdk2410 建立自己的配置文件: 1、在 borad/samsung/文件夹中 建立自己的板子的文件夹 cp -ar smdk2410 my2410(一定不能手动复 制,然后重命名) 2、将 my2410 中的 smdk 改成 my2410, 3、在 include/configs 中复制 smdk2410 的配置文件为自己的 配置文件 将 makefile 中 改成 COBJS := my2410.o cp smdk2410.h my2410.h 4、在根目录下的 makefile 中增 加 my2410 的配置选项,参考 smdk2410 5、接下来修改 start.s 使其能够判断 nor 还是 nand 启动: 判断原理: 我们知道 UBoot 源码本身直接支持从 Nor Flash 启动,这是 Nor Flash 的可执行特 性决定的.而针对 Nand Flash,则涉及到前 4K 数据的问题.S3C2410 的 Nand Flash 控制 器有一个特殊的功能,就是能在上电后自动将 Nand Flash 中的前 4K 数据搬移到 4K 内 部的 RAM 中,并把 0x00000000 设置为内部 RAM 的起始地址,然后 CPU 从内部 RAM 的 0x000000 位置启动,该过程由硬件自动完成. 所以,要使 UBoot 支持从 Nand Flash 启动,必须在其前 4K 代码执行过程中完成将自身 复制到 RAM 中的工作. 但是,我们现在需要让 UBoot 支持双启动,现在的问题就是该如何判断 UBoot 是 在 Nor Flash 还是在 Nand Flash 中呢?呵呵,在 S3C2410(S3C2440)中,这个可以通过 BWSCON(BUS WIDTH & WAIT CONTROL REGISTER)控制寄存器[2:1]的值进行判断,如果
为 00 则表示是从 Nand Flash 启动的.因此,我们可以直接通过如下代码进行判断并在 BWSCON[2:1]为 00 时跳转到 UBoot 复制自身(copy_myself)的代码处: 源文档 在内存重定为之前,加入如下代码: # define BWSCON 0x48000000 ldr r0,=BWSCON ldr r0,[r0] ands r0,r0,#6 beq copy_myself 然后在任意位置加入如下代码: @ @ copy_myself: copy u-boot to ram @ copy_myself: @ reset NAND mov r1, #NAND_CTL_BASE //r1=0x4e000000 ldr r2, =0xf830 @ initial value str r2, [r1, #oNFCONF] //初始化 nandflash 寄存器参数 ldr r2, [r1, #oNFCONF] bic r2, r2, #0x800 @ enable chip str r2, [r1, #oNFCONF] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD] mov r3, #0 @ wait 1: add r3, r3, #0x1 cmp r3, #0xa blt 1b 2: ldr r2, [r1, #oNFSTAT] @ wait ready tst r2, #0x1 beq 2b ldr r2, [r1, #oNFCONF] orr r2, r2, #0x800 @ disable chip //等后面用的时候载开启 str r2, [r1, #oNFCONF] @ get read to call C functions //由于下面要运行 c 函数,所以要定义堆栈 ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp=0 @ copy UBOOT to RAM ldr r0, _TEXT_BASE //复制目的地的起始地址 mov r1, #0x0 //uboot 源的起始地址,这里应该是 nandflash 中的起始地址 mov r2, #0x40000 //uboot 的大小,这里应该根据自己的 uboot 大小进行相 应的修改,这里为 256K,足以 bl nand_read_ll //跳到 nandflash 复制函数开始复制 teq r0, #0x0 //ro 为上面函数的返回值 beq ok_nand_read
bad_nand_read: 1: b 1b @ infinite loop ok_nand_read: ldr r0, =boot_flash mov r1, #0x0 str r1, [r0] /*设置 boot_flash 的值为 0 表示为 nand 启动*/ @ verify mov r0, #0 ldr r1, _TEXT_BASE mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes go_next: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq stack_setup bne go_next notmatch: 1: b 1b DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 这样,start.s 修改就完成了 6、接下来修改 my2410.h 的配置文件,增加对 nandflash 和对板子中 sst39vf1208 的支 持:(系统原带的不是这个 norflash) #ifndef __CONFIG_H #define __CONFIG_H /* * High Level Configuration Options * (easy to change) */ #define CONFIG_ARM920T 1 /* This is an ARM920T Core */ #define CONFIG_S3C2410 1 /* in a SAMSUNG S3C2410 SoC */ #define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board */ /* input clock of PLL */ #define CONFIG_SYS_CLK_FREQ 12000000/* the SMDK2410 has 12MHz input clock */ #define USE_920T_MMU 1 #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ /* * Size of malloc() pool */ #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ /*
* Hardware drivers */ #define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */ #define CS8900_BASE 0x19000300 #define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */ /* * select serial console configuration */ #define CONFIG_SERIAL1 1 /* we use SERIAL 1 on SMDK2410 */ /************************************************************ * RTC ************************************************************/ #define CONFIG_RTC_S3C24X0 1 /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_BAUDRATE 115200 /* for tag(s) to transfer message to kernel, www.100ask.net */ #define CONFIG_SETUP_MEMORY_TAGS 1 #define CONFIG_CMDLINE_TAG 1 /*********************************************************** * Command definition ***********************************************************/ #define CONFIG_COMMANDS \ (CONFIG_CMD_DFL | \ CFG_CMD_CACHE | \ CFG_CMD_PING | \ CFG_CMD_JFFS2 | \ CFG_CMD_NAND | \ /*CFG_CMD_EEPROM |*/ \ /*CFG_CMD_I2C |*/ \ /*CFG_CMD_USB |*/ \ CFG_CMD_REGINFO | \ CFG_CMD_DATE | \ CFG_CMD_ELF) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include //在这里修改 uboot 的环境参数 #define CONFIG_BOOTDELAY 2 #define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 rootfstype=yaffs" #define CONFIG_ETHADDR 08:00:3e:26:0a:5b #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.1.62 #define CONFIG_SERVERIP 192.168.1.63 /*#define CONFIG_BOOTFILE "elinos-lart" */ #define CONFIG_BOOTCOMMAND "nboot 0x32000000 0 0; bootm 0x32000000"
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) #define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ /* what's this ? it's not used anywhere */ #define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ #endif /* * Miscellaneous configurable options */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "ct@lab410 " /* Monitor Command Prompt 这里可以 自己改成在 uboot 中的显示名称 */ #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START 0x30000000 /* memtest works on */ #define CFG_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */ #undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ #define CFG_LOAD_ADDR 0x33000000 /* default load address */ /* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */ /* it to wrap 100 times (total 1562500) to get 1 sec. */ #define CFG_HZ 1562500 /* valid baudrates */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } /*----------------------------------------------------------------------- * Stack sizes * * The stack sizes are set up in start.S using the settings below */ #define CONFIG_STACKSIZE (128*1024) /* regular stack */ #ifdef CONFIG_USE_IRQ #define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ #endif #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_IS_IN_NAND 1 //添加上面两句话是为了确保 common/env_flash.c 和 common/env_nand.c 中的内容被编 译进 uboot,并且添加这两种情况环境变量保存位置信息: /*----------------------------------------------------------------------- * Physical Memory Map
*/ #define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ #define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ #define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ #define CFG_FLASH_BASE PHYS_FLASH_1 /*----------------------------------------------------------------------- * FLASH and environment organization */ #define CONFIG_SST_39VF1601 1 #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define PHYS_FLASH_SIZE 0x00200000 /* 2MB */ #define CFG_MAX_FLASH_SECT (512) /* max number of sectors on one chip */ 这里 请关注我的另一片日记对于这个 512 的疑问 /*----------------------------------------------------------------------- * NAND FLASH BOOT */ #define CONFIG_S3C2410_NAND_BOOT 1 #define STACK_BASE 0x33f00000 #define STACK_SIZE 0x8000 #define NAND_CTL_BASE 0x4e000000 //定义 nand flash 控制器的起始地 址 #define bINT_CTL(Nb) _REG(INT_CTL_BASE+(Nb)) #define oNFCONF 0x00 #define oNFCMD 0x04 #define oNFADDR 0x08 #define oNFDATA 0x0c #define oNFSTAT 0x10 #define oNFECC 0x14 /*----------------------------------------------------------------------- * NAND flash settings */ #define NAND_MAX_CHIPS 1 #define CFG_MAX_NAND_DEVICE 1 #define CFG_NAND_BASE 0 /* timeout values are in ticks */ #define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* Timeout for Flash Erase */ #define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */ /*配置 nor 和 nand 的环境保存信息 #ifdef CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x1F0000) /* addr of environment */ #endif #ifdef CFG_ENV_IS_IN_NAND 1 #define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector *///64KB #define CFG_ENV_OFFSET 0x40000 #endif #endif /* __CONFIG_H */ 7、由于自带的没有对 nandflash 的读写,所以要增加这个函数, nand_read_ll 为新增加的 Nand Flash 读取方法,在 board/samsung/my2410 目录下新建 文件 nand_read.c 源文档 #include #include "linux/mtd/mtd.h" #include "linux/mtd/nand.h" //#define LARGEPAGE_FLASH #define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x)) #define NF_BASE 0x4e000000 #define NFCONF __REGi(NF_BASE + 0x0) #define NFCMD __REGb(NF_BASE + 0x4) #define NFADDR __REGb(NF_BASE + 0x8) #define NFDATA __REGb(NF_BASE + 0xc) #define NFSTAT __REGb(NF_BASE + 0x10) #define BUSY 1 inline void wait_idle(void) { int i; while(!(NFSTAT & BUSY)) for(i=0; i<10; i++); } #ifndef LARGEPAGE_FLASH #define NAND_SECTOR_SIZE 512 #else #define NAND_SECTOR_SIZE 2048 #endif #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1) /* low level nand read function */ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j; if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){
//if ((start_addr & NAND_BLOCK_MASK) /*|| (size > SZ_1M)*/) { return -1; /* invalid alignment */ } /* chip Enable */ NFCONF &= ~0x800; for(i=0; i<10; i++); for(i=start_addr; i < (start_addr + size);) { /* READ0 */ NFCMD = NAND_CMD_READ0; /* Write Address */ #ifndef LARGEPAGE_FLASH NFADDR = i & 0xff; NFADDR = (i >> 9) & 0xff; NFADDR = (i >> 17) & 0xff; NFADDR = (i >> 25) & 0xff; #else NFADDR = i & 0xff; NFADDR = (i >> 8) & 0x07; NFADDR = (i >> 11) & 0xff; NFADDR = (i >> 19) & 0xff; NFADDR = (i >> 27) & 0x3; NFCMD = NAND_CMD_READSTART; #endif wait_idle(); for(j=0; j < NAND_SECTOR_SIZE; j++) { *buf = (NFDATA & 0xff); buf++; } i += NAND_SECTOR_SIZE; } /* chip Disable */ NFCONF |= 0x800; /* chip disable */ return 0; } 之后在 makefile 中增加最 nand_read 的编译,即:COBJS := my2410.o flash.o nand_read.o 8、根据文档,修改板子目录下的 flash.c,以便支持 norflash 9、原生的 u-boot 没有对 nand 的驱动函数,这里得自己添加,这里可以参考完全手册 中第 nandflash 驱动的添加,注意手册上还增加了对 2440nand 的支持,我们这里不需 要,所以要去掉关于 2440 的设置 在 cpu/arm920t/s3c2410/s3c24x0 中增加如下函数,nand_flash.c /* * Changed from drivers/mtd/nand/s3c2410.c of kernel 2.6.13 */
分享到:
收藏