S3c2440 code relocation details 5---code relocation and position-independent code

Publisher:星空行者Latest update time:2021-10-20 Source: eefocusKeywords:S3c2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

A program consists of a code segment, a read-only data segment, a data segment, a bss segment, etc.


The program can be burned on Nor Flash at the beginning, and the code segment can still run on Nor Flash at runtime, but for the data segment, the data segment must be moved to SDRAM, because only in SDRAM can the variables of the data segment be written. The process of moving the program from one location to another is called relocation.


First, let's sort out the technical details required to copy the entire program to SDRAM:


Copy the program from Flash to the runtime address. In the link script, specify the runtime address (Runtime addr) as the SDRAM address.

The bin file generated by the compilation and linking needs to be run on the SDRAM address, but after power-on it must first be run at address 0, which requires that the code before relocation is position-independent (it is written in position-independent code);

Refer to Uboot to modify the link script:

SECTIONS

{

    . = 0x30000000;


    . = ALIGN(4);

    .text :

    {

      *(.text)

    }


    . = ALIGN(4);

    .rodata : { *(.rodata) }


    . = ALIGN(4);

    .data : { *(.data) }


    . = ALIGN(4);

    __bss_start = .;

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

    _end = .;

}


The link script we are writing now is called an integrated link script. The difference between it and the previous split link script is whether the storage locations of the code segment and the data segment are separated.


For example, the code segment of the current integrated linker script is followed by the read-only data segment, data segment, and bss segment, which are all continuous.


The split link script consists of a code segment and a read-only data segment, with the data segment and bss segment being far behind.

Our future codes will use more integrated linker scripts for the following reasons:


The split link script is suitable for single-chip microcomputers, which have built-in flash, so there is no need to copy the code to the memory to occupy space. However, our embedded system has a very large memory, so there is no need to save this space. In addition, some embedded systems do not have flash such as Nor Flash that can run the code directly, so it is necessary to copy the entire code from Nand Flash or SD card to the memory;

Debuggers such as JTAG generally only support all-in-one link scripts;

Modify the start.S section


    /* Relocate the entire program in text, rodata, and data segments*/

    mov r1, #0

    ldr r2, =_start /* The address when the first instruction is executed*/

    ldr r3, =__bss_start /* Starting address of bss segment*/


cpy:

    ldr r4, [r1]

    str r4, [r2]

    add r1, r1, #4

    add r2, r2, #4

    cmp r2, r3

    ble cpy



    /* Clear BSS segment */

    ldr r1, =__bss_start

    ldr r2, =_end

    mov r3, #0

clean:

    str r3, [r1]

    add r1, r1, #4

    cmp r1, r2

    ble clean


    bl main  


halt:

    b halt


Recompile and burn the modified code into Nor Flash, and then power on and run it.

Analyze the startup of this code:

insert image description here

In the generated bin file, the code is saved at 0x30000000. Then it is burned to address 0 of NOR Flash, but the structure of the code does not change. Then it is relocated to SDRAM.


View the disassembly:


3000005c:eb000106 bl 30000478  


30000060: e3a01000 mov r1, #0 ; 0x0

30000064: e59f204c ldr r2, [pc, #76] ; 300000b8 <.text+0xb8>

30000068: e59f304c ldr r3, [pc, #76] ; 300000bc <.text+0xbc>


Here, bl 30000478 does not jump to 30000478, because sdram is not initialized at this time;

To verify, we do another experiment, modify the connection script sdram.lds, change the link address to 0x32000478, compile, and view the disassembly:


3000005c:eb000106 bl 30000478  


30000060: e3a01000 mov r1, #0 ; 0x0

30000064: e59f204c ldr r2, [pc, #76] ; 300000b8 <.text+0xb8>

30000068: e59f304c ldr r3, [pc, #76] ; 300000bc <.text+0xbc>


You can see that it has now become bl 30000478, but the machine codes eb000106 of the two are the same. If the machine codes are the same, the execution content must be the same.

So here it does not jump to the displayed address, but jumps to: pc + offset, which is determined by the linker.


Assuming the program is executed from 0x30000000, the current instruction address is: 0x3000005c, then it jumps to 0x30000478; if the program runs from 0, the current instruction address: 0x5c is transferred to: 0x00000478


Jumping to a certain address is not determined by the bl instruction, but by the current pc value. The disassembly shows this value only for the convenience of reading the code.


Key points:

In the disassembled file, the value of B or BL is just for the convenience of viewing and does not really jump.


How to write position-independent code?


1. Use the relative jump command b or bl;

2. Before relocation, you cannot use absolute addresses, access global variables/static variables, or access arrays with initial values ​​(because the initial values ​​are placed in rodata and are accessed using absolute addresses);

3. After relocation, use ldr pc = xxx to jump to the /runtime address;


Writing position-independent code actually means not using absolute addresses. In addition to the previous rules, the most fundamental way to determine whether absolute addresses are used is to look at the disassembly.


Therefore, the previous example program uses the bl command to jump relatively, and the program is still executed in NOR/sram. If you want the main function to execute in SDRAM, you need to modify the code


 //bl main /*bl relative jump, the program is still executed in NOR/sram*/

 ldr pc, =main/*absolute jump, jump to SDRAM*/

Keywords:S3c2440 Reference address:S3c2440 code relocation details 5---code relocation and position-independent code

Previous article:S3c2440 code relocation details 4 --- copy code and link script improvements
Next article:S3c2440 code relocation details 6---Relocation and clearing of BSS segment C function implementation

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号