Http://www.mcuol.com/tech/107/26052.htm
Introduction
Location-Based independenceCodePIC (positionindependent code)ProgramThe design plays an important role in the development of embedded application systems.
Development of bootloader programs and kernel initialization design, especially in bare metal environments. Location-independent programming methods can also be used in specific applications to build highly efficient dynamic link libraries, therefore, it is helpful for developers to design simple and clear applications by thoroughly understanding and mastering location-independent programming methods. This article first introduces the basic concepts and implementation principles of location-independent code, then describes the program design method and implementation process based on ARM Assembly location-independent, and finally takes the bootloader program design as an example, this article introduces the functions of position-independent programming in bootloader programming.
1. Location-independent code and Programming Method
1.1 Basic concepts and implementation principles
The application must be compiled, compiled, and linked before it becomes an executable file. During the link, all target files must be relocated to create a symbolic reference rule, at the same time, allocate the run address for variables and functions. When a program is executed, the system must load the code to the address space specified during the link to ensure that the program correctly references symbols such as variables and functions during execution so that the program can run normally. In a system with an operating system, the relocation process is automatically completed by the operating system.
When designing the bootloader program, it must be carried out in a bare-metal environment. In this case, the operating address of the bootloader image file must be set by the programmer. In general, the bootloader program is downloaded to the 0x0 address of the RoM for startup. In most application systems, the bootloader program is copied to the SDRAM for quick start and then run. Generally, the addresses of the two are not the same. The address relocation process of the program in SDRAM must be completed by the programmer. In fact, because bootloader is the first program to be executed after the system is powered on, the copy of the bootloader program and all previous work must be completed by itself, these commands are executed in Rom. That is to say, these codes can be correctly executed even if they are not in the runtime address space specified during the link. This is the location-independent code, which is a special code that can be normally executed when loaded to any address space.
Location-independent code is often used in the following scenarios:
The program is dynamically loaded to the memory during running;
The program is combined with different programs in different scenarios and loaded into the memory (such as a shared dynamic link library );
Ing between different addresses during running (such as the bootloader program ).
Although the-FPIC option is used to generate location-independent code for the C language during GCC compilation, this does not fix the location-related defects inherent in the program design. In particular, the assembly language code must be followed by certain program design principles by programmers to ensure the independence of the program's position.
Key points of the 1.2 ARM processor location-independent Program Design
The location-independent Executable File pie (positionindependent executable) of the arm program consists of the Location-independent code PIC and the location-independent data PID (positionindependent data.
PID is mainly used for read/write data segments (. data segments), where the global variables with initial values are saved. To achieve its location independence, register R9 is usually used as the static base address register to point it to the first address of the read/write segment, and uses the offset relative to the base register to address the variables in this segment. This method is often used to generate multiple independent data segments for multiple instances of the reentrant program. In program design, it is generally unnecessary to consider the location independence of the read/write segments. This is mainly because the read/write data is mainly allocated in SDRAM.
PIC includes code in the program and read-only data (. text Segment). To ensure that the program can run correctly in ROM and SDRAM space (for example, the bootloader program in bare metal state), the position-independent code program must be used. The following describes the key points of the PIC program design.
PIC complies with the program design specifications of the atpcs (armthumb procedure call standard) of the read-only segment location-independent ropi (readonly position independence:
(1) Program Design Specifications
When referencing the symbols in the same ropi segment or another ropi segment with a fixed position, it must be a PC-based symbolic reference, that is, using the offset relative to the current PC to achieve jump or constant access.
① Position-independent program jump. In the arm assembler, use the relative redirect command B/BL to redirect the program. The destination address to jump to in the command is expressed based on the offset of the current PC. It has nothing to do with the absolute address value assigned to the address label at the link time. Therefore, the code can jump anywhere, achieves location independence.
In addition, you can use the ADR or adrl pseudocommand to read the address label value to the PC for program jump. This is because pseudocommands such as ADR or adrl will be replaced by the compiler to operate on PC-based address values, but the range of addresses that can be read in this way is small, the address value may vary depending on whether the word is aligned. However, in the arm program, LDR and other commands are used to directly read the address label value to the PC, so that the program jump is not location-independent. For example:
Ldrpc, = Main
The result of compilation of the preceding LDR Assembly pseudo commands is:
Ldrpc, [PC, offset_to_lpool]
Lpooldcd main
It can be seen that, although LDR loads the content of a PC-based storage unit lpool to the PC, the storage unit stores the absolute address of the main function entry determined by the link, therefore, the actual section of the main function is not irrelevant to the position.
② Location-independent constant access. In applications, it is often necessary to read and write registers to complete necessary hardware initialization. To enhance the readability of the program, values are assigned to some constants using the equ pseudo command. However, location independence must be achieved during access. The following describes the location-independent constant access method through gpio initialization of PXA270.
It can be seen that the LDR pseudo command uses the PC-based offset to reference the symbol constants gpio_base and init_gpdr0, and thus is location independent. The following conclusions can be drawn: using the LDR pseudo command to read a constant to other general registers outside the PC can achieve location-independent constant access; however, when an address value is read to the PC for program jump, the jump target is location-related.
(2) programming Specification 2
Other code referenced by the ropi segment must be an absolute address or writable Data Based on the static base address register of the rwpi segment.
With an absolute address, you can only reference the symbols in a code segment that has been relocated to a specific position. By introducing an absolute address in a location-independent code, you can redirect the program to a specified position. For example, if Phase 1 of the bootloader copies its own code to the SDRAM address space specified when it is linked, you can use the command "ldrpc, = main "jump to the main function entry address of the program in SDRAM to start execution. This is because the program assigns an absolute address to the main function during link compilation. The system directly assigns the absolute address of the main function to the PC to redirect the program. If the relative redirect command "bmain" is used, only the main function entry inside the boot Rom is redirected.
2 Application of location-independent code in bootloader Design
When developing bootloader using the GNU tool, the program uses a link script (linker script) to set the memory ing of the image file. A simple link script structure is as follows:
The link script syntax is not introduced here. It should be noted that the output segment address described in the Link script is virtual memory address ). The "virtual address" here only refers to the migration of each output segment to the corresponding storage address space when the image file is executed, which is irrelevant to memory management. Therefore, the above link script actually specifies that when the bootloader image is executed, it will be relocated to the bucket starting with bootaddr to ensure correct reference of the symbol at the relevant location, make the program run normally.
After the ARM processor is reset, it always obtains 1st commands from the 0x0 address. Therefore, you only need to set bootaddr to 0, then, download the compiled executable binary file to the bucket starting from the 0x0 address of the RoM, and the program can boot normally. However, once the specified image file starts from the 0x0 address at the link, the bootloader can only run in the ROM space starting from 0x0, but cannot copy to the SDRAM space for quick boot. Of course, for PXA270 and other microprocessor with MMU functions, although we can first copy the entire bootloader image to the SDRAM, and then use the MMU function to map the SDRAM space to the 0x0 address, in addition, it will continue to run in the SDRAM. However, this will complicate the design and implementation of the bootloader, and in some applications that must block the MMU function (for example, guide the armlinux system ), MMU cannot be used for address re ing.
ARM-based location-independent programming can solve the above problems. You only need to set bootaddr to the address of the SDRAM space when connecting the program (generally, the highest 1 MB storage space in the SDRAM is used as the starting address ), in this way, after the ARM processor is powered on and reset, bootloader can still start from the address 0 and copy itself to the specified _ boot_start startup SDRAM for running. The startup code architecture of the link script that implements the above functions is as follows:
The program entry is _ start, indicating that the reset is abnormal. All other exception vectors are implemented using the relative jump command B to ensure location independence. After completing the basic hardware initialization, use the link script to pass the _ boot_start and _ boot_end parameters to copy the entire bootloader image to the specified SDRAM space and clear it. BSS segment. After the stack is initialized, the program assigns the absolute address of the main function entry to the PC, and then jumps to the SDRAM to continue running. Before the program jumps to the main function, all the code runs in the Rom. Therefore, the Code Location independence must be ensured. Therefore, when you call a subroutine such as initializing gpio, storage system, and stack, all are completed using relative jump commands.
Position-independent design of the bootloader program has the following advantages:
① Simplified design to facilitate quick system guidance. Location-independent code can avoid address ing during boot and easily jump to the SDRAM for fast boot.
② Achieve intelligent resetting. Because location-independent code can be loaded to any address space for running, the current address during running is not necessarily the same as the address assigned during the link. With this feature, you can add the following code in the reset handler to enable the processor to enter the SVC mode and disable the interrupt, so that different reset processes can be performed based on the current runtime address:
The _ start address read by the ADR command in the above Code is determined by the instruction execution address. If bootloader is started from SDRAM, the above comparison results are equal, and the program will directly jump to the clear_bss label address for execution, which can avoid the re-initialization of the storage system and the copy process of bootloader; if the program is started from Rom during power-on or hardware reset, the program will perform a full reset operation including system initialization and bootloader copying without the above comparison results.
③ Easy debugging. Bootloader debugging is also a complicated process. When location-independent code is used, the image file can be loaded into the SDRAM for debugging, this not only reflects the system boot of the program from the Rom, but also avoids frequent program memory burning.
3 conclusion
The location-independent program design described in this article is implemented through the symbol reference specification based on PC or base register. This method is widely used in actual system development. It can be used for guiding program design, development of general applications or embedded shared libraries. Introducing location-independent code in the design of bootloader can make the program structure simpler and clearer, and avoid address re ing and fast system guidance from SDRAM; the design method unrelated to the reference position makes the reset processing function of bootloader more flexible, and achieves the same effect for program debugging in SDRAM and in Rom.
References
[1] du chunlei. Arm architecture and programming [M]. Beijing: Tsinghua University Press, 2003.
[2] Chen wenzhi. Embedded system development principles and practices [M]. Beijing: Tsinghua University Press, 2005.
[3] arm limited. Arm Architecture Reference Manual. 2nd ed, 2000.
[4] arm limited. Ads developer guide. Release 1.2, 200111.
[5] arm limited. Ads explorer guide. Release 1.2, 200111.
[6] Red Hat Inc. Using lD, the GNU linker. Version 2.14.