[SOLVED] 64-bit Higher Half relocation issues
Posted: Sun Oct 08, 2017 3:09 pm
Hi, I'm trying to get a 64-bit higher half kernel working, which has been somewhat challenging. I opted to go with a 32-bit bootstrap placed in the physical address space, in which I set up identity mapping and enter Long Mode, then set up real higher-half page tables and then jump into the higher-half. The relevant part of the bootstrap code is:
Entry64 is defined in another file (linked into the virtual address space with a base of 0xffffff0000100000):
This is all linked into one executable (with the bootstrap at 0x100000 and the rest of the kernel at 0xffffff0000100000) with:
However, it seems to emit the incorrect relocation to load the address of Entry64 (I don't understand why this doesn't output a R86_64_64 type relocation):
There also seem to be problems with Entry64:
What's causing these issues, and is this even a sensible approach to 64-bit higher half? I came across this thread and tried to find the NASM version of movabs without success, but I think it should've just loaded the 64-bit addresses correctly? Thank you in advance, and sorry if I've cluttered the post with too much code etc.
Code: Select all
extern Entry64
InLongMode:
; Reload every data segment with 0 (Long-mode doesn't use segmentation)
mov ax, 0
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; This sets up the higher half page tables
call MapHigherHalf
; Correct the address of the Multiboot structure
add rdi, 0xffffff0000000000
lea rax, [Entry64]
jmp rax
Code: Select all
bits 64
section .text
global Entry64
Entry64:
; Print OKAY
mov rax, 0x2f592f412f4b2f4f
mov qword [0xb8000], rax ; TODO: use proper virtual address (this would only work because the identity mapping is still also in place)
hlt
Code: Select all
KERNEL_LMA = 0x100000;
KERNEL_VMA = 0xffffff0000100000;
SECTIONS
{
/*
* First, we physically-map a bootstrap section that will load the 64-bit code. This is required
* because we haven't enabled paging yet, and so code that uses virtual addresses won't work.
*/
. = KERNEL_LMA;
.bootstrap.text :
{
KEEP(*(.multiboot))
*bootstrap.o (.text .text.*)
. = ALIGN(4K);
}
.bootstrap.bss :
{
*bootstrap.o (.bss)
. = ALIGN(4K);
}
.bootstrap.rodata :
{
*bootstrap.o (.rodata .rodata.*)
. = ALIGN(4K);
}
/*
* Then, we place everything else at proper virtual addresses
*/
. = KERNEL_VMA;
.rodata : AT(ADDR(.rodata) - KERNEL_VMA)
{
*(EXCLUDE_FILE(bootstrap.o) .rodata .rodata.*)
. = ALIGN(4K);
}
...
Code: Select all
relocation truncated to fit: R_X86_64_32S against symbol `Entry64' defined in .text section in /home/isaac/Documents/RustOS/build/x86_64/entry64.o
Code: Select all
entry64.s:11:(.stab+0x14): relocation truncated to fit: R_X86_64_32 against `.text'
entry64.s:11:(.stab+0x20): relocation truncated to fit: R_X86_64_32 against `.text'
entry64.s:12:(.stab+0x2c): relocation truncated to fit: R_X86_64_32 against `.text'
entry64.s:12:(.stab+0x38): relocation truncated to fit: R_X86_64_32 against `.text'