1. 程式人生 > >記錄u-boot不能引導核心的解決過程

記錄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 ...

看上上邊幾篇文章,發現自己對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時就列印,檢視卡到哪裡去了。