本文所要讲述的是如何使UBoot只编译一次就能支持从Nor Flash和Nand Flash启动,并且在保存环境变量时能够保存在其所在的Flash中.
注意,本文针对的为S3C2410芯片,其他芯片原理相同,可在适当修改代码后进行移植.
我们知道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中的工作.
下面讲解具体的修改过程(以u-boot-2010.09为例).
首先,修改include/configs/smdk2410.h文件,添加如下宏定义:
注意,本文针对的为S3C2410芯片,其他芯片原理相同,可在适当修改代码后进行移植.
我们知道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 @ 判断BWSCON[2:1]是否为00,如果是,则跳转到copy_myself
beq copy_myself
好了,双启动问题算是解决了,但是新的问题又来了,这个环境变量又应该如何保存呢?是都保存到Nor Flash还是Nand Flash呢?当然,最好的方式还是保存到各自所在的Flash中.这个可以设置一个标志,在进入Nand Flash启动代码时设置该标志,表示从Nand Flash启动,然后,在保存环境变量时通过该标志的值判断是调用Nor Flash的保存方法还是Nand Flash的保存方法.
下面讲解具体的修改过程(以u-boot-2010.09为例).
首先,修改include/configs/smdk2410.h文件,添加如下宏定义:
#define CONFIG_CMD_ENV // 开启环境变量操作命令
#define CONFIG_CMD_NAND // 开启Nand Flash操作命令
#ifdef CONFIG_CMD_NAND
# define CONFIG_SYS_NAND_BASE 0x4E000000 //Nand配置寄存器基地址
# define CONFIG_SYS_MAX_NAND_DEVICE 1
# define CONFIG_MTD_NAND_VERIFY_WRITE 1
# define CONFIG_NAND_S3C2410
# define STACK_BASE 0x33f00000 /* 堆栈基址 */
# define STACK_SIZE 0x8000 /* 堆栈大小 */
#endif
/*---------------------------------------------------------------------
* Boot From Nor or Nand Flash or both
*/
#define CONFIG_NOR_BOOT
#define CONFIG_NAND_BOOT
#ifdef CONFIG_NOR_BOOT
# define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
# define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
# define CONFIG_AMD_LV160B /* 使用AM29LV160DB Nor Flash芯片 */
# define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
/* timeout values are in ticks */
# define CONFIG_SYS_FLASH_ERASE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
# define CONFIG_SYS_FLASH_WRITE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Write */
# define CONFIG_ENV_IS_IN_FLASH /* 将环境变量保存到Nor Flash中*/
#endif
#ifdef CONFIG_NAND_BOOT
# define UBOOT_RAM_BASE 0x33f80000
# define NAND_CTL_BASE 0x4E000000
# define bINT_CTL(Nb) __REG(INT_CTL_