Arm-linux-ld command-T option is an important option in the ld command. It can be used to directly specify the code segment, data segment, doctoral student, www.2cto.com segment. For complex connections, you can write a script specifically to tell the compiler how to connect. -Ttext addr-Tdata addr-Tbss addr arm-elf-ld-Ttext 0x00000000-g led_On.o-o led_on_elf, the running address is 0x00000000, because there is no data or bss, they will be followed by default. For different Ttext codes, you can compare the differences between them. ld automatically adjusts the jump address. * Simple Linker script (1) SECTIONS command: The SECTIONS command tells the linker how to map input sections into output sections, and how to place the output sections in memory. command syntax: SECTIONS {sections-command ......} specifically, the sections-command can be an ENTRY command, a symbolic value assignment, an output segment description, or an overlay description. (2) address counter '. '(location counter): This symbol can only be used inside the SECTIONS command. The initial value is '0'. You can assign values to this symbol, or use this symbol to calculate or assign values to other symbols. It automatically calculates the current address based on the size of the output segment described in the section command. (3) output section description (output section description): As mentioned above, the output section description can be used in the SECTIONS command. The format of the description is as follows: section [address] [(type)]: [AT (lma)] {output-section-command ...} [> region] [AT> lma_region] [: phdr...] [= fillexp] many additional options are not available. The output-section-command can also be a symbolic value assignment, the input segment description, the data value to be included directly, or a specific output segment keyword. * Linker script instance ================================ OUTPUT_ARCH (arm) ENTRY (_ start) SECTIONS {. = 0xa3f00000; _ boot_start = .;. start ALIGN (4 ):{*(. text. start )}. setup ALIGN (4): {setup_block = .; *(. setup) setup_block_end = .;}. text ALIGN (4 ):{*(. text )}. rodata ALIGN (4 ):{*(. rodata )}. data ALIGN (4 ):{*(. data )}. got ALIGN (4 ):{*(. got)} _ boot_end = .;. bss ALIGN (16): {bss_start = .; *(. Bss) * (COMMON) bss_end = .;}. comment ALIGN (16 ):{*(. comment)} stack_point = _ boot_start + 0x00100000; loader_size = _ boot_end-_ boot_start; setup_size = setup_block_end-setup_block ;} ============================================== in the SECTIONS command, similar to the following description structure is the output segment Description :. start ALIGN (4 ):{*(. text. start )}. start is output section name, ALIGN (4) returns a location-based counter (.) the 4-byte alignment address value. *(. Text. start) is the input segment description, * is a wildcard, which means to put all the linked object files. text. the start segment is linked to this. the output segment of start. The section and its attributes identified in the source file are actually descriptions of the input segment, for example. text. the start input segment is in the source file start. the code in S is as follows :. section. text. start. global _ start: B start arm-elf-ld-Ttimer. lds-o timer_elf header. o there must be a timer.. For the. lds file, it defines the connection process after the program is compiled, and determines the storage location of each segment of the executable program. Although I have not used it yet, it is very important to know about it. Let's take a look at the GNU official website. the complete description of the lds File Format: SECTIONS {... secname start BLOCK (align) (NOLOAD): AT (ldadr) {contents}> region: phdr = fill ...} secname and contents are mandatory, and others are optional. Here are a few common examples: 1. secname: segment name 2. contents: Determine which content is placed in this segment, which can be the entire target file, it can also be a segment in the target file (code segment, data segment, etc.) 3. start: the connection (run) address of this segment. If AT (ldadr) is not used ), the address stored in this section is also start. On the GNU website, start can be described using any type of address description symbol. 4. AT (ldadr): defines the address for storing (loading) This section. /* Nand. lds */SECTIONS {firtst 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, 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 specified by AT, the storage address), but its running address is 0x30000000. Before running, it must start from 0x1000 (loading location) copy to 0x30000000 (runtime), and read the Nand flash. This is the difference between the storage address and the connection (run) Address, known as loading the time domain and running the time domain, which 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, 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, such as arm-linux-ld? Ttext 0x30000000 x. o y. o? O xy. o. Since the program has two types of addresses, there are some differences between jump commands. Here we will write them down. If you forget them, you can check them. In the past, many things have not been written down, and now you forget them. In ARM assembly, there are two jump Methods: B jump command and ldr command assign value to PC. I have summarized as follows: B step1: The B jump command is a relative jump, depending on the current PC value, the offset is calculated by the bit of the command itself, this makes the program using the B command not dependent on the position of the Code to be jumped, only the instruction itself. Ldr pc, = step1: This command reads data from a location in the memory (step 1) and assigns it to the PC. It also depends on the value of the current PC, but the offset is the location (step 1) connection address (runtime address), so you can use it to redirect from Flash to RAM. In addition, it is necessary to repeat the adr pseudocommand. The relocate code in U-boot is used to realize whether the current program is in RAM or flash. I still used the comments of adr r0 at the time, and _ start/* r0 is the current position of the Code * // * adr pseudocommand, the assembler automatically calculates the value of the PC when it runs to _ start through the value of the current PC and puts it into r0: 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, ugg boots, _ TEXT_BASE/* test whether to start from Flash or RAM * // * the result of executing this sentence r1 is always 0x33FF80000, because this value is specified by the compiler (set in ads, or-D to set the compiler parameters) */cmp r0, r1/* compare r0 and r1, do not execute relocation during debugging */below, take a look at The formal connection script file. The basic functions of this file can be clearly understood. Although I have analyzed a lot above, the GNU-style symbols still confuse me. OUTPUT_FORMAT ("elf32 littlearm", "elf32 littlearm", "elf32 littlearm"); specify that the output executable file is in the elf format, 32-bit ARM command, small OUTPUT_ARCH (arm); specify the platform for outputting executable files as arm entry (_ start); specify the starting code segment of the output executable file as _ start. SECTIONS {. = 0x00000000; Starting from 0x0. = ALIGN (4); the Code is 4-byte 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)}; specified 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 = .; assign the value of _ u_boot_cmd_start to the current position, that is, the start position. u_boot_cmd :{*(. u_boot_cmd)}; specifies the u_boot_cmd segment. uboot places all uboot commands in this segment. _ u_boot_1__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)}; Specify bss segment _ end = .; assign the _ end value to the current position, that is, the end position of the bss segment.} from load address to runn Who will complete the loading process of ing address? Does bootloader (stage 1) Complete the loading process based on the corresponding address? Blog author's reply: Yes, you are very inspired to read your article. However, it is not clear that if the program contains only main. o so can I use the AT command to specify the loading segment as 4096, then what program will. o is stored in the memory 4096 instead of the memory 0? Is it a program written by burning? Blog author's reply: main. o will be placed in the bin from the beginning of the 4096 offset position (assuming the bin is connected by this lds), and then burn the entire bin into flash. S3C2410 Basic Experiment-Experiment 4: arm-linux-ld2009-04-29 20: 55 before starting the subsequent experiment, we have to understand the use of arm-linux-ld connection command. In the above experiment, we have been using commands similar to the following to connect: arm-linux-ld-Ttext 0x00000000 crt0.o led_on_c.o-o led_on_c_tmp.o. Let's see what it means: -o option: Set the name of the output file to led_on_c_tmp.o; "-- Ttext 0x00000000": Set the starting address of the code segment to 0x00000000; this command is used to connect crt0.o and led_on_c.o to the led_on_c_mp.o executable file. The starting address of the code segment of this executable file is 0x00000000. We are interested in the "-Ttext" option! Enter the LINK directory. the s Code is as follows: 1. text 2. global _ start 3 _ start: 4 B step1 5 step1: 6 ldr pc, = step2 7 step2: 8 B step2 Makefile: 1 link: link. s 2 arm-linux-gcc-c-o link. o link. s 3 arm-linux-ld-Ttext 0x00000000 link. o-o link_tmp.o 4 # arm-linux-ld-Ttext 0x30000000 link. o-o link_tmp.o 5 arm-linux-objcopy-O binary-S link_tmp.o link 6 arm-linux-objdump-D-B binary-m arm link> ttt. s 7 # arm-linux-obj Dump-D-B binary-m arm link> ttt2.s 8 clean: 9 rm-f link 10 rm-f link. o 11 rm-f link_tmp.o tutorial steps: 1. go to the LINK directory and run make to generate the disassembly code ttt with the arm-linux-ld option "-Ttext 0x00000000. s 2. make clean 3. modify Makefile: Remove "#" in rows 4th and 7, and add "#" 4 before rows 3rd and 6. run make to generate the disassembly code ttt2.s link with the arm-linux-ld option "-Ttext 0x30000000. two jump methods are used in the s program: B jump command and direct assignment to the pc register. We first list the disassembly codes of the executable files generated under different "-Ttext" options, and then analyze the differences between the two commands in detail. Ttt. s: ttt2.s 0: eaffffff B 0x4 0: eaffffff B 0x4 4: e59ff000 ldr pc, [pc, #0]; 0xc 4: e59ff000 ldr pc, [pc, #0]; 0xc 8: eafffffe B 0x8 8: eafffffe B 0x8 c: 00000008 andeq r0, r0, r8 c: 30000008 tsteq r0, #8; 0x8 first look at B jump command: it is a relative jump command, its machine code format is as follows: Cond 1 0 1 L Offset [31: 28] bit is a condition code; [27:24] When the bit is "1010", it indicates the B jump command. If it is "1011", it indicates the BL jump command; [] indicates the offset address. When B or BL is used for redirection, the address of the next command is calculated as follows: the number of 24-Bit Signed completion codes in the command is expanded to 32 (its symbol bit is extended ); remove the 32-digit value to the left and add the value to the pc register to obtain the jump destination address. Let's take a look at the machine code eaffffff of the First Command "B step1": 1. the 24-Bit Signed complement code is 0 xffffff, which is extended to 32 to get: 0 xffffffff 2. after moving the 32-digit value to the left, the result is: 0 xfffffc; the value is-4 3. the pc value is the address of the next two commands of the current command, plus-4 from step 2, this is exactly the address of step 1 in the Second instruction. You should not be confused by the "B 0x4" in the disassembly code. It does not mean to jump to the absolute address 0x4 for execution, the absolute address is calculated as in the preceding three steps. You can see that the B jump command depends on the value of the current pc register, this feature makes the program using the B command not dependent on the location where the code is stored-that is, it can run correctly regardless of the "-- Ttext" in the connection command. Look at the second command ldr pc, = step2: From the disassembly code "ldr pc, [pc, #0]", we can see that this command reads data from a location in the memory, and assign it to the pc register. The address at this position is the value of the current pc register plus the offset value 0, where the stored value depends on the "-- Ttext" option in the connection command. After this command is executed, for ttt. s, pc = 0x00000008; For ttt2.s, pc = 0x30000008. Therefore, when the Third Command "B step2" is executed, its absolute address is different: For ttt. s. The absolute address is 0x00000008. For ttt2.s, the absolute address is 0x30000008. The storage location of ttt2.s after power-on is also 0, but its connection address is 0x30000000. We will often use the feature "Different Storage addresses and connection addresses" (referred to as loading time domains and running time domains) in the future: Most machines run from address 0 when power-on, however, there are always many performance limitations in running a program from address 0. Therefore, at the beginning, the program itself is copied to its connection address using a location-independent command, then, use the method assigned to the pc register to jump to the memory starting from the connection address and execute the remaining code. In experiments 5 and 6, we will introduce them further. In the arm-linux-ld command, the option "-Ttext" can also be replaced by the option "-Tfilexxx". In the file filexxx, we can write more complex parameters to use the arm-linux-ld command-in Experiment 6, we use this method to specify the connection parameters.