日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

u-boot.lds详细的分析

發布時間:2024/9/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 u-boot.lds详细的分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

u-boot.lds的更詳細的分析

Linker Script Format

Linker scripts are text files.

You write a linker script as a series of commands.Each command is either a keyword,

possibly followed by arguments,or an assignment to a symbol.You may separate commands using semicolons.Whitespace is generally ignored.

Strings such as file or format names can normally be entered directly.If the file name

contains a character such as a comma which would otherwise serve to separate file names, you may put the file name in double quotes.There is no way to use a double quote character in a file name.

You may include comments in linker scripts just as in C,delimited by‘/*’and‘*/’.As in

C,comments are syntactically equivalent to whitespace.

?

一個可執行img(鏡像)文件必須有一個入口點,并且只能有一個全局入口點,通常這個入口點的地址放在ROMFlash)的0x0位置,因此我們必須使編譯器知道這個入口地址,而該過程是通過修改連接腳本文件來完成的。

這里,我們可以嘗試著分析一下u-boot-1.1.6的鏈接腳本u-boot.lds。可以選擇u-boot-1.1.6/board/smdk2410/目錄下的鏈接腳本u-boot.lds進行剖析。

?

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

?

先看看GNU官方對OUTPUT_FORMAT的解釋:

Commands Dealing with Object File Formats

A couple of linker script commands deal with object file formats.

l?????????OUTPUT_FORMAT(bfdname)

l?????????OUTPUT_FORMAT(default,big,little)

The OUTPUT_FORMAT command names the BFD format to use for the output

file.Using OUTPUT_FORMAT(bfdname)is exactly like using‘--oformat bfdname’on the command line.If both are used,the command line option takes precedence.

?

You can use OUTPUT_FORMAT with three arguments to use different formats based

on the‘-EB’and‘-EL’command line options. This permits the linker script to set the output format based on the desired endianness. If neither‘-EB’nor‘-EL’are used, then the output format will be the first argument,default. If‘-EB’is used,the output format will be the second argument, big.If‘-EL’is used, the output format will be the third argument,little.

?

For example, the default linker script for the MIPS ELF target uses this command:

OUTPUT_FORMAT(elf32-bigmips,elf32-bigmips,elf32-littlemips)

This says that the default format for the output file is‘elf32-bigmips’, but if the user uses the‘-EL’command line option, the output file will be created in the‘elf32-littlemips’format.

?

注:BFD是一種特殊的庫。The linker accesses object and archive files using the BFD libraries.These libraries allow the linker to use the same routines to operate on object files whatever the object file format.

?

l?????????OUTPUT_FORMAT(DEFAULT,BIG,LITTLE) :?這一行的目的是指定輸出目標文件的輸出文件格式,一共三種,缺省是第一種DEFAULT

l?????????若有命令行選項-EB,?則使用第2BFD格式;?若有命令行選項-EL,則使用第3BFD格式.否則默認選第一個BFD格式.

l?????????三個分別指定在缺省、大端、小端情況下的輸出可執行文件格式,u-boot-1.1.6在這里(缺省為第一種,即elf32-littlearm)指定可執行文件輸出格式是elf32,小端和arm體系結構。

?

?

OUTPUT_ARCH(arm)

?

先看看GNU官方對OUTPUT_ARCH的解釋:

Other Linker Script Commands

OUTPUT_ARCH(bfdarch)

Specify a particular output machine architecture.The argument is one of the names used by the BFD library.You can see the architecture of an object file by using the objdump program with the‘-f’ option.

?

注:可通過?man -S 1 ld查看ld的聯機幫助,?里面也包括了對這些命令的介紹.

l?????????指定輸出可執行文件的平臺為ARM

l?????????OUTPUT_ARCH(BFDARCH):設置輸出文件的machine architecture(體系結構)BFDARCH為被BFD庫使用的名字之一。可以用命令objdump -f查看。

?

ENTRY(_start)?

先看看GNU官方對ENTRY的解釋:

Setting the Entry Point

The first instruction to execute in a program is called the entry point.You can use the

ENTRY linker script command to set the entry point.The argument is a symbol name:

ENTRY(symbol)

There are several ways to set the entry point.The linker will set the entry point by trying

each of the following methods in order,and stopping when one of them succeeds:

l?????????the‘-e’entry command-line option;

l?????????the ENTRY(symbol)command in a linker script;

l?????????the value of the symbol start,if defined;

l?????????the address of the first byte of the‘.text’section,if present;

l?????????The address 0.

?

中文解釋:

ENTRY(SYMBOL) :?將符號SYMBOL的值設置成入口地址。

入口地址(entry point):?進程執行的第一條用戶空間的指令在進程地址空間的地址。

ld有多種方法設置進程入口地址,?按一下順序: (編號越前,?優先級越高)

1ld命令行的-e選項

2、連接腳本的ENTRY(SYMBOL)命令

3、如果定義了start符號,?使用start符號值

4、如果存在.text section,?使用.text section的第一字節的位置值

5、使用值0

?

注:ENTRY(_start)?在這里的意思是——指定啟動時的函數入口地址,_start在每個CPU目錄下的start.S中定義,真正的啟動運行地址段在編譯時在/u-boot-1.1.6/board/smdk2410/config.mk中由TEXT_BASE宏定義,即TEXT_BASE = 0x33F80000

?

?

在開始看SECTIONS之前,我們先看看官方給SECTIONS的解釋和一個例子:

?

Simple Linker Script Example

Many linker scripts are fairly simple.

The simplest possible linker script has just one command:‘SECTIONS’.You use the

SECTIONS’command to describe the memory layout of the output file.

The‘SECTIONS’command is a powerful command.Here we will describe a simple use of it.

Let’s assume your program consists only of code,initialized data,and uninitialized data.

These will be in the‘.text’(代碼段),‘.data’(數據段),and‘.bss’(未初始化數據段)sections,respectively.Let’s assume further that these are the only sections which appear in your input files.

For this example,let’s say that the code should be loaded at address 0x10000,and that the

data should start at address 0x8000000.Here is a linker script which will do that:

SECTIONS

{

.=0x10000;

.text:{*(.text)}

.=0x8000000;

.data:{*(.data)}

.bss:{*(.bss)}

}

You write the‘SECTIONS’command as the keyword‘SECTIONS’,followed by a series of

symbol assignments and output section descriptions enclosed in curly braces.

The first line inside the‘SECTIONS’command of the above example sets the value of the

special symbol‘.’,which is the location counter.If you do not specify the address of an

output section in some other way(other ways are described later),the address is set from

the current value of the location counter.The location counter is then incremented by the

size of the output section.At the start of the‘SECTIONS’command,the location counter

has the value‘0’.

The second line defines an output section,‘.text’.The colon is required syntax which may

be ignored for now.Within the curly braces after the output section name,you list the

names of the input sections which should be placed into this output section.The‘*’is a

wildcard which matches any file name.The expression‘*(.text)’means all‘.text’input

sections in all input files.

Since the location counter is‘0x10000’when the output section‘.text’is defined,the linker

will set the address of the‘.text’section in the output file to be‘0x10000’.

The remaining lines define the‘.data’and‘.bss’sections in the output file.The linker

will place the‘.data’output section at address‘0x8000000’.After the linker places the

.data’output section,the value of the location counter will be‘0x8000000’plus the size of

the‘.data’output section.The e?ect is that the linker will place the‘.bss’output section

immediately after the‘.data’output section in memory

The linker will ensure that each output section has the required alignment,by increasing

the location counter if necessary.In this example,the specified addresses for the‘.text’

and‘.data’sections will probably satisfy any alignment constraints,but the linker may

have to create a small gap between the‘.data’and‘.bss’sections.

注:下面是對上面那個例子的中文解釋。

這段腳本將輸出文件的text section定位在0x10000, data section定位在0x8000000:

SECTIONS

{

. = 0x10000;

.text : { *(.text) }

. = 0x8000000;

.data : { *(.data) }

.bss : { *(.bss) }

}

?

解釋一下上述的例子:

l?????????. = 0x10000 :?把定位器符號置為0x10000 (若不指定,?則該符號的初始值為0).

l?????????.text : { *(.text) } :?將所有(*符號代表任意輸入文件)輸入文件的.text section合并成一個.text section,?section的地址由定位器符號的值指定,?0x10000.

l?????????. = 0x8000000?:把定位器符號置為0x8000000

l?????????.data : { *(.data) } :?將所有輸入文件的.text section合并成一個.data section,?section的地址被置為0x8000000.

l?????????.bss : { *(.bss) } :?將所有輸入文件的.bss section合并成一個.bss section,該section的地址被置為0x8000000+.data section的大小.

?

連接器每讀完一個section描述后,?將定位器符號的值*增加*section的大小(此處暫且不考慮對齊約束)。

?

下面開始分析SECTIONS

SECTIONS?

{

???????. = 0x00000000;

l?????????這里的點”.”,是定位器符號(GNU風格的一個典型)。

l?????????把定位器符號置為0x00000000 (若不指定,?則該符號的初始值為0)

l?????????定系統啟動從偏移地址零處開始。注意這只是個代碼地址偏移值,真正的起始地址是由編譯時指定的CFLAGS指定的。

?

???????. = ALIGN(4);

l?????????4字節對齊調整,?那么ALIGN(0x10)?16字節對齊后

?

再看看官方給的解釋:

ALIGN(exp)

Return the location counter(.)aligned to the next exp boundary.ALIGN

doesn’t change the value of the location counter—it just does arithmetic on it.

Here is an example which aligns the output.data section to the next 0x2000

byte boundary after the preceding section and sets a variable within the section

to the next 0x8000 boundary after the input sections:

SECTIONS{...

.data ALIGN(0x2000):{

*(.data)

variable=ALIGN(0x8000);

}

...}

The first use of ALIGN in this example specifies the location of a section be-

cause it is used as the optional address attribute of a section definition(see

Section 3.6.3[Output Section Address],page 37).The second use of ALIGN is

used to defines the value of a symbol.

The builtin function(內嵌函數)?NEXT is closely related to ALIGN.

?

NEXT(exp)

Return the next unallocated address that is a multiple of exp.This function is

closely related to ALIGN(exp);unless you use the MEMORY command to define

discontinuous memory for the output file,the two functions are equivalent.

?

對字節對齊的進一步講解,可以看看這篇博客:

http://www.yuanma.org/data/2006/0723/article_1213.htm

?

???????.text??????:

???????{

?????????cpu/arm920t/start.o?(.text)????/*.text段空間?*/

?????????*(.text)????/*后續.text段內容的分配*/

???????}

這段腳本的意思是將所有輸入文件的.text section,以及cpu/arm920t/start.o合并成一個.text section,該section的地址由定位器符號的值指定(字節對齊后定位器符號的值)。

?

???????. = ALIGN(4);

???????.rodata : { *(.rodata) } /*.rodata只讀數據段*/

這段腳本的意思是先進行4字節對齊,然后將所有輸入文件的.rodata section合并成一個.rodata section,該section的地址由定位器符號的值指定(字節對齊后定位器符號的值)。

?

???????. = ALIGN(4);

???????.data : { *(.data) }??/* .data可讀可寫數據段?*/

按照上面的解釋,這段應該自己去理解!

?

???????. = ALIGN(4);

???????.got : { *(.got) } /*.got段是uboot自定義的一個段,不是GNU官方定義的標準段?*/

?

???????. = .; //這里沒有搞清楚為什么要這樣做!

???????__u_boot_cmd_start = .;

/*把當前位置賦值給__u_boot_cmd_start,即定義了.u_boot_cmd段空間的開始位置?*/

?

???????.u_boot_cmd : { *(.u_boot_cmd) }

???????__u_boot_cmd_end = .;

/*把當前位置賦值給__u_boot_cmd_end,即定義了.u_boot_cmd段空間的結束位置

?

/*

armboot_end_data = .;???????;armboot_end_data符號指向之前所有分配完段的結束

*/

?

???????. = ALIGN(4);

???????__bss_start = .;

/* .bss段開始位置?*/

???????.bss : { *(.bss) }

?

???????_end = .;

/* .bss段結束位置?*/

}

?

?

最后附上官方對location counter的解釋:

The Location Counter

The special linker variable dot‘.’always contains the current output location counter.Since

the.always refers to a location in an output section,it may only appear in an expression

within a SECTIONS command.The.symbol may appear anywhere that an ordinary symbol

is allowed in an expression.

Assigning a value to.will cause the location counter to be moved.This may be used to

create holes in the output section.The location counter may never be moved backwards.

SECTIONS

{

output:

{

file1(.text)

.=.+1000;

file2(.text)

.+=1000;

file3(.text)

}=0x12345678;

}

In the previous example,the‘.text’section from‘file1’is located at the beginning of the

output section‘output’.It is followed by a 1000 byte gap.Then the‘.text’section from

file2’appears,also with a 1000 byte gap following before the‘.text’section from‘file3’.

The notation‘=0x12345678’specifies what data to write in the gaps(see Section 3.6.8.5

[Output Section Fill],page 45).

Note:.actually refers to the byte o?set from the start of the current containing object.

Normally this is the SECTIONS statement,whose start address is 0,hence.can be used as

an absolute address.If.is used inside a section description however,it refers to the byte

o?set from the start of that section,not an absolute address.Thus in a script like this: Using LD,the GNU linker

SECTIONS

{

.=0x100

.text:{

*(.text)

.=0x200

}

.=0x500

.data:{

*(.data)

.+=0x600

}

}

The‘.text’section will be assigned a starting address of 0x100 and a size of exactly 0x200

bytes,even if there is not enough data in the‘.text’input sections to fill this area.(If

there is too much data,an error will be produced because this would be an attempt to move

.backwards).The‘.data’section will start at 0x500 and it will have an extra 0x600 bytes

worth of space after the end of the values from the‘.data’input sections and before the

end of the‘.data’output section itself.

總結

以上是生活随笔為你收集整理的u-boot.lds详细的分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。