自己写u-boot启动不了内核?请问是为什么?

2019-12-03 13:55发布

<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&nbsp; &nbsp;&nbsp; &nbsp; = 0x00000000</p><br><p> boot_params = 0x50000100</p><br><p> DRAM bank&nbsp; &nbsp;= 0x00000000</p><br><p> -&gt; start&nbsp; &nbsp; = 0x50000000</p><br><p> -&gt; size&nbsp; &nbsp;&nbsp;&nbsp;= 0x10000000</p><br><p> ethaddr&nbsp; &nbsp;&nbsp;&nbsp;= 08:90:90:90:90:90</p><br><p> ip_addr&nbsp; &nbsp;&nbsp;&nbsp;= 192.168.1.230</p><br><p> baudrate&nbsp; &nbsp; = 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&nbsp; &nbsp;&nbsp;&nbsp;(*((volatile unsigned long *)0x7E00F120))</p><br><p> #define </p><p>NFC</p><p>ONF&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (*((volatile unsigned long *)0x70200000))</p><br><p> #define NFCONT&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (*((volatile unsigned long *)0x70200004))</p><br><p> #define NFCMMD&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (*((volatile unsigned long *)0x70200008))</p><br><p> #define NFADDR&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (*((volatile unsigned long *)0x7020000C))</p><br><p> #define NFDATA&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (*((volatile unsigned char *)0x70200010))</p><br><p> #define NFSTAT&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (*((volatile unsigned long *)0x70200028))</p><br> <br> <br><p> void nand_select(void) { NFCONT &amp;= ~(1&lt;&lt;1); }</p><br><!--1--> <br><p> void nand_deselect(void) { NFCONT |= (1&lt;&lt;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 &amp; 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 &amp;= ~(1&lt;&lt;1);</p><br><!--1--> <br><p> #define TACLS&nbsp; &nbsp;&nbsp;&nbsp;0</p><br><p> #define TWRPH0&nbsp; &nbsp; 2</p><br><p> #define TWRPH1&nbsp; &nbsp; 1</p><br> <br><p> NFCONF &amp;= ~((1&lt;&lt;30) | (7&lt;&lt;12) | (7&lt;&lt;8) | (7&lt;&lt;4));</p><br><!--30--> <br><p> NFCONF |= ((TACLS&lt;&lt;12) | (TWRPH0&lt;&lt;8) | (TWRPH1&lt;&lt;4));</p><br><!--12--> <br><p> NFCONT |= 1;</p><br> <br><p> NFCONT &amp;= ~(1&lt;&lt;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 &amp; (8192 - 1);</p><br> <br> <br><p> /* 这两个地址表示从页内哪里开始 */</p><br> <br><p> nand_addr(col &amp; 0xff);</p><br> <br><p> nand_addr((col &gt;&gt; 8) &amp; 0xff);</p><br> <br> <br> <br><p> /* 下面三个地址表示哪一页 */</p><br> <br><p> nand_addr(page &amp; 0xff);</p><br> <br><p> nand_addr((page &gt;&gt; 8) &amp; 0xff);</p><br> <br><p> nand_addr((page &gt;&gt; 16) &amp; 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;&nbsp;&nbsp;//列地址</p><br><p> int left = i;&nbsp; &nbsp; //</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 &lt; len)</p><br><p> {</p><br><p> &nbsp;&nbsp;nand_cmd(0x00);</p><br> <br><p> &nbsp;&nbsp;nand_send_addr(addr);</p><br> <br><p> &nbsp;&nbsp;nand_cmd(0x30);</p><br> <br><p> &nbsp;&nbsp;wait_ready();</p><br> <br><p> &nbsp;&nbsp;for (; i &lt; (8192-left) &amp;&amp; count &lt; len; i++)</p><br><p> &nbsp;&nbsp;{</p><br><p> &nbsp; &nbsp;data = nand_get_data();</p><br> <br> &nbsp; &nbsp;<p>IF</p><p>(addr&lt; (4*8192))&nbsp;&nbsp;//前4页</p><br><p> &nbsp; &nbsp;{</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;if(i&lt;(2048-left))&nbsp; &nbsp;//小于2K</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;{</p><br><p> &nbsp; &nbsp; dest[count++] = data;</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;}</p><br><p> &nbsp; &nbsp;}</p><br> <br><p> &nbsp; &nbsp;else</p><br><p> &nbsp; &nbsp;{</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;dest[count++] = data;</p><br><p> &nbsp; &nbsp;}</p><br> <br><p> &nbsp; &nbsp;//dest[count++] = nand_get_data();</p><br><p> &nbsp; &nbsp;addr++;</p><br><p> &nbsp;&nbsp;}</p><br> <br><p> &nbsp;&nbsp;i = 0;</p><br> <br><p> &nbsp;&nbsp;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-&gt;hdr.tag = ATAG_CORE;</p><br><p> params-&gt;hdr.size = tag_size (tag_core);</p><br> <br><p> params-&gt;u.core.flags = 0;</p><br><p> params-&gt;u.core.pagesize = 0;</p><br><p> params-&gt;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-&gt;hdr.tag = ATAG_MEM;</p><br><p> params-&gt;hdr.size = tag_size (tag_mem32);</p><br> <br><p> params-&gt;u.mem.start = 0x50000000;&nbsp; &nbsp;&nbsp; &nbsp;//RAM起始地址</p><br><p> params-&gt;u.mem.size =&nbsp;&nbsp;256*1024*1024;&nbsp; &nbsp;//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> &nbsp; &nbsp; int i = 0;</p><br><p> &nbsp; &nbsp; while(str</p><i>)<br> &nbsp; &nbsp; {<br> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;i++;<br> &nbsp; &nbsp; }<br> <br> &nbsp; &nbsp; return i;<br> }<br> <br> void strcpy(char *dest, char *src)<br> {<br> &nbsp; &nbsp; char *tmp = dest;<br> <br> &nbsp; &nbsp; while ((*dest++ = *src++) != '');<br> }<br> <br> void setup_commandline_tag (char *commandline)<br> {<br> &nbsp; &nbsp; int len = strlen(commandline) + 1;<br> <br> params-&gt;hdr.tag = ATAG_CMDLINE;<br> params-&gt;hdr.size = (sizeof (struct tag_header) + len + 3 ) &gt;&gt; 2;<br> <br> strcpy (params-&gt;u.cmdline.cmdline, commandline);<br> <br> params = tag_next (params);<br> }<br> <br> void setup_end_tag (void)<br> {<br> params-&gt;hdr.tag = ATAG_NONE;<br> params-&gt;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);&nbsp; &nbsp;//将内核从nand flash拷贝到sdram,内核烧写在nand flash的 0x400000地址,拷贝到sdram的0x50008000地址,拷贝大小为0x500000<br> <br> puthex(0x1234ABCD);<br> &nbsp; &nbsp; putstr(" ");<br> <br> putstr("Data in sdram from 0x50400000: ");<br> <br> for(j = 0; j&lt;4;j++)<br><!--4--> {<br> &nbsp;&nbsp;for(i = 0; i&lt;4; i++)<br><!--4--> &nbsp;&nbsp;{<br> &nbsp; &nbsp;puthex(*(p_sdram_kernel + 4*j+i));<br> &nbsp; &nbsp;putstr(" ");<br> &nbsp;&nbsp;}<br> <br> &nbsp; &nbsp;&nbsp;&nbsp;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&lt;4;j++)<br><!--4--> {<br> &nbsp;&nbsp;for(i = 0; i&lt;4; i++)<br><!--4--> &nbsp;&nbsp;{<br> &nbsp; &nbsp;puthex(*(p_sdram_parameters + 4*j+i));<br> &nbsp; &nbsp;putstr(" ");<br> &nbsp;&nbsp;}<br> <br> &nbsp; &nbsp;&nbsp;&nbsp;putstr(" ");<br> }<br> <br> /* 3. 跳转到内核 */<br> <br> putstr("Starting kernel... ");<br> <br> theKernel = (void (*)(int, int, unsigned int)) 0x50008000;&nbsp;&nbsp;//内核在sdram中的地址<br> theKernel(0, 2520, 0x50000100);&nbsp;&nbsp;//机器ID: 2520,&nbsp;&nbsp;内核参数约定地址:0x50000100<br> <br> putstr("Error! ");<br> <br> <br> return 0;<br> }<br> <br> <br> <br></i><p><br></p>
1条回答
lich90
1楼 · 2019-12-03 19:12.采纳回答
没看出什么问题呀,这部分看起来都很ok
你确定启动后是卡死了而不是串口没有设置为console吗?会不会没有卡死,只是串口无输出
启动参数中我看用的ttySAC0 115200,确定内核驱动中有这个口吗?

首先第一步,你已经确定了copy过程的正确,包括内核和启动参数
然后第二步,你需要检查kernel中解析启动参数的地方格式是否和你的启动参数一致
第三步,确定是否kernel中有ttySAC0口
地四步,如果上面都没有结果,那么确定下kernel程序是否运行了,比如kernel启动代码中执行一个串口打印或者io口操作(越早越好,不行就汇编控制寄存器控制io口)
第五步,如果kernel是没有启动,那么就要确认启动地址相关,主要是编译器相关,可以用readelf,来检查kernel的elf格式文件,查看复位的代码地址 最佳答案

一周热门 更多>