久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2699|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

淺談RISC-V GCC之:鏈接腳本學(xué)習(xí)筆記(一)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:809235 發(fā)表于 2021-11-5 15:28 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我們在用RISC-V GCC做嵌入式開發(fā)的時(shí)候,免不了要和啟動(dòng)文件和鏈接文件等打交道,本篇文章記錄了一些鏈接腳本相關(guān)的學(xué)習(xí)筆記。
1.基礎(chǔ)概念
鏈接腳本的主要作用是描述輸入文件中的段應(yīng)當(dāng)如何映射到輸出文件中,并控制輸出文件的內(nèi)存布局。多數(shù)鏈接腳本都執(zhí)行類似功能。但是,如果需要,鏈接腳本也可以使用下面所描述的命令指揮鏈接器進(jìn)行很多其他操作。
鏈接器通常使用一個(gè)鏈接腳本。如果沒有為其提供一個(gè),鏈接器將會(huì)使用默認(rèn)的編譯在鏈接器執(zhí)行文件內(nèi)部的腳本。可以使用命令’–verbose’顯示默認(rèn)的鏈接腳本。
為了描述鏈接腳本語言,我們需要定義一些基本概念和詞匯。
鏈接器將許多輸入文件組合成一個(gè)輸出文件。輸出文件和每個(gè)輸入文件都有一個(gè)特定的已知格式成為目標(biāo)文件格式。每個(gè)文件都被稱為目標(biāo)文件。輸出文件通常叫做可執(zhí)行文件,但我們?nèi)詫⑵浞Q為目標(biāo)文件。每個(gè)目標(biāo)文件在其他東西之間,都有一個(gè)段列表。有時(shí)把輸入文件的段稱作輸入段,類似的,輸出文件的段稱作輸出段。
每個(gè)目標(biāo)文件中的段都有名字和大小。多數(shù)段還有一個(gè)相關(guān)的數(shù)據(jù)塊,稱為 段內(nèi)容。一個(gè)段可能被標(biāo)記為可加載,表示當(dāng)輸出文件運(yùn)行時(shí),段內(nèi)容需要先加載到內(nèi)存中。一個(gè)沒有內(nèi)容的段可能是可分配段,即在內(nèi)存中留出一段空間(有時(shí)還需要清零)。一個(gè)即不是加載又不是可分配的段,通常含有一些調(diào)試信息。
每個(gè)加載或可分配輸出段有兩個(gè)地址。第一個(gè)地址為VMA,或者叫做虛地址。這是當(dāng)輸出文件運(yùn)行時(shí)段所擁有的地址。第二個(gè)地址是LMA,或者叫加載內(nèi)存地址。這是段將會(huì)被加載的地址。一個(gè)它們會(huì)產(chǎn)生區(qū)別的例子是,當(dāng)一個(gè)數(shù)據(jù)段加載到ROM, 此后在程序啟動(dòng)時(shí)被復(fù)制到RAM中(這個(gè)技術(shù)通常被用來初始化全局變量)。此種情況下,ROM使用LMA地址,RAM使用VMA地址。
如果想查看目標(biāo)文件中的段,可以用objdump程序的’-h’選項(xiàng)。
每個(gè)目標(biāo)文件還有一個(gè)符號列表,稱為符號列表。一個(gè)符號可能是被定義的或者未定義的。每個(gè)符號都有一個(gè)名字,且所有已定義的符號在其他信息中間都有一個(gè)地址。如果將一個(gè)c或者c++程序編譯成目標(biāo)文件,會(huì)將所有定義過的函數(shù)和全局變量以及靜態(tài)變量作為已定義符號。所有輸入文件引用的未定義的函數(shù)或者全局變量會(huì)成為未定義符號。
2.常用關(guān)鍵詞與用法
ENTRY(symbol) 用來指定程序執(zhí)行的入口點(diǎn)
MEMORY            內(nèi)存分配命令
SECTIONS            段命令 描述輸出文件的內(nèi)存和布局
.text                 程序代碼段
.rodata              只讀數(shù)據(jù)
.data                可讀寫且需要初始化的數(shù)據(jù)
.bss                        可讀寫的清零初始化數(shù)據(jù)
ASSERT                     斷言
PROVIDE(symbol=expression)   定義一個(gè)符號
AT                         后跟MEMORY定義的內(nèi)存區(qū)域或者地址
ALIGN                      字節(jié)對齊
3 . MEMORY
鏈接器默認(rèn)的設(shè)置允許分配所有可用的內(nèi)存。你通過MEMORY命令可以重載這些。
MEMORY命令描述了一個(gè)內(nèi)存塊在目標(biāo)中的位置和大小。你可以使用它描述一個(gè)可能會(huì)在鏈接器中使用的內(nèi)存區(qū)域,以及那些必須避免使用的內(nèi)存區(qū)域。此后你可以把段放到特定的內(nèi)存區(qū)域里。鏈接器將會(huì)基于內(nèi)存區(qū)域設(shè)置段地址,如果區(qū)域趨于飽和將會(huì)產(chǎn)生警告信息。鏈接器不會(huì)為了把段更好的放入內(nèi)存區(qū)域而打亂段的順序。
一個(gè)鏈接腳本可能含有許多MEMORY命令,但是,所有定義的內(nèi)存塊都被當(dāng)作他們是在一個(gè)MEMORY命令中定義的一樣。MEMORY的語法是:
MEMORY
   {
     name [(attr)] : ORIGIN = origin, LENGTH =len
     ...
   }
name是鏈接腳本用來引用內(nèi)存區(qū)域的名字。區(qū)域名在鏈接腳本外部沒有任何意義。區(qū)域名被存儲在一個(gè)獨(dú)立的名字空間,且不會(huì)與符號名,文件名,或者段名起沖突。每個(gè)內(nèi)存區(qū)域必須在MEMORY命令中有一個(gè)不同的名字。但是你此后可以使用REGION_ALIAS命令為已存在的內(nèi)存區(qū)域添加別名。
attr字符是一個(gè)可選的屬性列表,用來決定是否讓一個(gè)腳本中沒有顯式指定映射的輸入段使用一個(gè)特定的內(nèi)存區(qū)域。就像SECTIONS中進(jìn)行過的說明,如果你不為一個(gè)輸入段指定一個(gè)輸出段,鏈接器將會(huì)創(chuàng)建一個(gè)與輸入段名字相同的輸出段。如果你定義了區(qū)域?qū)傩裕溄悠鲿?huì)使用他們來決定創(chuàng)建的輸出段存放的內(nèi)存區(qū)域。
attr字符串只能使用下面的字符組成:
‘R’只讀段
‘W’讀寫段
‘X’可執(zhí)行段
‘A’可分配段
‘I’已初始化段
‘L’類似于’I’
‘!’反轉(zhuǎn)其后面的所有屬性
如果一個(gè)未映射段匹配了上面除’!’之外的一個(gè)屬性,它就會(huì)被放入該內(nèi)存區(qū)域。’!’屬性對該測試取反,所以只有當(dāng)它不匹配上面列出的行何屬性時(shí),一個(gè)未映射段才會(huì)被放入到內(nèi)存區(qū)域。
origin是一個(gè)數(shù)字表達(dá)式,代表了內(nèi)存區(qū)域的起始地址。表達(dá)式必須等價(jià)于一個(gè)常數(shù)并且不能含有任何符號。關(guān)鍵字ORIGIN縮短為org或者o(但不能寫成ORG)。
len是一個(gè)表達(dá)式用來給出內(nèi)存區(qū)域中的字節(jié)數(shù)大小。類似于origin表達(dá)式,表達(dá)式必須只能為數(shù)字的切必須求值為常數(shù)。關(guān)鍵字LENGTH可以被縮寫為len或者l。
下面的例子里,我們制定了有兩個(gè)可分配的內(nèi)存區(qū)域:一個(gè)從’0’開始有256k字節(jié),另一個(gè)從’0x40000000’開始,由4兆字節(jié)。鏈接器把所有沒有顯式映射到一個(gè)內(nèi)存區(qū)域的段放到’rom’內(nèi)存區(qū)域內(nèi),段可以是只讀的或者可執(zhí)行的。鏈接器將把其它沒顯式指定內(nèi)存區(qū)域映射的段放到’ram’內(nèi)存區(qū)域。
MEMORY
   {
     rom (rx) : ORIGIN = 0, LENGTH = 256K
     ram (!rx) : org = 0x40000000, l = 4M
   }
一旦你定義了一個(gè)內(nèi)存區(qū)域,你可以使用’>region’輸出段屬性指引鏈接器把特殊輸出段放到該內(nèi)存區(qū)域。例如,如果你擁有一個(gè)內(nèi)存區(qū)域名為’mem’,你可以在輸出段定義中使用’>mem’。參考Output Section Region。如果沒有給輸出段指出地址,鏈接器將會(huì)把地址放到最先符合要求的內(nèi)存區(qū)域中的可用地址。如果指引給一個(gè)內(nèi)存區(qū)域的組合輸出段比區(qū)域還大,鏈接器將會(huì)提交錯(cuò)誤。
可以通過ORIGIN(memory)和LENGTH(memory)函數(shù)獲得內(nèi)存區(qū)域的起始地址以及長度:
   _fstack = ORIGIN(ram) + LENGTH(ram) - 4;
4. 段描述
4.1輸出段
完整的輸出段描述如下
section [address] [(type)] :
   [AT(lma)]
   [ALIGN(section_align) | ALIGN_WITH_INPUT]
   [SUBALIGN(subsection_align)]
   [constraint]
   {
     output-section-command
     output-section-command
     ...
   } [>region] [AT>lma_region] [:phdr:phdr ...] [=fillexp] [,]
地址(address)是一個(gè)輸出段VMA(虛地址)的表達(dá)式。此地址為可選參數(shù),但如果給出了地址,則輸出地址就會(huì)被精確的設(shè)置到給定值。
如果輸出的地址沒有給定,則依照下面的嘗試選擇一個(gè)地址。此地址將會(huì)被調(diào)整到符合輸出端要求的對齊地址。輸出段的對齊要求是所有輸入節(jié)中含有的對齊要求中最嚴(yán)格的一個(gè)。
輸出段地址探索如下:
如果為段設(shè)置了內(nèi)存區(qū)域,則段被放如該區(qū)域,并且段地址為區(qū)域中的下一個(gè)空閑位置。
如果使用MEMORY命令創(chuàng)建了一個(gè)內(nèi)存區(qū)域列表,此時(shí)第一個(gè)屬性匹配段的區(qū)域被選擇來加載段,段地址為區(qū)域中的下一個(gè)空閑位置。參見MEMORY。
如果沒有指定的內(nèi)存區(qū)域,或者沒有匹配段的,則輸出地址將會(huì)基于當(dāng)前位置計(jì)數(shù)器的值
  4.2輸入段
輸入段存在于輸出段的內(nèi)容中,用來指定不同輸入段在輸出段中的位置,常見的有.text .data  .rodat  .bss COMMOM等,一個(gè)輸入段描述由跟隨在段名稱后面括號包含的一個(gè)可選的文件名稱列表構(gòu)成。也可以使用通配符,例如
*main.o(.text)或者直接*(.text)
前一個(gè)代表main.o 文件中所有.text段,后一個(gè)代表所有參與鏈接文件中的.text段,當(dāng)然也可以排除一些文件
EXCLUDE_FILE (*文件名.o) *(.text)
5. 一些內(nèi)建函數(shù)
ABSOLUTE(exp)
返回表達(dá)式exp的絕對(非可重分配的,而不是非負(fù))值。主要用來在段定義內(nèi)為符號分配一個(gè)絕對值,通常段定義內(nèi)的符號值都是相對段地址的。
ADDR(section)
返回名為’section’的段的地址(VMA)。你的腳本必須事先未該段定義了位置。在下面的例子里,start_of_output_1, symbol_1, symbol_2分配了同樣的值,除了symbol_1為與段.output1相關(guān)的值而其他兩個(gè)為絕對值:
SECTIONS { ...
        .output1 :
          {
         start_of_output_1 = ABSOLUTE(.);
          ...
          }
        .output :
          {
          symbol_1 =ADDR(.output1);
          symbol_2 =start_of_output_1;
          }
      ... }
LENGTH(memory)
返回名為memory的內(nèi)存的長度。
MAX(exp1, exp2)
返回exp1和exp2最大的
MIN(exp1, exp2)
返回exp1和exp2最小的。
ORIGIN(memory)
返回名為memory的內(nèi)存區(qū)域的起始地址。
SIZEOF(section)
返回名為section段的字節(jié)數(shù)。如果段還沒被分配就是用函數(shù)求值,將會(huì)產(chǎn)生錯(cuò)誤。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 五月天国产视频 | 中文字幕1区2区3区 亚洲国产成人精品女人久久久 | 中文字幕精品一区二区三区精品 | 久优草| 成人毛片视频免费 | 国产在线资源 | 亚洲最大的黄色网址 | 免费在线观看黄视频 | 精品一区二区三区在线视频 | 国产精品久久久久久久久久免费看 | 国产精品一区二区欧美 | 亚洲一区精品在线 | 国产亚洲精品精品国产亚洲综合 | 日本在线综合 | 毛片软件 | 欧美日韩国产欧美 | 国产精品欧美一区二区 | 久久久久久久久久久国产 | 国产精品免费在线 | 亚洲一区二区精品 | 久久精品一级 | 日韩精品一区二区三区视频播放 | 欧美日韩电影一区 | 精品免费av | 特a毛片| 亚洲欧美视频一区 | 久久久精彩视频 | 中文字幕成人在线 | 精品美女视频在免费观看 | 国产精品视频久久久久久 | 老司机狠狠爱 | 成人免费淫片aa视频免费 | 成人免费小视频 | 国产欧美精品一区二区三区 | 不卡一区二区三区四区 | 中文字幕日韩在线观看 | 97色综合| 久久亚洲精品国产精品紫薇 | 91视频网址 | 日韩一级在线 | 一色一黄视频 |