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

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

一网友发来邮件求助,说是移植的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.支持内核启动》《》《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时就打印,查看卡到哪里去了。

通过仿真器对go命令加以改造
a.将通用寄存器值改成
R00 = 00000000 R01 = 000000A0 R02 = 08000100 R03 = 0000000C
R04 = 08008000 R05 = 08808000 R06 = 41129200 R07 = 083E0264
R08 = 08000000 R09 = 18000000 R10(SL) = 00000000 R11(FP) = 00000020
R12(IP) = 08808354 R13(SP) = 088E9464 R14(LR) = 08808298 PC = 08008000
CPSR = 400000D3 SPSR = B00000FF
b.通过仿真器修改 0x08000100 地址的值
sml 0x08000100 00000005 54410001 00000000 00000000 00000000 00000004 54410002 04000000 08000000 0000000F 54410009 736E6F63
sml 0x08000130 3D656C6F 53797474 2C30584D 32353131 386E3030 3D706920 746F6F62 6F722070 2F3D746F 2F766564 0073666E 00000000

BKM>dml 0x08000100 0x50
08000100: 00000005 54410001 00000000 00000000 …TA…
08000110: 00000000 00000004 54410002 04000000 …TA…
08000120: 08000000 0000000F 54410009 736E6F63 …TA…snoc
08000130: 3D656C6F 53797474 2C30584D 32353131 =eloSytt,0XM2511
08000140: 386E3030 3D706920 746F6F62 6F722070 8n00=pi toobor p
08000150: 2F3D746F 2F766564 0073666E 00000000 /=to/ved.sfn…
08000160: 00000000 00000000 00000000 00000000 …
然后让程序执行,这样通过uboot也可以让zImage得以执行。
可见go和bootm差异就是 go只是改写pc值,而bootm传递r0,r1,r2还有bootargs

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xx-xx-xxx-xxx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值