According to the Using ld doc:
The linker command language includes a command specifically for defining the first executable instruction in an output file (its entry point).
How to understand the first here? Is it logically the first instruction to jump to? Or it is physically the first instruction to place in the .text
section?
I use below linker script from here as experiment:
ENTRY(__entry) /* <=============== HERE, the __entry */
/*kernel will be loaded at this address after boot*/
INCLUDE linker.ld
SECTIONS
{
/*kernel will be compiled with virtual address base at 2GB*/
. = 0x80000000 + start_address; /*2GB + start_address = (0x80010000)*/
PROVIDE(_kernel_start = .); /*defined at kernel/include/kernel.h, set to 0x80010000*/
.text : AT(start_address)
{
*(.text)
}
.data :
{
*(.data)
}
.bss :
{
*(.bss COMMON)
}
. = ALIGN(8);
PROVIDE(_fb_start = .);
. += framebuffer_size;
PROVIDE(_kernel_end = .); /*defined at kernel/include/kernel.h*/
}
I tried to search for the instruction bytes at the __entry
in the final built binary. And found that those instructions are indeed located at the beginning of the .text
section.
So does it mean the ENTRY()
command always place the entry point at the beginning of the final binary's .text
section?
The first machine instruction in executable file means the instruction which is executed first. It doesn't have to be the first one (with the lowest offset) from the ordered list of all instructions in .text segment.
Many programs are written in natural top-down style and their entry indeed points to the physically first instruction (at offset zero). However program code may also start with helper subroutines and its entry point will be shifted deeper in code in this case.
The ENTRY(__entry)
will record the VMA location of the __entry
symbol in the final object file. For example, in ELF header. After the loader loads each section of the object file into the memory, the loader or runtime will just jump to the entry point.
But in my scenario, the ENTRY(__entry)
is actually not necessary. Because the EwokOS runs on bare machine and there's no loader. As I tried, if I commented out the ENTRY(__entry)
, the EwokOS still can boot on a bare metal.
The reason that the first instruction of __entry
happens to be the first instruction of the final EwokOS.bin
file, is a combination of two factors:
the input order of the object file to the linker ld
the coding order in the boot.S
file.
There are 3 files fed to ld
in the order of boot.o system.o context.o
. So we can see boot.o
is the first object file to link.
And the the boot.S
file, which assembles into the boot.o
contains the __entry
as the first line of code.
These 2 factors lead to the result that __entry
is at the beginning of the final EwokOS.bin
, whihc is extracted from the .text
section of the EwokOS.elf
.
And in my scenario, I need the __entry
to appear at the beginning of the EwokOS.bin
file because the bin file is loaded at the 0x10000 address, which is the start address of the QEMU ARM versatilepb virtual machine.
User contributions licensed under CC BY-SA 3.0