天地無極, 乾坤借法 |
我已經有了樹莓派 2, 為什麼還需要用模擬器呢?
為了除錯, 我沒有可以在了樹莓派上用的 ice/jtag, 對於開發 bare metal 程式實在太困難, 總不能老是靠「冥想」, 有了 qemu arm 搭配 gdb 的除錯功能, 會有事半功倍的效果。
source code:
https://github.com/descent/bare-metal_qemu_arm_v7a
VersatilePB version startup.s test.c test.ld
- The software must be compiled and linked to be placed at 0x00010000
- I need to create a binary image of our program
- I can ignore interrupt handling for now
qemu load -kernel 後的檔案到 0x00010000, 但卻是從 0x00000000 執行, 有點不太理解。
而 qemu/arm 模擬的開發板 source code 在:
qemu/hw/arm vexpress.c versatilepb.c
可以看到其對 uart register 的定義。
hello world 程式只有 2 個檔案, 很容易理解, 最主要是設定 stack, call c function, 寫 uart register 完成字元的輸出。
ctrl+a x 可以離開 qemu。
list 1. L6 秀出了 hello ARM926EJ-S, 有沒很感動。
再來是 VEXPRESS-A9 的版本, 我以為如法泡製, 將 uart base address 改成 0x10009000 即可, 事實上, 我吃了更多的苦頭才找到答案。
VEXPRESS-A9 version startup_vexpress_a9.o test.c vexpress_a9.ld
首先 qemu 指令要改成 -bios
qemu-system-arm -M vexpress-a9 -m 128M -bios test.a9.bin -nographic
好不容易看到 qemu 有畫面了, 但是是錯誤的訊息, 我一開始以為是 stack 沒設好的關係 (事實上也是啦), 透過反組譯後, 發現原本的 0x10000 記憶體 (我拿這段位址當 stack 區域) 無法寫入, 在參考 http://infocenter.arm.com/help/topic/com.arm.doc.dui0448i/DUI0448I_v2p_ca9_trm.pdf p3-3, 0x6000_0000-0x7FFF_FFFF 512MB Local DDR2 lower, use the ddr2 address.
使用 0x70000000 這個位址來設定 stack 就對了, 然後把 qemu 記憶體大小改成 512M。
qemu-system-arm -M vexpress-a9 -m 512M -bios test.a9.bin -nographic
終於一舉功成。
另外 linker script 起始位置改為 0x0, 這樣才可以配合 gdb 來 single step。
在 gdb 下
x/8xb 0
可以看到載入的 test.a9.bin (linker script 起始位置為 0x10000 也一樣在 0x0 這裡看得到, 其實把 linker script 起始位置改為 0x0 也可以的), 就在這裡。
以下連結的程式碼也可以參考, 有 gic 的設定。該作者用 svn, 可用以下 svn 指令抓取 soure code。
http://ellcc.org/blog/?p=10
Updating From Outside Sources
svn co http://ellcc.org/svn/ellcc/trunk/baremetal svn ls http://ellcc.org/svn/ellcc/trunk/
能成功設定 gic + timer 才是我的終極目的。若你比我先完成了, 請通知我讓我抄一下, 這樣我就不用那麼累了。
最後還是要提醒一下, 模擬器畢竟是模擬器, 和真實機器還是有點差異, 例如 uart 的設定不會這麼簡單, 通常還有 Baud 要設定。為了不讓自己白努力一場, 請在真實機器驗證整個模擬環境的程式碼, 正常來說, 應該還要修修改改。
最後的最後再提醒第二下, 這個程式碼看起來好像能使用 c 語言了, 好像可以正常呼叫 c function, 但其實離真正可用的 c 環境還有點距離, 若隨意使用 c 的各種宣告 (例如沒有初始值的全域變數), 是有可能出問題的。
因為 bss 沒設定, data section 也沒處理好, 很容易就踩雷了。我另外寫了一份完整版的 c runtime, 請參考 source code makefile 得知 v_a9.elf 相關的程式檔案, 這個版本打造了完整的 c runtime, bss/data section 均做了相關的初始化 。
本來我打算整合到 simple c++ library 當中的, 但我的目的僅僅是 gic+timer, 就不分心在其他事情上了。
若要練習的朋友, 請從 v_a9.elf 開始。
目前的版本無法在 vexpress-a15 qemu 上執行, 若你成功改到 vexpress-a15 qemu 上執行, 可以通知我一下嗎? 這可是幫了我很大的忙。
ref:
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。