天天看點

調試U-Boot筆記(四)

  昨天說了axd的那個 configure target... 菜單項中要選擇個什麼dll檔案。今天在公司裡我查了一下,确實如果。昨天我忽略了一點,打開axd進行調試的時候,axd怎麼知道我與目标闆是通過 jlink進行通信的?發果沒有,那麼實際上我們昨天調試的程式都是在電腦上仿真的。

    打開 options->configure target.. 在彈出的對話框中添加 jlinkrdi.dll 檔案。

調試U-Boot筆記(四)

    點選[add]按鈕,在jlink驅動的安路徑下找到 jlinkrdi.dll 檔案并添加進來。在我的電腦該檔案的路徑是:c:program files (x86)seggerjlinkarm_v434jlinkrdi.dll

    然後,我們再來調試u-boot程式。

    我們把axd的加載u-boot的指令寫成一個腳本檔案u-boot.txt,放到 e: 下。

    > loadbinary e:u-boot-gdbu-boot.bin 0x33f80000

    > loadsymbols e:u-boot-gdbu-boot.axf

    > setpc 0x33f80000

    然後我們在axd的指令行裡執行指令:

    > ob e:u-boot.txt

    axd就從u-boot.txt裡讀取指令,并執行。這樣可以減少我們反複敲指令帶來的麻煩。

    好,我們執行一下。代碼已導進來了,可以我們一執行就出錯了。

    這時我才想起,sdram沒有配置,下載下傳到0x33f80000位址上的代碼肯定無法儲存。是以,我們得先下載下傳并執行init.bin程式來初始化sdram,使之可用。

    ok,執行以下指令,下載下傳init.bin檔案并執行:

    > loadbinary e:init.bin 0x40000000

    > setpc 0x40000000

    > run

    這下,看到開發闆上的led在閃爍,說明init.bin程式完成了sdram的初始化。

    暫停程式,然再導入u-boot程式到0x33f80000

    ok,這下u-boot程式才算是真正地下載下傳到了目标闆上去了。單步執行一下,沒有問題。

    但我還是遇到了挑戰:

調試U-Boot筆記(四)

    為什麼執行到start.s檔案的165~166行時r0與r1的值不會勁呀!

調試U-Boot筆記(四)

    怎麼會是這兩個值呢?按程式的執行預期結果。它們應該都為0x33f80000呀!?

    按ctrl+m打開記憶體螢幕,将位址設定為0x33f80000,觀查這塊記憶體空間有沒有被篡改的迹象

調試U-Boot筆記(四)

    果不其然,發現程式執行了160行的 bl cpu_init_crit之後,0x33f80000空間記憶體全被篡改了:

調試U-Boot筆記(四)

    那問題肯定出在cpu_init_crit裡,那麼我們一步一步跟起去,看倒底是執行了什麼語句使用記憶體資料被改的。最終發現是在cpu_init_crint() 調用 lowleve_init()對sdram進行初始化時,記憶體裡的資料被破壞了:

調試U-Boot筆記(四)

    lowlevel_init定義在 u-boot/board/my2440/lowlevel_init.s 檔案裡,主要的工作是配置sdram的控制寄存器。将l155~167的資料逐一賦給bwscon位址的控制寄存器。正是這個指派操作,使用記憶體中存在的 資料被破壞。

    如果這個操作有破壞性,那很明顯我們是直接從0x33f80000位址運作的,不需要但初始化sdram了。我們可以會程式做一點小修改,使之跳過執行lowlevel_init。

    由于start.s中全為彙編代碼,不友善描述。這裡我用僞代碼說一下我的思路。

    之前的程式邏輯是:

    現在将其更改為: 

  cpu_init_crit()隻有在reboot時才執行,如果是從nandflash啟動,則調用nand_read_ll()從nandflash 中導入程式代碼,如果是從norflash啟動的,那麼就直接調用重定位函數relocate()将代碼從0x00搬到0x33f80000去。

    修改了start.s檔案行,重新編譯,再用axd進行調試。

    oh, yeah! u-boot真的跑起來了!!!

調試U-Boot筆記(四)

    好了,今天的學習就暫且到此為止。明天我們一起嘗試将u-boot燒錄到nandflash與norflash中……