1. 程式人生 > >用模擬器解決Linux核心載入問題

用模擬器解決Linux核心載入問題

快樂蝦

歡迎轉載,但請保留作者資訊

在使用合眾達DVS6467T開發板時遇到一個問題,在核心選項中加上initramfs的支援,結果在bootm時核心載入失敗:

## Booting image at 8e000000 ...

Image Name:Linux-2.6.10_mvl401-davinci_evm-

Image Type:ARM Linux Kernel Image (uncompressed)

Data Size:3479208 Bytes =3.3 MB

Load Address: 80008000

Entry Point:80008000

Verifying Checksum ... OK

OK

Starting kernel ...

UncompressingLinux..........................................................................................................................................................done, booting the kernel.

然後就沒有下文了。

這種情況其實在剛開始除錯核心時經常會遇到,通常也只能通過核心功能的新增和刪除來初步判斷問題的位置。但我們現在有模擬器這個神器,就不再需要這麼摸索了。

下面有請模擬器大神上場。

首先啟動uboot並將核心tftp到板上。Bootm後出現上文所提的現象。

ccs下用模擬器連線裝置:

很顯然pc跑飛了,但此時已經無法得到更多資訊了。

再來一次。

uboot將核心tftp下載到裝置上,在bootm之前用ccs連線到裝置,此時ccs將在uboot的程式碼中中斷下來:

新增兩個斷點:

因為0x80008000這個地址是Linux核心的入口地址。

ccs中繼續執行,uboot繼續工作,我們也可以通過串列埠和uboot

進行互動。

在串列埠中輸入bootm,此時模擬器將在核心入口處中斷下來:

通過單步執行,很容易發現程式跑飛的位置:

/*

* The following fragment of code is executedwith the MMU on, and uses

* absolute addresses; this is not positionindependent.

*

*r0= cp#15 control register

*r1= machine ID

*r9= processor ID

*/

.type__mmap_switched, %function

__mmap_switched:

adrr3,__switch_data + 4

ldmiar3!,{r4, r5, r6, r7}

cmpr4,r5@ Copy data segment if needed

1:cmpner5,r6

ldrnefp,[r4], #4

strnefp,[r5], #4

bne1b

movfp,#0@ Clear BSS (and zero fp)

1:cmpr6,r7

strccfp,[r6],#4

bcc1b

在這裡清除BSS段時程式飛了。通過檢查各暫存器的值感覺並沒有什麼異常,但當核心執行到這裡時,可以發現mmu已經啟用了,那麼問題估計和這個有關了。

看看之前執行的MMU相關的一段程式碼:

/*

* Setup the initial page tables.We only setup the barest

* amount which are required to get the kernelrunning, which

* generally means mapping in the kernel code.

*

* r8=machinfo

* r9=cpuid

* r10 = procinfo

*

* Returns:

*r0,r3, r5, r6, r7 corrupted

*r4 =physical page table address

*/

.type__create_page_tables, %function

__create_page_tables:

ldrr5,[r8, #MACHINFO_PHYSRAM]@ physram

pgtblr4,r5@ page table address

………..

/*

* Nowsetup the pagetables for our kernel direct

*mapped region.We round TEXTADDR down tothe

*nearest megabyte boundary.It is assumedthat

* thekernel fits within 4 contigous 1MB sections.

*/

addr0,r4,#(TEXTADDR & 0xff000000)>> 18@ start of kernel

strr3,[r0, #(TEXTADDR & 0x00f00000) >> 18]!

addr3,r3, #1 << 20

strr3,[r0, #4]!@ KERNEL + 1MB

addr3,r3, #1 << 20

strr3,[r0, #4]!@ KERNEL + 2MB

addr3,r3, #1 << 20

strr3,[r0, #4]@ KERNEL + 3MB

……

很顯然這裡只配置了核心程式碼開始的3M空間,而我們的核心在加上initramfs之後,bss段的一部分資料是處於3M之外的,這也是正是核心跑飛的原因!!

知道原因就好辦了,修改下這段程式碼:

/*

* Nowsetup the pagetables for our kernel direct

*mapped region.

*/

addr0,r4,#(TEXTADDR & 0xff000000)>> 18

strr3,[r0, #(TEXTADDR & 0x00f00000) >> 18]!

ldrr6,=(TEXTADDR + 0x01000000 - 1)

addr0,r0, #4

addr6,r4, r6, lsr #18

1:cmpr0,r6

addr3,r3, #1 << 20

strlsr3,[r0], #4

bls1b

再編譯執行,搞定!!