The Higher Half Tutorial relocates the actual kernel code to the virtual address 0xC0000000. I would like to achieve the same but without the need for repeated subtraction of the virtual address within the bootsrap-code. If I understood it correctly, unless explicitly specified, the linker usually assumes the load address of the individual sections to be the same as their virtual memory addresses. To provide the information to the linker that the virtual address differs from the load address one can use the optional macro: AT(lma). (Note: lma stands for load memory address).
I have tried to do just that within my linker script. Although the linker correctly placed the specified section .kern to the virtual address 0xC0000000, it failes to load the actual function within this section annotated as .kerntext to the virtual address. Hence after page table initialization the code tries to jump to a function that has not been loaded by the linker.
In the following, you can find my linker script:
Code: Select all
ENTRY(_start)
SECTIONS
{
. = 0x00100000;
.text ALIGN(0x1000) :
{
*(.multiboot)
*(.text)
*(.gnu.linkonce.t*)
}
.rodata ALIGN(0x1000) :
{
PROVIDE (_srodata = .);
start_ctors = .;
*(SORT(.ctors*))
end_ctors = .;
start_dtors = .;
*(SORT(.dtors*))
end_dtors = .;
*(.rodata*)
*(.gnu.linkonce.r*)
PROVIDE (_erodata = .);
}
.data ALIGN(0x1000) :
{
PROVIDE (_sdata = .);
*(.data*)
*(.gnu.linkonce.d*)
PROVIDE (_edata = .);
}
.bss :
{
PROVIDE (_sbss = .);
*(COMMON)
*(.bss)
*(.bootstrap_stack)
/* *(.gdt_area)*/
*(.gnu.linkonce.b*)
PROVIDE (_ebss = .);
}
. = 0xC0000000 + 0x100000;
/* the following section .kern is at the virtual address 0xC0100000 */
.kern ALIGN(0x1000) : AT(ADDR(.kern) - (0xC0000000)) {
PROVIDE (_skern = .);
*(.kerntext)
PROVIDE (_ekern = .);
}
/DISCARD/ :
{
*(.note)
*(.comment)
/* *(.eh_frame) */ /* discard this, unless you are implementing runtime support for C++ exceptions. */
}
}
Thank you very much in advance.
Best regards.