引用 ARM開發(fā),對entry point的含義
本文引用地址:http://butianyuan.cn/article/201611/317248.htm 從事了這么久的ARM開發(fā),對entry point的含義一知半解,今日再次拿出一本寫得還算不錯的ARM教材來翻,書中這一段僅僅是把英文手冊單純翻譯成中文,并沒有講到真正的實質。不是ARM公司手冊寫得不詳細,而是多數(shù)中文教材的編寫采用的方式是: english--華文 mapping,但英文手冊是有系列組織的suite,而書本往往翻譯自系列中的一篇,容易使得讀者管中窺豹。 摘要:ARM link的時候-entry ‘行標號’ 選項用于指定程序的入口地址,其實就是ICE把代碼load完之后自動跳入的地址,最后的程序中這個工作是由bootloader來完成的,當然bootloader也可以跳到別的入口地址去。幾乎所有的成品ARM芯片都有內置的bootloader,因此開發(fā)者看到的程序入口點就是entry point。對于FPGA上的ARM系統(tǒng)調試,ARM復位后跳轉到一個固化地址,就需要自己寫bootloader代碼并通過scatter加載到rom中(我們的EAS片上存儲器包括rom在內全部用FPGA的ram實現(xiàn),tape out的時候bootloader代碼會被固化到chip的rom中) 1.entry point在編譯中的指定 看了make file,entry point的指定是在link的時候用命令行參數(shù)的方式告訴編譯器的, armlink ... -Entry reset_handler 如果采用RVDS或ADS,工程屬性中有entry point選項可供設置,但最終還是作為參數(shù)傳遞給armlink。 這樣, 在連接ICE并loadimage之后,ICE會通過JTAG把代碼映像搬移到內存中,然后把當前PC指針指向reset_handler,但引出了一個問題:在最終的產(chǎn)品中不存在ICE和JTAG,ARM上電復位后跳向固化的復位地址,如0xFFFF0000,那么由誰來讓PC指針指向我們指定的entry point呢?答案是:由bootloader代碼來完成,進一步引出2個問題:1,誰來生成bootloader?2,怎么把bootloader定位到硬件復位地址? 2. 自己寫bootloader并通過scatter文件將之定位到硬件復位地址。 或許某些開發(fā)工具會自動的為我們生成bootloader,這里介紹的是自力更生的方法。 首先介紹bootloader,這里僅實現(xiàn)中斷向跳轉: AREA Vect, CO ENTRY ;這個entry和本文中的entry point是沒有關系的,它表示的是匯編程序代碼部分的開始 LDR PC, Reset_Addr LDR PC, Undefined_Addr LDR PC, SWI_Addr LDR PC, Prefetch_Addr LDR PC, Abort_Addr NOP ; Reserved vector LDR PC, IRQ_Addr LDR PC, FIQ_Addr Reset_Addr DCD Reset_Handler Undefined_Addr DCD Undefined_Handler SWI_Addr DCD SWI_Handler Prefetch_Addr DCD Prefetch_Handler Abort_Addr DCD Abort_Handler IRQ_Addr DCD IRQ_Handler FIQ_Addr DCD FIQ_Handler Reset_Handler LDR PC, =0x00000000; 然后是scatter文件: ROM_LOAD 0x00000000 { ROM_EXEC 0x00000000 { * (InRoot$$Sections); 實現(xiàn)搬移scatter的代碼,編譯器自動生成 *(+RO) ; 除了bootloader的所有代碼段放這里 } D-TCM 0x00400000 0x003FFFFF { * (+RW,+ZI);這里放所有的RW段(char ch=4;)和ZI段(char ch; ch會被初始化零)。 } } ROM2 0xFFFF0000 { BOOTLOAD 0xFFFF0000 { bootloader.o(+RO) ;bootloader的程序段放這里 } } scatter也是在link的時候通過參數(shù)‘-scatter 文件名’傳遞的。 3.總結 在以上條件下,比較使用ICE和最終產(chǎn)品中的啟動順序:當使用ICE調試時,ICE讀入映像文件,找到其中的scatter信息,通過JTAG把代碼段和數(shù)據(jù)段放到指定的位置,然后把PC設為-entry所指定的標號,這就是為什么當我們loadimage之后看到的是在entry point中指定的行號所在的源代碼。當脫離ICE運行時,ARM上電后跳轉到硬件復位地址0xFFF0000 (ROM),我們已事先在那里燒入了我們的bootloader,bootloder從外設中讀入加載映像文件(如片外nand,I2C,UART等)并放入scatter的加載域中(0x00000000),然后跳轉到0x000000,由于我們已在scatter中將InRoot$$Sections定位在那里,所以它被執(zhí)行,它負責把映像文件從加載域搬移到執(zhí)行域中,然后跳轉到__main,__main是arm編譯器自動生成的,它負責清零ZI段和初始化C庫,最后__main跳向C代碼的入口main() |
評論