Source: http://www.top-e.org/jiaoshi/class/
Generally, users do not need to care about the specific location of a section. In the user State, the kernel will parse the sections of the elf executable file and map it to the virtual address space. However, when the kernel is started, everything starts from scratch. Many applications in user mode do not need to worry about things. For example, the task of section ing a section must be completed by the kernel itself. Previous insights reveal how the kernel creates a page table and maps some of its own parts to virtual addresses. The kernel is also responsible for initializing BSS segments (all the global variables not defined in the Code) (set to 0 ), this requires the kernel to know the specific location of the Section (otherwise, how to know which part of the ing is required ?)
In addition, when page ing is enabled, I am most confused about how several constants (page Directory swapper_pg_dir, page table pg0, etc.) are determined. Extension. How does GCC determine the variable address when linking executable files? There should be some way (command line parameters or files) to tell the linker LD how to locate these variables. The most common example is Hello world. Why is the _ start address 0x80482e0? As a result, we need a file to specify the virtual address of each section. In the kernel source code, the file ARCH/i386/kernel/vmlinux. LDS. S is also displayed. It is not like a Common Assembly file. This is the linker scripts linker script.
In the linker script,. indicates the value of the current location counter address counter. The default value is 0.
017. = _ kernel_start;
Indicates that the address counter starts from _ kernel_start (0xc00100000.
. Text :{...}
Which sections are included in the. text section?
031. = align (16 );
It indicates the alignment mode.
For specific formats, call Info LD to view the linker scripts section.
The linker script specifies the start position and end position of each section. It also allows programmers to assign values to variables in scripts. This allows the kernel to get the start address and end address of the segment through variables such as _ initcall_start and _ initcall_end to operate on some segments.
Based on the linker script and the result of NM vmlinux, the virtual addresses of each section in the kernel are clear. Take my machine as an example (rough ):
Address Allocation
Text section:
From _ text: c0100000 A _ text
To _ etext: c0436573 A _ etext
Exception table
From _ start ___ ex_table: c0436580 A _ start ___ ex_table
To _ Stop ___ ex_table: c04370b8 A _ Stop ___ ex_table
Rodata read only section
. Data writable Section
. Data_nosave Section
From _ nosave_begin: c050f000 A _ nosave_begin
To _ nosave_end: c050f000 A _ nosave_end
. Data. page_aligned Section
. Data. cacheline_aligned Section
. Data. read_mostly Section
. Data. init_task Section
Init Section
From _ init_begin c0514000 A _ init_begin
To _ init_end c0540000 A _ init_end
Where. initcall. init section:
From _ initcall_start: c053b570 A _ initcall_start
To _ initcall_end: c053b8c0 A _ initcall_end
BSS section
From _ bss_start c0540000 A _ bss_start
To _ bss_end c0594c78 A _ bss_stop
Page table of the Swapper Process
From c0540000 B swapper_pg_dir
To c0541000
One page
Empty_zero_page
From c0541000 B empty_zero_page
To c0542000
One page
Pg0 page Directory 0
From c0595000 A pg0
To init_pg_tables_end
. Exitcall. Exit
Section
Stab Section
Several important sections:
BSS section, stores the uninitialized global variables in the code, and finally initializes the variable to 0.
Init sections, all functions and variables called only during initialization, including all functions called during kernel startup and functions called during kernel module initialization. The most special one is. initcall. init section. Through _ initcall_start and _ initcall_end, the kernel can call all functions in it. These sections can be released once, saving memory.