I have recently studied uboot, and the red part adds annotations to me.
Reprinted address:
Http://blog.chinaunix.net/space.php? Uid = 23373524 & Do = Blog & cuid = 2324182lds files are similar to scatter files, which determine the storage location and entry address of each segment of an executable program. This is also the function of link locating. Description of U-boot's lDs file: Sections {... secname start block (align) (noload): At (ldadr) {contents}> region: phdr = fill ...} secname and contents are mandatory. The former is used to name this segment, and the latter is used to determine what part of the code is placed in this segment. The following is an explanation of some keywords in this description. 1. secname: segment name 2. Contents: determines which content is placed in this segment. This can make the entire target file or a segment in the target file (code segment, data segment, etc) 3. Start: the Relocation Address of the segment. The Link (run) address of this segment. If there is a location-independent instruction in the code, this segment must be placed on this address when the program is running, start can be described by any symbol describing the address. 4. At (ldar): defines the address for storing (loading) This section. If this option is not used, the load address is equal to the run address. You can use this option to control different segments stored in the output file, for example,/* NAND. LDS */sections {first 0x00000000: {head. O init. o} second0 x 30000000: At (4096) {main. o} or above, head. O is placed at the beginning of 0x00000000 address, init. o put in head. O and the running address is 0x00000000, that is, the connection address is the same as the storage address (not specified at); main. O is placed at the beginning of 4096 (0x1000 is the storage address specified by at), but its running address is 0x30000000. Before running, it must start from 0x1000 (loading address) copy to 0x30000000 (run address). In this process, you need to read flash and copy the program to the corresponding location to run it. This is the difference between the storage address and the operation, called loading the time domain and running the time domain, which can be determined separately in the. LDS connection script file. Compiled. LDS file, which is called and executed with-tfilename when you use the arm-Linux-LD connection command, such as arm-Linux-LD-tnand. lds x. o y. o-o xy. o. You can also use the-ttext parameter to directly specify the connection address, for example, arm-Linux-LD-ttext 0x30000000 X. o y. o-o xy. O since the program has two types of addresses, it involves some jump commands.
The following part 1 and 2 can be viewed in the book of Wei Dongshan to see how to jump
1) B step: the B jump command is relative to the current Pc value, and the offset is calculated by the bit [] of the command, this makes the use of the B command not dependent on the position of the Code to jump to, just look at the Command itself. 2) ldr pc, = step; this command is a pseudo command that will generate the following code after compilation: ldr pc, 0x30008000 <0x30008000> step reads data from a location in the memory and assigns it to the PC. It also depends on the value of the current PC, however, the offset is the connection address (runtime address) of step, so you can use it to redirect from flash to ram. (3) In addition, it is necessary to repeat the ADR pseudocommand. The relocate code in U-boot is to use ADR to realize whether the current program is in Ram or in Flash: relocate: /* re-locate U-boot to Ram */ADR r0, and _ start R0 is the current position of the Code.
ADR command: ADR pseudocommand-small range of address reading
The ADR pseudocommand reads the address value based on PC relative offset or the address value based on register relative offset to the Register. When the compilation compiler compiles the source program, the ADR pseudocommand is replaced by an appropriate command by the compiler. Generally, the compiler uses an add or sub command to implement this ADR pseudocommand. If it cannot be implemented using one command, an error is generated and compilation fails.
ADR pseudocommand format: ADR {cond} register, expr
Value Range of the address expression expr:
When the address value is in byte alignment, the value ranges from + 255 ~ 255b;
When the address value is a word alignment, the value ranges from-1020 ~ 1020b;
It is calculated based on the PC address and relative offset address. For example, when it is executed in the On-chip RAM, the R0 value is 0x00000000, if it is loaded from flash to external SDRAM (assuming the cheap address is 0x3000 0000), then the R0 value is 0x3000 0000.
/* ADR pseudocommand. The assembler automatically calculates the value of "_ start" in this command based on the value of the current PC, and puts the value of PC to R0 when executing the command to start: when this segment is executed in flash, R0 = _ start = 0; when this segment is executed in Ram, _ start = _ text_base (in board/smdk2410/config. the value specified in Mk) is 0x33f80000, that is, the start of the code snippet that U-boot copied to Ram */LDR R1, _ text_base/* test whether to start from flash or from Ram. The result of executing this sentence R1 is always 0x33ff80000, because this value is linked to the specified */CMP r0, r1/* compare R0 and R1, do not perform relocation during debugging */output_format ("elf32-littlearm", "elf32-littlearm", "elf32-littlearm"); specify the ELF format of the output executable file, 32-bit arm instruction, small-end Mode
/* Output_format ("elf32-arm", "elf32-arm", "elf32-arm ")*/
Output_arch (ARM) specifies that the input platform is arm
Entry (_ start) specifies that the start code of the output executable file is _ start.
Sections
{
. = 0x00000000; the current address is 0. = align (4); the Code is aligned in four bytes.
. Text: Specifies the code segment.
{
The first code segment of the CPU/ARM920T/start. O (. Text) Code
* (. Text) Other code segments
}. = Align (4 );
. Rodata: {* (. rodata)} specifies the read-only data segment. = align (4 );
. Data: {* (. Data)} specifies the read/write data segment. = align (4 );
. Got :{*(. got)} specifies the got segment. The got segment is a custom segment of uboot, and the non-standard segment _ u_boot_cmd_start = .; the value is assigned to the current position, that is, the starting position.
. U_boot_cmd: {* (. u_boot_cmd)} u_boot_cmd segment. uboot puts all uboot commands in this segment.
_ U_boot_cmd_end =.; assign the value to the current position, that is, the end position. = align (4 );
_ Bss_start =.; assign _ bss_start to the current position, that is, the start position of the BSS segment.
. BSS: {* (. BSS)}; specifies the BSS segment
_ End =.; assign the _ end value to the current position, that is, the end position of the BSS segment.
} This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/catamout/archive/2010/02/08/5298449.aspx u-boot.lds file details
For. LDS files, the storage location and entry address of each segment of an executable program are determined, which is also the role of link locating. The following uses the U-boot lDs as an example to describe the uboot link process. First, let's take a look at the complete description of the. LDS file format on the GNU Official Website: Sections { ... Secname start block (align) (noload): At (ldadr) {Contents}> region: phdr = fill ... } Secname and contents are mandatory. The former is used to name this segment, and the latter is used to determine what part of the code is placed in this segment. The following is an explanation of some keywords in this description. 1. secname: segment name 2. Contents: determines which content is placed in this segment. It can be the entire target file or a segment in the target file (code segment, data segment, etc) 3. Start: the Relocation Address of the segment. The Link (run) address of this segment. If there is a location-independent instruction in the code, this segment must be placed on this address when the program is running. Start can be described by any symbol describing the address. 4. At (ldadr): defines the storage (loading) address of this segment. If this option is not used, the loading address is equal to the running address, you can use this option to control the locations where each segment is stored in the output file. Example: /* NAND. LDS */ Sections { Firtst 0x00000000: {head. O init. O} Second 0x30000000: At (4096) {main. O} }
The starting address of Main. O in the generated execution file is 4096. After 4 K, the S3C2440 can automatically load 4 K content from nanflash to the built-in Ram to run
Above, head. O is placed at the beginning of 0x00000000 address, init. o put in head. o, their running address is also 0x00000000, that is, the connection and storage address are the same (not specified at); main. O is placed at the beginning of 4096 (0x1000, which is the storage address specified by at), but its running address is 0x30000000, before running the program, you need to copy from 0x1000 (loading address) to 0x30000000 (running address). In this process, you also need to read the flash and copy the program to the corresponding position to run the program. This is the difference between the storage address and the operating address. It is called the loading time domain and the running time domain. It can be specified separately in the. LDS connection script file.
The compiled. LDS file is called and executed with-tfilename when you use the arm-Linux-LD connection command, as shown in figure Arm-Linux-lD? Tnand. lds x. o y. O? O xy. O. You can also use the-ttext parameter to directly specify the connection address, as shown in figure Arm-Linux-lD? Ttext 0x30000000 X. o y. O? O xy. O. Since the program has two types of addresses, it involves some jump commands. In arm assembly, there are two jump Methods: B jump command and LDR command assign value to PC. Pay special attention to the meanings of the two commands: (1) B step: the B jump command is relative to the current Pc value, and the offset is calculated by the bit [] of the command, this makes the program using the B command not dependent on the position of the Code to be jumped, only the instruction itself. (2) ldr pc, = step: this command is a pseudo command that will generate the following code after compilation: Ldr pc, 0x30008000 <0x30008000> Step It refers to reading data from a location (STEP) in the memory and assigning it to the PC. It also depends on the value of the current PC, but the offset is the connection address (runtime address) of the step ), so you can use it to redirect from flash to ram. (3) In addition, it is necessary to review the pseudocommands of ADR. The relocate code in U-boot is to use ADR to realize whether the current program is in Ram or flash: Relocate:/* relocate U-boot to Ram */ ADR r0, _ start/* R0 is the current position of the Code */ /* ADR pseudocommand. The assembler automatically calculates the value of "_ start" in this command based on the value of the current PC. The value of PC is placed in R0 when _ start is executed:
When this segment is executed in flash, R0 = _ start = 0; when this segment is executed in Ram, _ start = _ text_base (in board/smdk2410/config. the value specified in MK is 0x33f80000, that is, U-boot copies the code to the beginning of the code snippet executed in Ram )*/ LDR R1, _ text_base/* test whether it is started from flash or Ram */ /* The result of executing this sentence R1 is always 0x33ff80000, because this value is specified by the link */ CMP r0, R1/* compare R0 and R1. do not perform relocation during debugging */ Talk about the connection script in combination with the u-boot.lds.
Output_format ("elf32 & shy; littlearm", "elf32 & shy; littlearm", "elf32 & shy; littlearm ") ; Specifies that the output executable file is in the ELF format, 32-bit arm command, small-end Output_arch (ARM) ; Specify the platform for outputting executable files as arm Entry (_ start) ; Specifies the starting code segment of the output executable file as _ start. Sections
{ . = 0x00000000; locate the current address as 0 . = Align (4); the Code is 4 bytes aligned . Text:; specifies the code segment { CPU/ARM920T/start. O (. Text); the first part of the code * (. Text); Other code } . = Align (4) . Rodata: {* (. rodata)}; specifies the read-only data segment. . = Align (4 ); . Data: {* (. Data)}; specifies the read/write data segment. . = Align (4 );
. Got: {* (. Got)}; specifies the got segment. The got segment is a custom segment of uboot and is not a standard segment. _ U_boot_cmd_start =.; assign _ u_boot_cmd_start to the current position, that is, the start position. . U_boot_cmd: {* (. u_boot_cmd)}; specify the u_boot_cmd segment. uboot puts all uboot commands in this segment. _ U_boot_cmd_end =.; assign _ u_boot_end _end to the current position, that is, the end position. . = Align (4 ); _ Bss_start =.; assign _ bss_start to the current position, that is, the start position of the BSS segment. . BSS: {* (. BSS)}; specifies the BSS segment _ End =.; assign the value of _ end to the current position, that is, the end position of the BSS segment.
|