问题还没有解决,记录一下吧。
一网友发来邮件求助,说是移植的u-boot启动不了内核,是2013.7版本的,移植到s5pv210上的。我之前移植的2013.1版本的没有问题的。
一开始觉得不是什么事,从以下几个方面查了:
a.传参数 机器码
b.内存初始化
c.检查拷贝到内存中的kernel是否完整
但是发现问题不是那么回事,上边的都排查过也没有找到问题所在,这个看来不是老生常谈的问题了。值得记录一下。
再深入的查找原因:
1.发现用bootm启动uImage能到这一步:
[Ver130807-TINY210v3]# fatload mmc 1 20000000 uImage
reading uImage
4816856 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 ... OK
Starting kernel ...
2.用go直接把zImage当成裸机程序来启动也启动不了
[Ver130807-TINY210v3]# fatload mmc 1 20000000 zImage
reading zImage
4816792 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 Image
reading Image
9560164 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 uImage
reading uImage
4816856 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 ... OK
Starting kernel ...
查看一下bdinfo:
a.不能启动的u-boot
[Ver130807-TINY210v3]# bdinfo
arch_number = 0x00000998
boot_params = 0x20000100
DRAM bank = 0x00000000
-> start = 0x20000000
-> size = 0x20000000
eth0name = dm9000
ethaddr = 00:40:5c:26:0a:5b
current eth = dm9000
ip_addr = 192.168.1.230
baudrate = 115200 bps
TLB addr = 0x3FFF0000
relocaddr = 0x3FF7D000
reloc off = 0x1C17D000
irq_sp = 0x3FE94F40
sp start = 0x3FE94F30
FB base = 0x00000000
[Ver130807-TINY210v3]#
b.能启动的uboot
[Ver130913-TINY210v2]# bdinfo
arch_number = 0x00000998
boot_params = 0x20000100
DRAM bank = 0x00000000
-> start = 0x20000000
-> size = 0x20000000
ethaddr = 00:40:5c:26:0a:5b
ip_addr = 192.168.1.230
baudrate = 115200 bps
TLB addr = 0x3FFF0000
relocaddr = 0x3FF7C000
reloc off = 0x1C17C000
irq_sp = 0x3FE93F68
sp start = 0x3FE93F58
FB base = 0x00000000
[Ver130913-TINY210v2]#
对比发现relocaddr reloc off irq_sq "sp start"是不同的。
[Ver130807-TINY210v3]# fatload mmc 1 21000000 zImage
reading zImage
4816792 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时就打印,查看卡到哪里去了。