Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1183533
  • 博文数量: 221
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2139
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(221)

文章存档

2024年(6)

2023年(8)

2022年(2)

2021年(2)

2020年(29)

2019年(11)

2018年(23)

2017年(41)

2016年(76)

2015年(23)

我的朋友
最近访客

分类: LINUX

2016-08-11 10:43:38

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

一网友发来邮件求助,说是移植的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  
               
               
               

本文来自ChinaUnix博客,
阅读(2135) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~