<strong>仿照韦东山老师的方法自己写一个简单的u-boot,发现启动不了zImage内核,在Starting kernel...处卡住。sdram中内核的数据与nand中内核的数据以及内核本身的数据是一致的,说明内核从nand拷贝到sdram是正确的。又看了一下sdram中的环境变量,发现也是正确的。代码已经上传附件,请大神帮我分析一下,问题出在哪里?? 不胜感激!!</strong><br>
<br>
<strong>开发板:友善之臂Tiny 6410, 256M sdram, 2G MLC2 Nand flash</strong><br>
<strong>Nand型号: K9GAG08U0E, 2G MLC2, 8K Page</strong><br>
<strong>烧写工具:MiniTools</strong><br>
<br><p>
友善之臂提供的MiniTools在烧写uboot到nand中的时候应该是已经处理过前4页只烧写2k内容的问题的。经过测试,友善之臂的MiniTools下载uboot到nand flash时每页只用前2K的空间而后面6K的空间装载的内容和前2K是一样的。</p><br>
<br>
<strong>hexdump zImage:</strong><br>
<br><p>
[root</p><p>@localhost</p><p> bins]# hexdump zImage | less</p><br><p>
0000000 0000 e1a0 0000 e1a0 0000 e1a0 0000 e1a0</p><br><p>
0000020 0002 ea00 2818 016f 0000 0000 5ac0 0039</p><br><p>
0000030 7001 e1a0 8002 e1a0 2000 e10f 0003 e312</p><br><p>
0000040 0001 1a00 0017 e3a0 3456 ef12 2000 e10f</p><br><p>
0000050 20c0 e382 f002 e121 0000 0000 0000 0000</p><br><p>
0000060 00d8 e28f 186e e890 d01c e590 47b8 e59f</p><br><p>
0000070 0001 e050 000a 0a00 5000 e085 b000 e08b</p><br><p>
0000080 c000 e08c 2000 e082 3000 e083 d000 e08d</p><br><p>
0000090 1000 e59b 1000 e081 1004 e48b 000c e15b</p><br><p>
00000a0 fffa 3aff 0000 e3a0 0004 e482 0004 e482</p><br><p>
00000b0 0004 e482 0004 e482 0003 e152 fff9 3aff</p><br><p>
00000c0 002e eb00 100d e1a0 2801 e28d 0002 e154</p><br><p>
00000d0 0016 2a00 0006 e084 0005 e150 0013 9a00</p><br><p>
00000e0 5002 e1a0 0005 e1a0 3007 e1a0 024f eb00</p><br>
<br>
<br>
<br>
<strong>串口中打印的数据如下:</strong><br>
<br><p>
Copying kernel from nand to sdram...</p><br><p>
0x1234ABCD</p><br><p>
Data in sdram from 0x50400000:</p><br><p>
0xE1A00000 0xE1A00000 0xE1A00000 0xE1A00000</p><br><p>
0xE1A00000 0xE1A00000 0xE1A00000 0xE1A00000</p><br><p>
0xEA000002 0x016F2818 0x00000000 0x00395AC0</p><br><p>
0xE1A07001 0xE1A08002 0xE10F2000 0xE3120003</p><br><p>
Copying finished!</p><br><p>
Setting kernel parameters...</p><br><p>
Kernel parameters setting finished!</p><br><p>
Data in sdram from 0x50000100:</p><br><p>
0x00000005 0x54410001 0x00000000 0x00000000</p><br><p>
0x00000000 0x00000004 0x54410002 0x10000000</p><br><p>
0x50000000 0x00000017 0x54410009 0x746F6F72</p><br><p>
0x65642F3D 0x746D2F76 0x6F6C6264 0x20656B63</p><br><p>
Starting kernel...</p><br>
<br>
<strong>使用友善之臂提供的u-boot_nand-ram256.bin烧写可以正常启动内核。</strong><br>
<br>
<strong>bdinfo如下:</strong><br>
<br><p>
MINI6410 # bdinfo</p><br><p>
arch_number = 0x000009D8</p><br><p>
env_t = 0x00000000</p><br><p>
boot_params = 0x50000100</p><br><p>
DRAM bank = 0x00000000</p><br><p>
-> start = 0x50000000</p><br><p>
-> size = 0x10000000</p><br><p>
ethaddr = 08:90:90:90:90:90</p><br><p>
ip_addr = 192.168.1.230</p><br><p>
baudrate = 115200 bps</p><br>
<br>
<strong>printenv如下:</strong><br>
<br><p>
MINI6410 # printenv</p><br><p>
bootdelay=3</p><br><p>
baudrate=115200</p><br><p>
ethaddr=08:90:90:90:90:90</p><br><p>
ipaddr=192.168.1.230</p><br><p>
serverip=192.168.1.88</p><br><p>
gatewayip=192.168.1.1</p><br><p>
netmask=255.255.255.0</p><br><p>
bootcmd=nand read.i c0008000 400000 500000;bootm c0008000</p><br><p>
bootargs=root=/dev/mtdblock2 console=ttySAC0,115200</p><br><p>
stdin=serial</p><br><p>
stdout=serial</p><br><p>
stderr=serial</p><br><p>
Environment size: 292/131068 bytes</p><br>
<br>
<strong>我的程序代码如下:</strong><br>
<br>
<br><p>
/**** nand.c ****/</p><br>
<br><p>
#define MEM_SYS_CFG (*((volatile unsigned long *)0x7E00F120))</p><br><p>
#define </p><p>NFC</p><p>ONF (*((volatile unsigned long *)0x70200000))</p><br><p>
#define NFCONT (*((volatile unsigned long *)0x70200004))</p><br><p>
#define NFCMMD (*((volatile unsigned long *)0x70200008))</p><br><p>
#define NFADDR (*((volatile unsigned long *)0x7020000C))</p><br><p>
#define NFDATA (*((volatile unsigned char *)0x70200010))</p><br><p>
#define NFSTAT (*((volatile unsigned long *)0x70200028))</p><br>
<br>
<br><p>
void nand_select(void) { NFCONT &= ~(1<<1); }</p><br><!--1-->
<br><p>
void nand_deselect(void) { NFCONT |= (1<<1);}</p><br><!--1-->
<br><p>
void nand_cmd(unsigned char cmd) { NFCMMD = cmd;}</p><br>
<br><p>
void nand_addr(unsigned char addr) { NFADDR = addr; }</p><br>
<br><p>
unsigned char nand_get_data(void) { return NFDATA; }</p><br>
<br><p>
void nand_send_data(unsigned char data) { NFDATA = data; }</p><br>
<br><p>
void wait_ready(void) { while ((NFSTAT & 0x1) == 0); }</p><br>
<br><p>
void nand_reset(void)</p><br><p>
{</p><br><p>
nand_select();</p><br>
<br><p>
nand_cmd(0xff);</p><br>
<br><p>
wait_ready();</p><br>
<br><p>
nand_deselect();</p><br><p>
}</p><br>
<br>
<br><p>
void nand_init(void)</p><br><p>
{</p><br><p>
MEM_SYS_CFG &= ~(1<<1);</p><br><!--1-->
<br><p>
#define TACLS 0</p><br><p>
#define TWRPH0 2</p><br><p>
#define TWRPH1 1</p><br>
<br><p>
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));</p><br><!--30-->
<br><p>
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));</p><br><!--12-->
<br><p>
NFCONT |= 1;</p><br>
<br><p>
NFCONT &= ~(1<<16); </p><br><!--16-->
<br><p>
nand_reset();</p><br><p>
}</p><br>
<br>
<br><p>
void nand_send_addr(unsigned int addr)</p><br><p>
{</p><br>
<br><p>
unsigned int page = addr / 8192;</p><br><p>
unsigned int col = addr & (8192 - 1);</p><br>
<br>
<br><p>
/* 这两个地址表示从页内哪里开始 */</p><br>
<br><p>
nand_addr(col & 0xff);</p><br>
<br><p>
nand_addr((col >> 8) & 0xff);</p><br>
<br>
<br>
<br><p>
/* 下面三个地址表示哪一页 */</p><br>
<br><p>
nand_addr(page & 0xff);</p><br>
<br><p>
nand_addr((page >> 8) & 0xff);</p><br>
<br><p>
nand_addr((page >> 16) & 0xff);</p><br>
<br><p>
}</p><br>
<br>
<br><p>
int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)</p><br><p>
{</p><br><p>
unsigned int addr = nand_start;</p><br><p>
int i = nand_start % 8192; //列地址</p><br><p>
int left = i; //</p><br><p>
int count = 0;</p><br><p>
unsigned char *dest = (unsigned char *)ddr_start;</p><br><p>
unsigned char data = 0;</p><br>
<br><p>
nand_select();</p><br>
<br><p>
while (count < len)</p><br><p>
{</p><br><p>
nand_cmd(0x00);</p><br>
<br><p>
nand_send_addr(addr);</p><br>
<br><p>
nand_cmd(0x30);</p><br>
<br><p>
wait_ready();</p><br>
<br><p>
for (; i < (8192-left) && count < len; i++)</p><br><p>
{</p><br><p>
data = nand_get_data();</p><br>
<br>
<p>IF</p><p>(addr< (4*8192)) //前4页</p><br><p>
{</p><br><p>
if(i<(2048-left)) //小于2K</p><br><p>
{</p><br><p>
dest[count++] = data;</p><br><p>
}</p><br><p>
}</p><br>
<br><p>
else</p><br><p>
{</p><br><p>
dest[count++] = data;</p><br><p>
}</p><br>
<br><p>
//dest[count++] = nand_get_data();</p><br><p>
addr++;</p><br><p>
}</p><br>
<br><p>
i = 0;</p><br>
<br><p>
left = i;</p><br>
<br><p>
}</p><br>
<br><p>
nand_deselect();</p><br>
<br><p>
return 0;</p><br><p>
}</p><br>
<br>
<br>
<br>
<br><p>
int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)</p><br><p>
{</p><br><p>
int ret;</p><br>
<br><p>
nand_init();</p><br>
<br><p>
ret = nand_read(nand_start, ddr_start, len);</p><br>
<br><p>
return ret;</p><br><p>
}</p><br>
<br><p>
/****** boot.c *******/</p><br>
<br><p>
#include "setup.h"</p><br>
<br><p>
#include "uart.h"</p><br>
<br><p>
extern int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len);</p><br>
<br><p>
extern void putstr(char * str);</p><br>
<br><p>
extern void uart_init(void);</p><br>
<br><p>
static struct tag *params;</p><br>
<br><p>
void setup_start_tag (void)</p><br><p>
{</p><br><p>
params = (struct tag *) 0x50000100;</p><br>
<br><p>
params->hdr.tag = ATAG_CORE;</p><br><p>
params->hdr.size = tag_size (tag_core);</p><br>
<br><p>
params->u.core.flags = 0;</p><br><p>
params->u.core.pagesize = 0;</p><br><p>
params->u.core.rootdev = 0;</p><br>
<br><p>
params = tag_next (params);</p><br><p>
}</p><br>
<br>
<br><p>
void setup_memory_tags (void)</p><br><p>
{</p><br>
<br><p>
params->hdr.tag = ATAG_MEM;</p><br><p>
params->hdr.size = tag_size (tag_mem32);</p><br>
<br><p>
params->u.mem.start = 0x50000000; //RAM起始地址</p><br><p>
params->u.mem.size = 256*1024*1024; //RAM: 256MB</p><br>
<br><p>
params = tag_next (params);</p><br>
<br><p>
}</p><br>
<br><p>
int strlen(char *str)</p><br><p>
{</p><br><p>
int i = 0;</p><br><p>
while(str</p><i>)<br>
{<br>
i++;<br>
}<br>
<br>
return i;<br>
}<br>
<br>
void strcpy(char *dest, char *src)<br>
{<br>
char *tmp = dest;<br>
<br>
while ((*dest++ = *src++) != '');<br>
}<br>
<br>
void setup_commandline_tag (char *commandline)<br>
{<br>
int len = strlen(commandline) + 1;<br>
<br>
params->hdr.tag = ATAG_CMDLINE;<br>
params->hdr.size = (sizeof (struct tag_header) + len + 3 ) >> 2;<br>
<br>
strcpy (params->u.cmdline.cmdline, commandline);<br>
<br>
params = tag_next (params);<br>
}<br>
<br>
void setup_end_tag (void)<br>
{<br>
params->hdr.tag = ATAG_NONE;<br>
params->hdr.size = 0;<br>
}<br>
<br>
<br>
int main(void)<br>
{<br>
int i,j; <br>
volatile unsigned int *p_sdram_kernel = (volatile unsigned int *)0x50008000;<br>
volatile unsigned int *p_sdram_parameters = (volatile unsigned int *)0x50000100; <br>
<br>
uart_init();<br>
<br>
void (*theKernel)(int zero, int arch, unsigned int params);<br>
<br>
<br>
<br>
/* 1. 从nand flash里把内核读入sdram */<br>
<br>
putstr("
Copying kernel from nand to sdram...
");<br>
<br>
copy2ddr(0x400000, 0x50008000, 0x500000); //将内核从nand flash拷贝到sdram,内核烧写在nand flash的 0x400000地址,拷贝到sdram的0x50008000地址,拷贝大小为0x500000<br>
<br>
puthex(0x1234ABCD);<br>
putstr("
");<br>
<br>
putstr("Data in sdram from 0x50400000:
");<br>
<br>
for(j = 0; j<4;j++)<br><!--4-->
{<br>
for(i = 0; i<4; i++)<br><!--4-->
{<br>
puthex(*(p_sdram_kernel + 4*j+i));<br>
putstr(" ");<br>
}<br>
<br>
putstr("
");<br>
} <br>
<br>
<br>
putstr("Copying finished!
");<br>
<br>
/* 2. 设置内核启动参数 */<br>
<br>
putstr("Setting kernel parameters...
");<br>
<br>
setup_start_tag();<br>
<br>
setup_memory_tags();<br>
<br>
setup_commandline_tag("root=/dev/mtdblocke rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200 lcd=S70");<br>
<br>
setup_end_tag();<br>
<br>
putstr("Kernel parameters setting finished!
");<br>
putstr("Data in sdram from 0x50000100:
");<br>
<br>
for(j = 0; j<4;j++)<br><!--4-->
{<br>
for(i = 0; i<4; i++)<br><!--4-->
{<br>
puthex(*(p_sdram_parameters + 4*j+i));<br>
putstr(" ");<br>
}<br>
<br>
putstr("
");<br>
}<br>
<br>
/* 3. 跳转到内核 */<br>
<br>
putstr("Starting kernel...
");<br>
<br>
theKernel = (void (*)(int, int, unsigned int)) 0x50008000; //内核在sdram中的地址<br>
theKernel(0, 2520, 0x50000100); //机器ID: 2520, 内核参数约定地址:0x50000100<br>
<br>
putstr("Error!
");<br>
<br>
<br>
return 0;<br>
}<br>
<br>
<br>
<br></i><p><br></p>
你确定启动后是卡死了而不是串口没有设置为console吗?会不会没有卡死,只是串口无输出
启动参数中我看用的ttySAC0 115200,确定内核驱动中有这个口吗?
首先第一步,你已经确定了copy过程的正确,包括内核和启动参数
然后第二步,你需要检查kernel中解析启动参数的地方格式是否和你的启动参数一致
第三步,确定是否kernel中有ttySAC0口
地四步,如果上面都没有结果,那么确定下kernel程序是否运行了,比如kernel启动代码中执行一个串口打印或者io口操作(越早越好,不行就汇编控制寄存器控制io口)
第五步,如果kernel是没有启动,那么就要确认启动地址相关,主要是编译器相关,可以用readelf,来检查kernel的elf格式文件,查看复位的代码地址 最佳答案
一周热门 更多>