记录u-boot不能引导内核的解决过程

来源:互联网 发布:无线mesh网络特点的是 编辑:程序博客网 时间:2024/05/16 01:51

问题还没有解决,记录一下吧。

一网友发来邮件求助,说是移植的u-boot启动不了内核,是2013.7版本的,移植到s5pv210上的。我之前移植的2013.1版本的没有问题的。

一开始觉得不是什么事,从以下几个方面查了:

a.传参数 机器码

b.内存初始化

c.检查拷贝到内存中的kernel是否完整

但是发现问题不是那么回事,上边的都排查过也没有找到问题所在,这个看来不是老生常谈的问题了。值得记录一下。

再深入的查找原因:

1.发现用bootm启动uImage能到这一步:

[Ver130807-TINY210v3]# fatload mmc 1 20000000 uImagereading uImage4816856 bytes read in 259 ms (17.7 MiB/s)[Ver130807-TINY210v3]# bootm 20000000## Booting kernel from Legacy Image at 20000000 ...   Image Name:   Linux-3.0.8-FriendlyARM   Image Type:   ARM Linux Kernel Image (uncompressed)   Data Size:    4816792 Bytes = 4.6 MiB   Load Address: 20008000   Entry Point:  20008000   Verifying Checksum ... OK   Loading Kernel Image ... OKStarting kernel ...

2.用go直接把zImage当成裸机程序来启动也启动不了

[Ver130807-TINY210v3]# fatload mmc 1 20000000 zImagereading zImage4816792 bytes read in 250 ms (18.4 MiB/s)[Ver130807-TINY210v3]# go 20000000## Starting application at 0x20000000 ...

内核是一句都没有打印出来,一般情况下会出现:

Uncompressing Linux... done, booting the kernel.

用crc32查看拷贝到内存中的数据是没有问题的,这个问题有点玄乎了。

3.用go启动Image

[Ver130807-TINY210v3]# fatload mmc 1 21000000 Imagereading Image9560164 bytes read in 463 ms (19.7 MiB/s)[Ver130807-TINY210v3]# go 21000000## Starting application at 0x21000000 ...

还是不行的。

说明问题是出在了:zImage还没有解压,这个属于前期的问题。

那么要从以下几个方面来看了:

1.可能出在kernel原始数据跟解压后的数据有重叠

将uImage下载到距离20008000很远的地方,这里选择22000000处。

[Ver130807-TINY210v3]# fatload mmc 1 22000000 uImagereading uImage4816856 bytes read in 256 ms (17.9 MiB/s)[Ver130807-TINY210v3]# bootm 22000000## Booting kernel from Legacy Image at 22000000 ...   Image Name:   Linux-3.0.8-FriendlyARM   Image Type:   ARM Linux Kernel Image (uncompressed)   Data Size:    4816792 Bytes = 4.6 MiB   Load Address: 20008000   Entry Point:  20008000   Verifying Checksum ... OK   Loading Kernel Image ... OKStarting kernel ...

查看一下bdinfo:

a.不能启动的u-boot

[Ver130807-TINY210v3]# bdinfoarch_number = 0x00000998boot_params = 0x20000100DRAM bank   = 0x00000000-> start    = 0x20000000-> size     = 0x20000000eth0name    = dm9000ethaddr     = 00:40:5c:26:0a:5bcurrent eth = dm9000ip_addr     = 192.168.1.230baudrate    = 115200 bpsTLB addr    = 0x3FFF0000relocaddr   = 0x3FF7D000reloc off   = 0x1C17D000irq_sp      = 0x3FE94F40sp start    = 0x3FE94F30FB base     = 0x00000000[Ver130807-TINY210v3]# 
b.能启动的uboot

[Ver130913-TINY210v2]# bdinfoarch_number = 0x00000998boot_params = 0x20000100DRAM bank   = 0x00000000-> start    = 0x20000000-> size     = 0x20000000ethaddr     = 00:40:5c:26:0a:5bip_addr     = 192.168.1.230baudrate    = 115200 bpsTLB addr    = 0x3FFF0000relocaddr   = 0x3FF7C000reloc off   = 0x1C17C000irq_sp      = 0x3FE93F68sp start    = 0x3FE93F58FB base     = 0x00000000[Ver130913-TINY210v2]# 

对比发现relocaddr reloc off irq_sq "sp start"是不同的。

[Ver130807-TINY210v3]# fatload mmc 1 21000000 zImagereading zImage4816792 bytes read in 277 ms (16.6 MiB/s)[Ver130807-TINY210v3]# go 21000000## Starting application at 0x21000000 ...Starting kernel ...

找到这里《移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤###4.支持内核启动》《Starting kernel ... 内核启动停止问题》《linux启动流程分析(3)---内核解压缩过程》《bootm后停在starting kernel》不过都没有解决问题。

看上上边几篇文章,发现自己对kernel的启动过程的理解不是完全对的,特别是linux启动流程分析(3)---内核解压缩过程》中提到的在最前边的是head.S,而后才是解压程序。

再理一下思绪,引导裸机程序是可以的,启动内核不可以,那么要转到最基本要求了:

在调用内核镜像前,u-boot必须使CPU具备以下的条件:


1. CPU 寄存器的设置:R0=0;
R1=Machine ID(即Machine Type Number,定义在
linux/arch/arm/tools/mach-types);
R2=内核标记列表在 RAM 中起始基地址;2. CPU 模式:必须禁止中断(IRQs和FIQs);
CPU 必须 SVC 模式;3. Cache 和 MMU 的设置:指令 Cache 可以打开也可以关闭;
数据 Cache 必须关闭;

这几条哪里都可以看到,但是检测有没有达到这个要求就有点难度了。最后可以借助J-link像《linux内核启动时R2的值来历》一样查看。还有一种调试方案是在内核中添加汇编打印代码,在启动时head.S时就打印,查看卡到哪里去了。









1 0