2017-08-28 50 views
0

我想了解裸機C應用程序如何正確工作。我寫了自己的啓動彙編代碼,調用__libc_init_array,我看到它迭代了preinit_array部分並調用了其中的所有函數。據我所知GCC增加了需要之前主要運行一些自己的初始化程序段,但隨後進來的.init部分_init()功能。裸機C應用程序究竟如何啓動?

是否GCC生成功能?它來自libc嗎?或者我必須自己提供一個嗎?有什麼好的資源來學習這些東西?

+0

良好的資源包括您的平臺文檔和'objdump'。 – spectras

+0

符號與平臺有什麼關係?是在一個平臺上由gcc生成的init_(),而不是在另一個平臺上生成的::) –

+0

所有進程都是特定於平臺的。例如,在AVR上,init代碼必須包含一些填充以跳過中斷向量表。然後內容本身在這裏爲C程序設置運行環境:初始化固定寄存器,設置堆棧指針,可能安裝一些陷阱處理程序...再次,所有這些都是平臺特定的。 – spectras

回答

1

是什麼符號有平臺做?是由一個平臺上的 gcc生成的init_()而不是另一個平臺上的?

是的啓動和epiloque例程留給執行,實際上gcc不會產生它。

libc中提供這些sysmbols - https://github.com/bminor/newlib/blob/e0f24404b3fcfa2c332ae14c3934546c91be3f42/newlib/libc/misc/init.c

根據您的目標硬件的初始化可以這樣做完全不同的方式。

例STM32Fxxx啓動。

.section .text.Reset_Handler 
    .weak Reset_Handler 
    .type Reset_Handler, %function 
Reset_Handler: 
    ldr sp, =_estack /* Atollic update: set stack pointer */ 

/* Copy the data segment initializers from flash to SRAM */ 
    movs r1, #0 
    b LoopCopyDataInit 

CopyDataInit: 
    ldr r3, =_sidata 
    ldr r3, [r3, r1] 
    str r3, [r0, r1] 
    adds r1, r1, #4 

LoopCopyDataInit: 
    ldr r0, =_sdata 
    ldr r3, =_edata 
    adds r2, r0, r1 
    cmp r2, r3 
    bcc CopyDataInit 
    ldr r2, =_sbss 
    b LoopFillZerobss 
/* Zero fill the bss segment. */ 
FillZerobss: 
    movs r3, #0 
    str r3, [r2], #4 

LoopFillZerobss: 
    ldr r3, = _ebss 
    cmp r2, r3 
    bcc FillZerobss 

/* Call the clock system intitialization function.*/ 
    bl SystemInit 
/* Call static constructors */ 
    bl __libc_init_array 
/* Call the application's entry point.*/ 
    bl main 

正如你在這個實現兩個功能被稱爲看 - 一個SystemInit非常低槓桿的硬件初始化和__libc_init_array

它是newlib庫的內部初始化(時下最常見的在裸機使用項目)

的問題是,如果你決定不使用標準庫,你不希望鏈接任何標準庫。一些takechains只提供了返回語句的弱函數,有些則沒有。如果你得到了鏈接問題,只是評論此呼叫在啓動文件或者提供一個空函數自己

相關問題