天天看點

淺談RISC-V GCC之:連結腳本學習筆記(二)

上一篇介紹了部分連結腳本知識,這次我們用MRS(MounRiver Studio)中内置的CH57x系列模闆工程來具體實踐一下:

1 入口

淺談RISC-V GCC之:連結腳本學習筆記(二)

ENTRY 關鍵字,确定程式入口在_start處

2 記憶體布局

淺談RISC-V GCC之:連結腳本學習筆記(二)

記憶體配置設定,FLASH隻讀可執行,起始位址為0x00000000.大小為448K,448K也可以寫成16進制;RAM讀寫可執行,起始位址為0x20003800,大小為18K。

3輸出段

淺談RISC-V GCC之:連結腳本學習筆記(二)

.init輸出段,提供了兩個符号_sinit和_einit,_sinit為FLASH起始位址,緊接着4位元組對齊之後放的是輸入段.init,這個輸入段可以在start_CH573.S中看到,是起始跳轉。

淺談RISC-V GCC之:連結腳本學習筆記(二)

這兩個段是将本來預設放在FLASH 中的代碼放到RAM中去運作,.highcodelalign段起始位址4位元組對齊,符号_highcode_lma是FLASH 中已經排布到的位址,注意.highcode段運作在RAM中,其中 ”.” 是在RAM中的位址,在這裡就是RAM起始位址,_highcode_vma_start與此相同,在這個輸出段中有 .vector .vertor_handler .highcode輸入段,四位元組對齊之後又提供了一個此段結束的位址_highcode_vma_end ,這兩個輸出段中定義的三個符号是為了将FALSH 中的代碼搬運到RAM裡取運作,同樣可以在start_CH573.S中可以看到

淺談RISC-V GCC之:連結腳本學習筆記(二)

使用和上面同樣的寫法,可以自定義将源碼中的函數或者資料自定義到RAM中執行,隻需要在源碼中指定其section屬性即可

__attribute__((section(".highcode")))

UINT16 Get_Calibration_Cnt_RAM( UINT16 loc ){

...

}

淺談RISC-V GCC之:連結腳本學習筆記(二)

.text段是存放在FLASH,運作時位址也在FLASH中。

首先說下__global_pointer這個符号,RISC-V核心中有一個GP寄存器,可以用來通路其位址内+/- 2K的資料,隻需要一條彙編語句即可,如果不在範圍内,就會使用auipc或者lui配合其他包括低12位立即數的指令來通路,可以手動調整其位置,使頻繁用到的資料在其通路範圍内可以有效的減少代碼大小。

此三段可以看成一個部分,首先.dalign中”.”的值是一個表達式,ORIGIN(RAM)是RAM 的起始位址,MAX(0x800,SIZEOF(.highcode))代表0x800和.highcode段中的最大值, “.”等于兩值相加,.dlalign定義了符号_data_lma,是FLASH排布到此處的位址,.data段中_data_vma與.dalign中的”.”位址相同,因為中間沒有占用RAM區的資料,_data_vma,_data_lma,_edata,三個符号為搬運資料到RAM 中提供了位址,同樣可以在start_CH573.S中可以看到

淺談RISC-V GCC之:連結腳本學習筆記(二)

其中data中的輸入段具體有哪些類型變量,對應哪種段,有興趣的可以到對應的MAP檔案中檢視,如下圖所示

淺談RISC-V GCC之:連結腳本學習筆記(二)

.bss存放未初始化的變量或者初始化為0的全局變量,其中COMMON段比較特殊,有機會專門在說一下,_sbss和_ebss為清零提供位址,同樣可以在start_CH573.S中可以看到

淺談RISC-V GCC之:連結腳本學習筆記(二)
淺談RISC-V GCC之:連結腳本學習筆記(二)

設定棧,起始位址放在RAM最上層。

繼續閱讀