本文主要是介绍u-boot-2012.07移植到TQ2440(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
五、支持Nand Flash读写:
1.修改配置文件include\configs\smdk2440.h打开之前注释掉的NAND相关的宏
#defineCONFIG_CMD_NAND //zai 101 hang
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET0x40000
#define CONFIG_ENV_SIZE0x20000
#define CONFIG_NAND_S3C2440 //zai 206 hang
#define CONFIG_SYS_S3C2440_NAND_HWECC
2.在drivers/mtd/nand/Makefile文件中增加一行
COBJS-$(CONFIG_NAND_S3C2440)+= s3c2440_nand.o
3.将drivers\mtd\nand\s3c2410_nand.c复制为drivers\mtd\nand\s3c2440_nand.c并进行修改
将s3c2440_nand.c中所有的2410替换为2440
//#define S3C2410_NFCONF_EN (1<<15)
//#define S3C2410_NFCONF_512BYTE (1<<14)
//#define S3C2410_NFCONF_4STEP (1<<13)
#define S3C2410_NFCONF_INITECC (1<<12)
#define S3C2410_NFCONF_nFCE (1<<11)
//#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
//#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
//#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
#define S3C2410_ADDR_NALE 12
#define S3C2410_ADDR_NCLE 8
修改下面这个函数为如下:
static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
struct s3c2440_nand *nand = s3c2440_get_base_nand();
debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
if (ctrl & NAND_CLE)
{
/* 发命令 */ writeb(cmd, &nand->nfcmd);
}
else if (ctrl & NAND_ALE)
{
/* 发地址 */ writeb(cmd, &nand->nfaddr);
}
}
将以下内容:
/* initialize hardware */
#if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)
tacls = CONFIG_S3C24XX_TACLS;
twrph0 = CONFIG_S3C24XX_TWRPH0;
twrph1 = CONFIG_S3C24XX_TWRPH1;
#else
tacls = 4;
twrph0 = 8;
twrph1 = 8;
#endif
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
writel(cfg, &nand_reg->nfconf);
替换为:
writel((0 << 12)|(1 << 8)|(0 << 4), &nand_reg->nfconf);
/*初始化ECC、禁止片选、使能NAND FLASH控制器*/
writel((1 << 4)|(0 << 1)|(1 << 0), &nand_reg->nfcont);
六、支持Nand Flash启动:
COBJS := smdk2440.onand_read_ll.o
Nand_read_ll.c文件内容如下:
/* NAND FLASH控制器 */
#define NFCONF(*((volatile unsigned long *)0x4E000000))
#define NFCONT(*((volatile unsigned long *)0x4E000004))
#define NFCMMD(*((volatile unsigned char *)0x4E000008))
#define NFADDR(*((volatile unsigned char *)0x4E00000C))
#define NFDATA(*((volatile unsigned char *)0x4E000010))
#define NFSTAT(*((volatile unsigned char *)0x4E000020))
static int isBootFromNorFlash(void)
{
volatile int *p = (volatile int *)0;
int val;
val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/* 写成功,是nand启动 */
*p = val;
return 0;
}
else
{
/* NOR不能像内存一样写 */
return 1;
}
}
void clear_bss(void)
{
extern int __bss_start, __bss_end__;
int *p = &__bss_start;
for (; p < &__bss_end__; p++)
*p = 0;
}
void nand_init_ll(void)
{
#defineTACLS 0
#defineTWRPH0 1
#defineTWRPH1 0
/* 设置时序 */
NFCONF =(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能NAND Flash控制器,初始化ECC, 禁止片选 */
NFCONT =(1<<4)|(1<<1)|(1<<0);
}
static void nand_select(void)
{
NFCONT &= ~(1<<1);
}
static void nand_deselect(void)
{
NFCONT |= (1<<1);
}
static void nand_cmd(unsigned char cmd)
{
volatile int i;
NFCMMD = cmd;
for (i = 0; i < 10; i++);
}
static void nand_addr(unsigned int addr)
{
unsigned int col = addr % 2048;
unsigned int page = addr / 2048;
volatile int i;
NFADDR = col & 0xff;
for (i = 0; i < 10; i++);
NFADDR = (col >> 8) & 0xff;
for (i = 0; i < 10; i++);
NFADDR = page & 0xff;
for (i = 0; i < 10; i++);
NFADDR = (page >> 8) & 0xff;
for (i = 0; i < 10; i++);
NFADDR = (page >> 16) & 0xff;
for (i = 0; i < 10; i++);
}
static void nand_wait_ready(void)
{
while (!(NFSTAT & 1));
}
static unsigned char nand_data(void)
{
return NFDATA;
}
void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
{
int col = addr % 2048;
int i = 0;
/* 1. 选中 */
nand_select();
while (i < len)
{
/* 2. 发出读命令00h */
nand_cmd(0x00);
/* 3. 发出地址(分5步发出) */
nand_addr(addr);
/* 4. 发出读命令30h */
nand_cmd(0x30);
/* 5. 判断状态 */
nand_wait_ready();
/* 6. 读数据 */
for (; (col < 2048) && (i< len); col++)
{
buf[i] = nand_data();
i++;
addr++;
}
col = 0;
}
/* 7. 取消选中 */
nand_deselect();
}
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
int i = 0;
/* 如果是NOR启动 */
if (isBootFromNorFlash())
{
while (i < len)
{
dest[i] = src[i];
i++;
}
}
else
{
nand_init_ll();
nand_read_ll((unsigned int)src, dest,len);
}
}
3.修改arch\arm\cpu\arm920t\start.S
call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABIcompliance */
ldr r0,=0x00000000
ldr r1, _TEXT_BASE
ldr r2, _bss_start_ofs
bl copy_code_to_sdram
bl clear_bss
ldr pc, = board_init_f /* 跳转到SDRAM */
.globl second
second:
mov sp, r2 /*重新设置栈指针 */
/* 调用第2阶段的代码 */
bl board_init_r
ldr r1, _TEXT_BASE
ldr r2, _bss_start_ofs
bl copy_code_to_sdram
bl clear_bss
ldr pc, = board_init_f /* 跳转到SDRAM */
.globl second
second:
mov sp, r2 /*重新设置栈指针 */
/* 调用第2阶段的代码 */
bl board_init_r
注释掉以下代码
#if 0
.globl relocate_code
relocate_code:
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */
。。。。。。。。。。。。。。。
clbss_l:str r2, [r0] /*clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
bl coloured_LED_init
bl red_led_on
#endif
#endif
4.修改arch\arm\lib\board.c中的函数board_init_f
//addr -=gd->mon_len;
//addr &=~(4096 - 1);
addr =CONFIG_SYS_TEXT_BASE;
注视最后的重定位,并跳转到刚才定义的second
//relocate_code(addr_sp,id, addr);
second(id, addr, addr_sp);
5.修改链接脚本arch\arm\cpu\u-boot.lds把start.o、nand_read_ll.o、lowlevel_init.o编译到前面4k
CPUDIR/start.o (.text)
board/smdk2440/libsmdk2440.o(.text)
6.修改arch\arm\lib\board.c
由于从NAND启动,CPU检测不到NOR FLASH,所以无法启动:
我们直接注释掉上面的hang();
# endif /*CONFIG_SYS_FLASH_CHECKSUM */
}
else {
puts(failed);
//hang();
}
#endif
7.测试能否成功从nand启动:
a.首先在开发板上ping一下主机,看是否恩能够ping通。
b.然后将u-boot.bin文件通过 TFTP 的方式加载到开发板的RAM中
SMDK2440 #tftp 32000000 u-boot.bin
c.擦除nand flash 芯片:
SMDK2440 #nand erase 0 40000
d.将u-boot.bin写到nand flash中:
SMDK2440 #nand write 32000000 0 40000
e.重启开发板。
这篇关于u-boot-2012.07移植到TQ2440(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!