2016年11月20日 星期日

如何準備 sd.img (2016 版)

如何準備 sd.img (2016 版)

先前我們所準備的 sd.img 已經接近可以開機的階段,現在只要將開機核心及 bootloader
放至 sd.img 的第一個分割區即可進行開機。底下是 sd.img 的分割區及內容:

sd.img +- part1-+
       |        + MLO         -> 不是每塊 ARM 版都有,主要適用於 TI OMAP 系列
       |        + u-boot      -> 在編譯完之 u-boot-VERSION 目錄下
       |        + u-boot.bin  -> 在編譯完之 u-boot-VERSION 目錄下
       |        + uImage      -> 在編譯完之 linux-VERSION/arch/arm/boot 目錄下
       +- part2-+
                + roofs       -> 先前以 debootstrap 作出來的內容

把上述內容準備好之後,我們可以執行 runsd.sh,其內容如下:

MACHINE=vexpress-a9
SD_IMAGE=sd.img
MEMORY=256

qemu-system-arm -machine $MACHINE -m $MEMORY \
  -nographic \
  -drive file=./$SD_IMAGE,if=sd,format=raw,index=0 \
  -kernel ./bootloader/u-boot-2016.09/u-boot \

然後將 sd.img 完全解除掛載,再執行 sh runsd.sh,我們可以先放著給它跑,最終會當掉,或是在倒數計時階段按 Enter 暫停下來。暫停後會出現 u-boot 的提示符號,如底下所示:

Hit any key to stop autoboot:  0
=> 

請執行 bdinfo 如底下所示:

=> bdinfo
arch_number = 0x000008E0
boot_params = 0x60002000
DRAM bank   = 0x00000000
-> start    = 0x60000000
-> size     = 0x10000000
DRAM bank   = 0x00000001
-> start    = 0x80000000
-> size     = 0x00000004
eth0name    = smc911x-0
ethaddr     = 52:54:00:12:34:56
current eth = smc911x-0
ip_addr     = <NULL>
baudrate    = 38400 bps
TLB addr    = 0x6FFF0000
relocaddr   = 0x6FF7D000
reloc off   = 0x0F77D000
irq_sp      = 0x6FEDCEF0
sp start    = 0x6FEDCEE0


我們可以看到版子資訊,在此可以看到 DRAM bank 0 的 start 位址是 0x60000000,待會我們以此位址來載入核心並開機試試,接下來可以執行 mmcinfo 如底下所示:

=> mmcinfo
Device: MMC
Manufacturer ID: aa
OEM: 5859
Name: QEMU! 
Tran Speed: 25000000
Rd Block Len: 512
SD version 1.0
High Capacity: No
Capacity: 400 MiB
Bus Width: 1-bit
Erase Group Size: 512 Bytes

此時可以看到有一張 sd 卡,其容量是先前所定義的,以例來說為 400MB。接下來我們可以試著手動載入 linux 核心讓它開機,請執行:

=> fatload mmc 0:1 0x60000000 uImage
reading uImage
2438600 bytes read in 235 ms (9.9 MiB/s)

將 uImage 核心載入 0x60000000 位址,並使用 iminfo 來驗證:
=> iminfo 0x60000000

## Checking Image at 60000000 ...
   Legacy image found
   Image Name:   Linux-3.18.44
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2438536 Bytes = 2.3 MiB
   Load Address: 60008000
   Entry Point:  60008000
   Verifying Checksum ... OK

驗證完沒問題的話可以使用 bootm 指令來開機,指令如下:

=> bootm 0x60000000
## Booting kernel from Legacy Image at 60000000 ...
   Image Name:   Linux-3.18.44
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2438536 Bytes = 2.3 MiB
   Load Address: 60008000
   Entry Point:  60008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

之後會當掉,我們要修正這個問題。

開機故障排除

故障 1 訊息如下:

VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00          131072 mtdblock0  (driver?)
b300          409600 mmcblk0  driver: mmcblk
  b301           25600 mmcblk0p1 58c7bb94-01
  b302          382976 mmcblk0p2 58c7bb94-02
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

這是表示開機時的 bootargs 沒有設定好,以此例來說,系統找到的開機裝置為 mmcblk0,但是 bootargs 沒有設定好,我們可以在 u-boot 環境下執行底下指令來觀看 bootargs 的設定:

=> printenv bootargs

如果沒有設定或是設定錯誤的話,那麼開機就會失敗,請執行底下指令來設定 bootargs 環境變數:

=> setenv bootargs "root=/dev/mmcblk0p1 console=ttyAMA0"

此時再執行 printenv 來觀看環境變數設定可以看到正確的組態:

=> printenv bootargs
bootargs=root=/dev/mmcblk0p1 console=ttyAMA0

接著再重新執行載入核心及開機的流程:

=> fatload mmc 0:1 0x60008000 uimage
reading uimage
2438600 bytes read in 234 ms (9.9 MiB/s)
=> bootm 0x60008000

此時會出現新的錯誤訊息,如底下所示:

Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.18.44 #1
[<80014824>] (unwind_backtrace) from [<800116d0>] (show_stack+0x10/0x14)
[<800116d0>] (show_stack) from [<80477c64>] (dump_stack+0x98/0xac)
[<80477c64>] (dump_stack) from [<80475b10>] (panic+0x9c/0x200)
[<80475b10>] (panic) from [<80474040>] (cpu_die+0x0/0x80)
[<80474040>] (cpu_die) from [<00000000>] (  (null))
---[ end Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.

開機發生錯誤的解決方式:

開機時會有幾個錯誤訊息,最終會導致無法開機:

Timed out waiting for device dev-mmcblk0p1
     Dependency failed for /boot.

Dependency failed for Local File Systems.

..
等錯誤


請編譯核心,在 General Setup 底下的設定打開:

 [*] open by fhandle syscalls

然後再重新編譯一次核心,並且把編譯完的 uimage 複製至第一個分割區。



沒有留言:

張貼留言