文章目錄
- 一、bootm
- 二、environment value
- 三、booting sequence
-
- 1. u-boot
-
- 1.1 boot_jump_linux()
- 2. linux kernel
-
- 2.1 secondary_startup()
- 2.2 start()
- 四、DEBUG
-
- 1. invalid dtb
- 2. unknown-block
- 3. No working init found
一、bootm
為了簡單驗證,首先使用 u-boot 的指令将 uImage 拷貝到 40008000 處,然後從此處 boot,能解析成功 uImage 的頭資訊。
xhr4412 # bootm 40008000
## Booting kernel from Legacy Image at 40008000 ...
Image Name: Linux-5.8.5
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5222448 Bytes = 5 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... Bad Data CRC
ERROR: can't get kernel image!
-
Verifying Checksum ... Bad Data CRC
該問題是由于 kernel 分區太小,可能其中有壞塊,導緻檔案讀取不全,将 kernel 分區改大就可以解決該問題。
Verifying Checksum ... OK
Loading Kernel Image
Starting kernel ...
當然,kernel 還并沒有啟動起來。
二、environment value
環境變量檔案:
-
include/configs/xhr4412.h
三、booting sequence
1. u-boot
啟動檔案:
-
arch/arm/lib/bootm.c
1.1 boot_jump_linux()
該函數前都執行成功,但是之後并沒有成功執行 linux, 或者說沒有序列槽輸出,先從這個函數查起吧。
2. linux kernel
2.1 secondary_startup()
啟動檔案:
-
arch/arm/kernel/head.S
secondary_startup() 該函數應該是 linux 解壓後重新開始執行的地方。
是以,先點個燈吧。好吧,沒有成功。
2.2 start()
啟動檔案:
-
arch/arm/boot/compressed/head.S
u-boot 會直接跳轉到該位址開始執行 linux,相當于 u-boot 的 spl 部分,解壓并再啟動完整的 linux。
函數原型為:
-
void kernel_entry(void *fdt_addr, void *res0, void *res1, void *res2);
在這裡點燈,yes,可以成功,看來應該是 u-boot 傳入的參數導緻最後 boot 失敗。
四、DEBUG
打開 kernel 的 low-level debug 和 early_print 選項後,能夠列印出 kernel 的資訊,肯定是傳入的參數不正确,看來 u-boot 還需要再做修改才行。
Starting kernel ...
Error: invalid dtb and unrecognized/unsupported machine ID
r1=0x000022b8, r2=0x40000100
r2[]=05 00 00 00 01 00 41 54 00 00 00 00 00 00 00 00
Available machine support:
ID (hex) NAME
ffffffff Generic DT based system
ffffffff Samsung Exynos (Flattened Device Tree)
1. invalid dtb
報錯檔案:
-
arch/arm/kernel/setup.c:1085
閱讀源碼可以看出,寄存器 r1 為 mach_id = 8888,是 u-boot 中在
arch/arm/include/asm/mach-types.h
定義的,實際上用處不大,現在都是用 dts 了;r2 = 40000100,是 u-boot 傳的啟動參數,dts 的資訊也應該包含在内。
使用指令:
- mmc dev 0
- mmc read 40006FC0 460 5000
- mmc read 41000000 5460 C8
- bootm 40006FC0 - 41000000
将裝置樹檔案拷貝到記憶體,就可以啟動 kernel 了,不過傳輸的指令應該還有問題,kernel panic 了。
2. unknown-block
[ 4.950425] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,50)
[ 4.958983] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.8.5 #4
[ 4.964772] Hardware name: Samsung Exynos (Flattened Device Tree)
這是由于傳入的參數不對,或是 emmc 沒有分區導緻的。傳入參數在 dts 檔案中修改,然後使用 u-boot 對 emmc 進行分區。
3. No working init found
[ 3.666790] Waiting 1 sec before mounting root device...
[ 4.767081] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Opts: (null)
[ 4.774179] VFS: Mounted root (ext4 filesystem) on device 179:2.
[ 4.781039] devtmpfs: error mounting -2
[ 4.784859] Freeing unused kernel memory: 1024K
[ 4.788846] Run /sbin/init as init process
[ 4.792621] Run /etc/init as init process
[ 4.796314] Run /bin/init as init process
[ 4.800430] Run /bin/sh as init process
[ 4.804063] Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.
[ 4.818243] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 5.8.5 #4
[ 4.823985] Hardware name: Samsung Exynos (Flattened Device Tree)
看起來似乎是因為沒有找到根檔案系統的問題,因為我本來也還沒有移植嘛。
是以應該是時候移植根檔案系統的時候了。