仿照韦东山老师的方法自己写一个简单的u-boot,发现启动不了zImage内核,在Starting kernel...处卡住。sdram中内核的数据与nand中内核的数据以及内核本身的数据是一致的,说明内核从nand拷贝到sdram是正确的。又看了一下sdram中的环境变量,发现也是正确的。代码已经上传附件,请大神帮我分析一下,问题出在哪里?? 不胜感激!!
开发板:友善之臂Tiny 6410, 256M sdram, 2G MLC2 Nand flash
Nand型号: K9GAG08U0E, 2G MLC2, 8K Page
烧写工具:MiniTools
友善之臂提供的MiniTools在烧写uboot到nand中的时候应该是已经处理过前4页只烧写2k内容的问题的。经过测试,友善之臂的MiniTools下载uboot到nand flash时每页只用前2K的空间而后面6K的空间装载的内容和前2K是一样的。
hexdump zImage:
[root
@localhost bins]# hexdump zImage | less
0000000 0000 e1a0 0000 e1a0 0000 e1a0 0000 e1a0
0000020 0002 ea00 2818 016f 0000 0000 5ac0 0039
0000030 7001 e1a0 8002 e1a0 2000 e10f 0003 e312
0000040 0001 1a00 0017 e3a0 3456 ef12 2000 e10f
0000050 20c0 e382 f002 e121 0000 0000 0000 0000
0000060 00d8 e28f 186e e890 d01c e590 47b8 e59f
0000070 0001 e050 000a 0a00 5000 e085 b000 e08b
0000080 c000 e08c 2000 e082 3000 e083 d000 e08d
0000090 1000 e59b 1000 e081 1004 e48b 000c e15b
00000a0 fffa 3aff 0000 e3a0 0004 e482 0004 e482
00000b0 0004 e482 0004 e482 0003 e152 fff9 3aff
00000c0 002e eb00 100d e1a0 2801 e28d 0002 e154
00000d0 0016 2a00 0006 e084 0005 e150 0013 9a00
00000e0 5002 e1a0 0005 e1a0 3007 e1a0 024f eb00
串口中打印的数据如下:
Copying kernel from nand to sdram...
0x1234ABCD
Data in sdram from 0x50400000:
0xE1A00000 0xE1A00000 0xE1A00000 0xE1A00000
0xE1A00000 0xE1A00000 0xE1A00000 0xE1A00000
0xEA000002 0x016F2818 0x00000000 0x00395AC0
0xE1A07001 0xE1A08002 0xE10F2000 0xE3120003
Copying finished!
Setting kernel parameters...
Kernel parameters setting finished!
Data in sdram from 0x50000100:
0x00000005 0x54410001 0x00000000 0x00000000
0x00000000 0x00000004 0x54410002 0x10000000
0x50000000 0x00000017 0x54410009 0x746F6F72
0x65642F3D 0x746D2F76 0x6F6C6264 0x20656B63
Starting kernel...
使用友善之臂提供的u-boot_nand-ram256.bin烧写可以正常启动内核。
bdinfo如下:
MINI6410 # bdinfo
arch_number = 0x000009D8
env_t = 0x00000000
boot_params = 0x50000100
DRAM bank = 0x00000000
-> start = 0x50000000
-> size = 0x10000000
ethaddr = 08:90:90:90:90:90
ip_addr = 192.168.1.230
baudrate = 115200 bps
printenv如下:
MINI6410 # printenv
bootdelay=3
baudrate=115200
ethaddr=08:90:90:90:90:90
ipaddr=192.168.1.230
serverip=192.168.1.88
gatewayip=192.168.1.1
netmask=255.255.255.0
bootcmd=nand read.i c0008000 400000 500000;bootm c0008000
bootargs=root=/dev/mtdblock2 console=ttySAC0,115200
stdin=serial
stdout=serial
stderr=serial
Environment size: 292/131068 bytes
我的程序代码如下:
/**** nand.c ****/
#define MEM_SYS_CFG (*((volatile unsigned long *)0x7E00F120))
#define
NFCONF (*((volatile unsigned long *)0x70200000))
#define NFCONT (*((volatile unsigned long *)0x70200004))
#define NFCMMD (*((volatile unsigned long *)0x70200008))
#define NFADDR (*((volatile unsigned long *)0x7020000C))
#define NFDATA (*((volatile unsigned char *)0x70200010))
#define NFSTAT (*((volatile unsigned long *)0x70200028))
void nand_select(void) { NFCONT &= ~(1<<1); }
void nand_deselect(void) { NFCONT |= (1<<1);}
void nand_cmd(unsigned char cmd) { NFCMMD = cmd;}
void nand_addr(unsigned char addr) { NFADDR = addr; }
unsigned char nand_get_data(void) { return NFDATA; }
void nand_send_data(unsigned char data) { NFDATA = data; }
void wait_ready(void) { while ((NFSTAT & 0x1) == 0); }
void nand_reset(void)
{
nand_select();
nand_cmd(0xff);
wait_ready();
nand_deselect();
}
void nand_init(void)
{
MEM_SYS_CFG &= ~(1<<1);
#define TACLS 0
#define TWRPH0 2
#define TWRPH1 1
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));
NFCONT |= 1;
NFCONT &= ~(1<<16);
nand_reset();
}
void nand_send_addr(unsigned int addr)
{
unsigned int page = addr / 8192;
unsigned int col = addr & (8192 - 1);
/* 这两个地址表示从页内哪里开始 */
nand_addr(col & 0xff);
nand_addr((col >> 8) & 0xff);
/* 下面三个地址表示哪一页 */
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
}
int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i = nand_start % 8192; //列地址
int left = i; //
int count = 0;
unsigned char *dest = (unsigned char *)ddr_start;
unsigned char data = 0;
nand_select();
while (count < len)
{
nand_cmd(0x00);
nand_send_addr(addr);
nand_cmd(0x30);
wait_ready();
for (; i < (8192-left) && count < len; i++)
{
data = nand_get_data();
if(addr< (4*8192)) //前4页
{
if(i<(2048-left)) //小于2K
{
dest[count++] = data;
}
}
else
{
dest[count++] = data;
}
//dest[count++] = nand_get_data();
addr++;
}
i = 0;
left = i;
}
nand_deselect();
return 0;
}
int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
int ret;
nand_init();
ret = nand_read(nand_start, ddr_start, len);
return ret;
}
/****** boot.c *******/
#include "setup.h"
#include "uart.h"
extern int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len);
extern void putstr(char * str);
extern void uart_init(void);
static struct tag *params;
void setup_start_tag (void)
{
params = (struct tag *) 0x50000100;
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
void setup_memory_tags (void)
{
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = 0x50000000; //RAM起始地址
params->u.mem.size = 256*1024*1024; //RAM: 256MB
params = tag_next (params);
}
int strlen(char *str)
{
int i = 0;
while(str
)
{
i++;
}
return i;
}
void strcpy(char *dest, char *src)
{
char *tmp = dest;
while ((*dest++ = *src++) != '