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:
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*/
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
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Application design of lighting terminal system based on GPRS module and Zigbee network
- APM32E103VET6 Review: Serial Port (USART1)
- What do you think about RF company Qorvo providing programmable power for smart home appliances?
- Design of SAW RFID system based on DSP device TMS320VC5509A chip
- Analysis of the "Signal" topic in the National College Student Electronics Contest
- I have just started learning Cadence Virtuoso and found that as long as the schematic diagram appears in the parallel inductor simulation, an error will be reported.
- How to use an oscilloscope to test the transient energy of a battery
- What frequency ESR should we choose for the output filter capacitor of a flyback power supply?
- ±0.1° Accurate Discrete Resolver Front-End Reference Design with C2000 Microcontroller
- Looking for a signal amplification design