This text is based on memory_areas_on_boot.md from my GitHub repo riscv-notes
On boot the kernel has the following memory areas required for code execution
On boot the kernel has the following memory areas required for code execution
- vmlinux ELF code and data sections mapped by the bootloader
- the page tables for virtual memory support created by the bootloader
- initial stack
The pages used by the above regions must be marked as reserved so they are not used for memory allocations.
As shown here https://github.com/slavaim/riscv-notes/blob/master/linux/memory-initialization.md the kernel makes the following calls for memory reservation.
memblock_reserve(info.base, __pa(_end) - info.base);
reserve_boot_page_table(pfn_to_virt(csr_read(sptbr)));
The first call to
memblock_reserve is to reserve the area from &_start to &_end , this area is defined in the following linker script.SECTIONS
{
/* Beginning of code and text segment */
. = LOAD_OFFSET;
_start = .;
__init_begin = .;
HEAD_TEXT_SECTION
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
/* we have to discard exit text and such at runtime, not link time */
.exit.text :
{
EXIT_TEXT
}
.exit.data :
{
EXIT_DATA
}
PERCPU_SECTION(L1_CACHE_BYTES)
__init_end = .;
.text : {
_text = .;
_stext = .;
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
ENTRY_TEXT
IRQENTRY_TEXT
*(.fixup)
_etext = .;
}
/* Start of data section */
_sdata = .;
RO_DATA_SECTION(PAGE_SIZE)
RW_DATA_SECTION(0x40, PAGE_SIZE, THREAD_SIZE)
.sdata : {
_gp = . + 0x800;
*(.sdata*)
}
.srodata : {
*(.srodata*)
}
/* End of data section */
_edata = .;
BSS_SECTION(0x20, 0, 0x20)
EXCEPTION_TABLE(0x10)
NOTES
.rel.dyn : {
*(.rel.dyn*)
}
_end = .;
STABS_DEBUG
DWARF_DEBUG
DISCARDS
}
As you can see this area encompasses all kernel code and data excluding debug information. This area starts at
ffffffff80000000. You can easily find the start and end addresses from the System.map file. These values for my test kernel ffffffff80000000 T _start
ffffffff803b10b4 R _end
The second call to
Where is a stack reservation? The stack is reserved by the first call to
reserve_boot_page_table reserves the initial page table pages.Where is a stack reservation? The stack is reserved by the first call to
memblock_reserve as the initial stack is allocated from the kernel data section. The initial stack is staically allocated as init_thread_union.stack . The init_thread_union has the following type definition in linux/linux-4.6.2/include/linux/sched.hunion thread_union {
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
For my test kernel the address of the
init_thread_union is again extracted from System.map asffffffff8035e000 D init_thread_union
As you can see it is in the range of the region
The stack register is set on boot by the kernel entry routine
[&_start,&_end) and is in the data section.The stack register is set on boot by the kernel entry routine
_start defined in linux/linux-4.6.2/arch/riscv/kernel/head.S__INIT
ENTRY(_start)
...
/* Initialize stack pointer */
la sp, init_thread_union + THREAD_SIZE
/* Initialize current task_struct pointer */
la tp, init_task
...
END(_start)
No comments:
Post a Comment