Thoughts on location-independent code (PIC)

Source: Internet
Author: User

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.

First, let's look at the following link script file:

Entry (_ start); specifies the starting code segment of the output executable file as _ start. sections {. = bootaddr; start address of bootloader /. = align (4); the Code is 4-byte aligned. text:; specifies the code segment {CPU/ARCH/start. O (. text); the text segment *(. text); other text segments }. = align (4 ). rodata :{*(. rodata)}; specifies the read-only data segment. = align (4 );. data :{*(. data)}; specifies the read/write data segment. = 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}

It should be noted that the output segment address described in the Link script is virtual address VMA (virtualmemoryaddress ). 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, it has nothing to do with the actual address (that is, the image loading address) written to the image file ). 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.

Suppose bootaddr = 0x0 is specified here. Taking arm as an example,

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, the final jump statement of the handling code can be written as an absolute address, such as JMP.
0x10000, so that you can jump to the 0x10000 address in Ram correctly. However, when the execution continues and another symbolic address calculation or global data access occurs, the Code is not location-independent, at this time, the address calculation needs to query the map table, but the address in the map table is still in the ROM space, so it will also jump back to the ROM space. In addition, there will be other problems, such as dynamic memory application.

With the location-independent code, you only need to modify the bootaddr = 0x10000 of the script file to map the entire image file to the ram space. However, the first code to be carried by bootloader must be location-independent code, in this way, although the transfer code is mapped to the RAM address space, it can also be correctly executed in the ROM starting with 0x0, and the final jump statement of the transfer code can jump to a certain number, because the address of the label has been mapped to the ram space, there will be no problem in subsequent code execution.

Of course, you can map the moving code to the ROM address space and other code to the ram space. However, there will be a problem: the generated binfile becomes very large. The generated binfile will be generated according to the ing to the address space. If the ROM space and the ram space address are not consecutive, assume that the ROM address space is 0x0 ~ 0x1000, the RAM address space is 0x10000 ~ 0x20000, so,
0x1000 ~ The address space between 0 x is filled with 0, unless it is re-assembled when the binfile is generated.

How do I write location-independent code?

When referencing symbols in irrelevant segments of the same position or in another irrelevant segment with a fixed relative position, it must be a PC-based symbol reference, that is, the offset relative to the current PC is used for jump or constant access.

1. Position-independent program jump. Use the relative jump command to redirect a 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.

2. 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.

3. Use an absolute address to jump. Generally, the jump is between segments irrelevant to different locations.

Finally, we will summarize the advantages of location-independent code segments:

1. Simplified Design to facilitate quick system guidance. Location-independent code can avoid address ing during boot and easily jump to ram for fast boot

2. Intelligent resetting. Location-independent code can be loaded to any address space for running.

3. Easy debugging. Bootloader debugging is also a complicated process. When location-independent code is used, the image file can be loaded into RAM for debugging, this not only reflects the system boot of the program from the Rom, but also avoids frequent program memory burning.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.