rt-thread 自动初始化机制分析-关于编译链接及段信息
本來我的工作主要集中于嵌入式Linux這一塊,關于RTOS,雖然之前也有用UcosII做過一兩個項目并量產,但并不是主要發力點,感覺相對與Linux來說,RTOS太過“easy”,能研究的東西并不多。
最新閑來看到Rtthread發展挺不錯,文檔更新也比較多,也出了專用的IDE,加之“中美大戰”,“國產”、“愛國”等情懷也被炒至高點,因此動了心思來研究研究。
因為之前用過ucos,所以研究路線即定為:改用rtthread實現之前ucos項目的所有功能。
經過一周的時間,項目基本移植完成并正常使用,此過程,收益還挺多,也總結了一些觀點
1. rtthread兼容性還是不錯的,支持范圍也挺廣,Cortex M,A,R都有,還有RISC-V,尤其是R系列支持,讓人感覺非常好
2. 編碼風格及設計思想,與Linux相近,尤其是設備驅動的思想,熟悉linux的話來學習rtthread應該會很似曾相識
3. 實現了很多POSIX API,比如Socket,pthread等,甚至有與Linux相近的設備驅動,個人感覺有點不倫不類,既是一個RTOS,就應該做RTOS專業的事情(微小,實時,精妙),搞得太過復雜不一定是好事。當然它的目的肯定是為了應用層統一和跨平臺。
4. 至于內核的實現,比如中斷處理,任務調度,通訊機制等等,基本是常用實現手段
5. shell控制臺有點意思,比較方便查看相關信息
回到正題,在研究過程中,自動初始化這一機制比較有特色,當然還有動態庫以及模塊的加載。
網上有很多關于自動初始化機制的使用以及一些實現原理的分析,在此不多描述,其核心思想是把函數加入特定段,配合特定標示符號,在系統加載過程中,捕獲特定標示,進而實現函數調用。
此文主要分析編譯過程:
首先看編譯結果的段信息
ELF Header:Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: EXEC (Executable file)Machine: ARMVersion: 0x1Entry point address: 0x80100000Start of program headers: 52 (bytes into file)Start of section headers: 817480 (bytes into file)Flags: 0x5000200, Version5 EABI, soft-float ABISize of this header: 52 (bytes)Size of program headers: 32 (bytes)Number of program headers: 2Size of section headers: 40 (bytes)Number of section headers: 22Section header string table index: 21Section Headers:[Nr] Name Type Addr Off Size ES Flg Lk Inf Al[ 0] NULL 00000000 000000 000000 00 0 0 0[ 1] .text PROGBITS 80100000 010000 02ff3c 00 AX 0 0 32[ 2] .init PROGBITS 8012ff3c 03ff3c 000004 00 AX 0 0 4[ 3] .fini PROGBITS 8012ff40 03ff40 000004 00 AX 0 0 4[ 4] .rodata PROGBITS 8012ff48 03ff48 003f35 00 A 0 0 8[ 5] .ARM.exidx ARM_EXIDX 80133e80 043e80 000008 00 AL 1 0 4[ 6] .l1_page_table NOBITS 80134000 043e88 004000 00 WA 0 0 1[ 7] .data PROGBITS 80138000 048000 001398 00 WA 0 0 8[ 8] .bss NOBITS 8013c000 049398 008cd8 00 WA 0 0 16384[ 9] .comment PROGBITS 00000000 049398 00006e 01 MS 0 0 1[10] .ARM.attributes ARM_ATTRIBUTES 00000000 049406 00002d 00 0 0 1[11] .debug_info PROGBITS 00000000 049433 0425e0 00 0 0 1[12] .debug_abbrev PROGBITS 00000000 08ba13 0087ae 00 0 0 1[13] .debug_loc PROGBITS 00000000 0941c1 009650 00 0 0 1[14] .debug_aranges PROGBITS 00000000 09d818 000750 00 0 0 8[15] .debug_line PROGBITS 00000000 09df68 00e3dd 00 0 0 1[16] .debug_str PROGBITS 00000000 0ac345 007eb6 01 MS 0 0 1[17] .debug_frame PROGBITS 00000000 0b41fc 006ad8 00 0 0 4[18] .debug_ranges PROGBITS 00000000 0bacd8 000148 00 0 0 8[19] .symtab SYMTAB 00000000 0bae20 007840 10 20 1038 4[20] .strtab STRTAB 00000000 0c2660 00520f 00 0 0 1[21] .shstrtab STRTAB 00000000 0c786f 0000d9 00 0 0 1 Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)沒有什么特別,都是常用的一些段
再查看鏈接腳本imx6.lds,以imx6ul為例
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm)SECTIONS {. = 0x80100000;__text_start = .;.text :{*(.vectors)*(.text)*(.text.*)/* section information for finsh shell */. = ALIGN(4);__fsymtab_start = .;KEEP(*(FSymTab))__fsymtab_end = .;. = ALIGN(4);__vsymtab_start = .;KEEP(*(VSymTab))__vsymtab_end = .;. = ALIGN(4);/* section information for modules */. = ALIGN(4);__rtmsymtab_start = .;KEEP(*(RTMSymTab))__rtmsymtab_end = .;/* section information for initialization */. = ALIGN(4);__rt_init_start = .;KEEP(*(SORT(.rti_fn*)))__rt_init_end = .;} =0__text_end = .;__rodata_start = .;.rodata : { *(.rodata) *(.rodata.*) }__rodata_end = .;. = ALIGN(4);。。。。。。. = ALIGN(8);__bss_start = .;.bss :{*(.bss)*(.bss.*)*(COMMON). = ALIGN(4);}. = ALIGN(4);__bss_end = .;/* Stabs debugging sections. */.stab 0 : { *(.stab) }.stabstr 0 : { *(.stabstr) }.stab.excl 0 : { *(.stab.excl) }.stab.exclstr 0 : { *(.stab.exclstr) }.stab.index 0 : { *(.stab.index) }.stab.indexstr 0 : { *(.stab.indexstr) }.comment 0 : { *(.comment) }_end = .; }注釋已經非常明確:?/* section information for initialization */,及各組件的初始化,位于text段,由此可見模塊以及shell也位于此段。
以board.c的rt_hw_timer_init函數為例,確認一下過程:
首先使用:
INIT_BOARD_EXPORT(rt_hw_timer_init);
其實現為:
/* board init routines will be called in board_init() function */ #define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")#define INIT_EXPORT(fn, level) \RT_USED const init_fn_t __rt_init_##fn SECTION(".rti_fn." level) = fn針對GCC: #define SECTION(x) __attribute__((section(x)))很明確rt_hw_timer_init 在.rti_fn段,包含在text段
下面,確認text段信息:
objdump -t -j .text rtthread-imx6.elf
gwind@gwind-P5820T:/media/gwind/gcode/opensource/rt-thread/bsp/imx6ul$ objdump -t -j .text rtthread-imx6.elf | grep rt_hw 801001cc l F .text 0000002c rt_hw_timer_isr 80100334 l F .text 00000034 rt_hw_uart_isr 8012a108 l .text 00000000 rt_hw_context_switch_interrupt_do 80112028 g F .text 00000038 rt_hw_trap_swi 80111cb4 g F .text 0000022c rt_hw_stack_init 80111648 g F .text 00000020 rt_hw_interrupt_get_irq 80111bcc g F .text 00000034 rt_hw_set_domain_register 801103bc g F .text 00000058 rt_hw_cpu_shutdown 80112304 g .text 00000000 rt_hw_cpu_dcache_disable 80112098 g F .text 00000038 rt_hw_trap_dabt 8012ff20 g O .text 00000004 __rt_init_rt_hw_timer_init 80112244 g .text 00000000 rt_hw_cpu_icache_enable 8011220c g .text 00000000 rt_hw_context_switch_to 801118d0 g F .text 00000244 rt_hw_cpu_dump_page_table 80111ee0 g F .text 00000110 rt_hw_show_register 80122468 g F .text 00000114 rt_hw_serial_register 8012a07c g .text 00000000 rt_hw_context_switch_interrupt 80111724 g F .text 000001ac rt_hw_cpu_dump_page_table_2nd 80112190 g F .text 00000068 rt_hw_trap_fiq 80100648 g F .text 0000007c rt_hw_uart_init 8010030c g F .text 00000028 rt_hw_board_init 801120d0 g F .text 00000038 rt_hw_trap_resv 80111c00 g F .text 0000006c rt_hw_init_mmu_table 80112108 g F .text 00000088 rt_hw_trap_irq 80111590 g F .text 00000068 rt_hw_interrupt_init 80111690 g F .text 00000094 rt_hw_interrupt_install 8012ff24 g O .text 00000004 __rt_init_rt_hw_uart_init 80112320 g .text 00000000 rt_hw_cpu_icache_disable 80111ff0 g F .text 00000038 rt_hw_trap_undef 80111668 g F .text 00000028 rt_hw_interrupt_ack 80111c6c g F .text 00000048 rt_hw_mmu_init 8010bcb8 w F .text 00000020 rt_hw_console_output 801121f8 g .text 00000000 rt_hw_interrupt_disable 801115f8 g F .text 00000028 rt_hw_interrupt_mask 8012a0a8 g .text 00000000 rt_hw_context_switch_exit 801001f8 g F .text 00000114 rt_hw_timer_init 80111b14 g F .text 000000b8 rt_hw_mmu_setmtt 80112204 g .text 00000000 rt_hw_interrupt_enable 80111620 g F .text 00000028 rt_hw_interrupt_umask 80112234 g .text 00000000 rt_hw_cpu_dcache_enable 80111570 g F .text 00000020 rt_hw_vector_init 8012257c g F .text 00000420 rt_hw_serial_isr 8012a058 g .text 00000000 rt_hw_context_switch 80112060 g F .text 00000038 rt_hw_trap_pabt可見結果: 801001f8 g???? F .text? 00000114 rt_hw_timer_init
對比編譯的MAP信息:
?.text????????? 0x00000000801001cc????? 0x168 build/drivers/board.o
??????????????? 0x00000000801001f8??????????????? rt_hw_timer_init
最后,初始化調用,標識為__rti_init_rti_board_end
volatile const init_fn_t *fn_ptr;for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++){(*fn_ptr)();}static int rti_board_start(void) {return 0; } INIT_EXPORT(rti_board_start, "0.end");static int rti_board_end(void) {return 0; } INIT_EXPORT(rti_board_end, "1.end");其段信息:
gwind@gwind-P5820T:/media/gwind/gcode/opensource/rt-thread/bsp/imx6ul$ objdump -t -j .text rtthread-imx6.elf | grep __rt_init_ 8012ff2c g O .text 00000004 __rt_init_dfs_init 8012ff18 g .text 00000000 __rt_init_start 8012ff20 g O .text 00000004 __rt_init_rt_hw_timer_init 8012ff3c g .text 00000000 __rt_init_end 8012ff38 g O .text 00000004 __rt_init_rti_end 8012ff18 g O .text 00000004 __rt_init_rti_start 8012ff24 g O .text 00000004 __rt_init_rt_hw_uart_init 8012ff28 g O .text 00000004 __rt_init_rti_board_end 8012ff30 g O .text 00000004 __rt_init_libc_system_init 8012ff34 g O .text 00000004 __rt_init_finsh_system_init 8012ff1c g O .text 00000004 __rt_init_rti_board_start總結:
rt-thread目前裝機量也有好幾億了,使用上也非常方便,提供的組件也很豐富,值得學習及深入研究。
?
?
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的rt-thread 自动初始化机制分析-关于编译链接及段信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GPSD架构介绍及交叉编译和使用
- 下一篇: IMX8QXP内部M4移植rt-thre