2014-07-15 66 views
2

但是,在檢查啓動代碼之後,我爲各種原因提供了我自己的啓動代碼(我們正在使用gcc交叉編譯器爲LEON2處理器(Sparc v8)空間應用程序和代碼不符合標準,在我看來它也非常複雜。我也覺得這部分非常有趣)。由於我們只使用移植過的newlib而沒有使用RTOS,所以我認爲這可以在沒有太多工作的情況下實現。替換裸機嵌入式系統中的啓動文件

爲了做到這一點,我使用-nostartfiles編譯了我的應用程序,因此我提供了自己的啓動入口點等等......代碼是從實際的啓動文件中取出來的,並對我進行了一些修改。

這似乎工作,但我現在卡在我應該初始化newlib的部分。

爲了理解這種工作方式,我編譯時使用和不使用-nostartfiles標誌來查找差異。由於其他部分不相關,因此在gcc調用collect2時,我只在這裏顯示最後一部分。

這是一個沒有建一個簡單的應用-nostartfiles

/opt/sparc-elf-4.4.2/bin/../libexec/gcc/sparc-elf/4.4.2/collect2 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/../../../../sparc-elf/lib/locore_mvt.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/../../../../sparc-elf/lib/crt0.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crti.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crtbegin.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/../../../../sparc-elf/lib/pnpinit_simple.o 
-L/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2 
-L/opt/sparc-elf-4.4.2/bin/../lib/gcc 
-L/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/../../../../sparc-elf/lib 
/tmp/ccCfxzLR.o 
-lgcc 
--start-group -lc -lgcc -lleonbare --end-group 
-lgcc 
--start-group -lc -lgcc -lleonbare --end-group 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crtend.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crtn.o 

現在一些調整後,我設法讓我的應用程序類似的東西。

/opt/sparc-elf-4.4.2/bin/../libexec/gcc/sparc-elf/4.4.2/collect2 
-o debug/BSW 
-L../../drv_EEPROM/SRC/debug 
-L/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2 
-L/opt/sparc-elf-4.4.2/bin/../lib/gcc 
-L/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/../../../../sparc-elf/lib 
-Map BSW_memory.map 
debug/trap_table.o 
debug/trap_reset.o 
debug/trap_access_exception.o 
debug/trap_fp_disabled.o 
debug/trap_window_overflow.o 
debug/trap_window_underflow.o 
debug/cpu_info.o 
debug/cpu_init.o 
debug/init_hooks.o 
debug/start_sequence.o 
debug/main.o 
debug/pnpinit_simple.o 
debug/register_atexit.o 
-lDrvEEPROM 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crti.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crtbegin.o 
-lgcc -lc -lgcc -lleonbare -lgcc -lc -lgcc -lleonbare 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crtend.o 
/opt/sparc-elf-4.4.2/bin/../lib/gcc/sparc-elf/4.4.2/crtn.o 
-Tlinkbootram 

我在GDB調試這一點,我可以看到正確執行我的代碼,至少現在看來,直到主叫。我的主要是非常簡單,只需打電話給printf。可悲的是,這個對printf的調用永遠不會返回,似乎永遠循環着。所以我猜想一些初始化沒有正確完成。

我想了解如何做的事情,但所有這些東西都很模糊,並沒有很多文件似乎可用。我仍然在學習,所以我可能錯過了一些重要的東西,但也許這裏的一些知識淵博的人可以提供一些前進的方式?謝謝。

回答

1

關於移植Newlib here有一些很好的文檔,包括C Runtime initialisation的實現。 CRT任務包括:

  • 設置目標平臺處於一致狀態。例如設置適當的異常向量。
  • 初始化堆棧和幀指針
  • 調用靜態數據初始化,包括靜態對象的C++構造函數。
  • 執行任何進一步的平臺特定初始化。
  • 調用C主函數。
  • 從main()退出時調用C++靜態對象析構函數。
  • 退出時從main()退出提供的返回碼。

不清楚你如何確定printf()沒有返回,但有一些可能性,如堆棧不足,或者實際上它會返回,但是當printf()調用返回main )將退出,然後會發生什麼取決於您的C運行時 - 大概會無限循環?如果從main()退出會禁用中斷,並且您的printf()輸出被緩衝和中斷驅動,則可能看不到任何輸出。另一種可能性是作爲main()中的最後一個語句,printf()調用返回可以通過將它與main()返回值「合併」來優化。我建議你至少在main()的末尾放置一個for(;;);以阻止它返回。 ()本身有點重量級作爲測試的起點;它需要大量的堆棧空間和stdout和syscalls的工作支持。我可能會從更低級別開始,更簡單一些,只需較少或不依賴庫,例如切換GPIO或無緩衝的串行輸出。

+0

謝謝你的信息 – Leo