OSDev.org https://forum.osdev.org/ |
|
[SOLVED] 64-bit Higher Half relocation issues https://forum.osdev.org/viewtopic.php?f=1&t=32475 |
Page 1 of 1 |
Author: | isaacwoods [ Sun Oct 08, 2017 3:09 pm ] |
Post subject: | [SOLVED] 64-bit Higher Half relocation issues |
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: Code: 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 Entry64 is defined in another file (linked into the virtual address space with a base of 0xffffff0000100000): Code: 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 This is all linked into one executable (with the bootstrap at 0x100000 and the rest of the kernel at 0xffffff0000100000) with: Code: 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); } ... 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): Code: 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 There also seem to be problems with Entry64: Code: 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' 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. |
Author: | Korona [ Sun Oct 08, 2017 3:41 pm ] |
Post subject: | Re: 64-bit Higher Half relocation issues |
Code: entry64.s:11:(.stab+0x14): relocation truncated to fit: R_X86_64_32 against `.text' means that the linker cannot satisfy a relocation that has an offset larger than 4 GiB. In 64-bit code things like loads from memory and jumps/calls are still limited to 4 GiB. As the address space is much larger, instead of 32-bit absolute offsets RIP-relative offsets are used. If you want absolute 64-bit addressing, you need to load the address into a register first (using movabs). The offending code is Code: lea rax, [Entry64] Use Code: movabs rax, Entry64 instead. (I'm not sure if your assembler uses the mov mnenomic for the movabs instruction but considering that your code does assemble with 64-bit mov instructions, I guess it does.) |
Author: | isaacwoods [ Sun Oct 08, 2017 4:05 pm ] |
Post subject: | Re: 64-bit Higher Half relocation issues |
Okay, so NASM doesn't provide movabs, but I've replaced the Code: lea rax, [Entry64] with: Code: mov rax, qword Entry64 which seems to disassemble to (obviously it won't be clear whether this actually does the relocation correctly until the link succeeds): Code: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0x0 However, I still have problems. This hasn't got rid of the relocation problems in Entry64, nor has it produced correct code for this (with or without the 'qword'): Code: add rdi, qword 0xffffff0000000000 turns into: Code: 48 83 c7 00 add rdi, 0x0 The 0x48 prefix leads me to think its worked out it needs to produce 64-bit code, but then it only emits a 1-byte immediate! |
Author: | Korona [ Sun Oct 08, 2017 4:46 pm ] |
Post subject: | Re: 64-bit Higher Half relocation issues |
There is no "add r/m64, imm64". movabs is the only instruction that takes a 64-bit immediate value. So load the value into a register first and then add it. |
Author: | Octocontrabass [ Sun Oct 08, 2017 6:39 pm ] |
Post subject: | Re: 64-bit Higher Half relocation issues |
BaconWraith wrote: What's causing these issues, and is this even a sensible approach to 64-bit higher half? Most instructions can only use 32-bit immediates and offsets, even though you're in 64-bit mode. The only instruction that can use a 64-bit immediate or offset is MOV. (AT&T syntax calls this "movabs".) Most developers choose a kernel base address around -2GB (0xFFFFFFFF80000000) so kernel symbols can use R_X86_64_32S relocations. This choice also gives the most freedom to user-mode software, since the lowest 2GB of address space may use both R_X86_64_32 and R_X86_64_32S relocations. BaconWraith wrote: 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? The NASM equivalent of movabs looks like this: Code: mov <r64>, qword <symbol>
mov al/ax/eax/rax, [qword <symbol>] mov [qword <symbol>], al/ax/eax/rax |
Author: | isaacwoods [ Tue Oct 10, 2017 11:41 am ] |
Post subject: | Re: 64-bit Higher Half relocation issues |
Thank you both for your replies! I've read up a little on that and probably should've known that I needed to use mov to load 64-bit immediates . I've moved the kernel base to 0xffffffff80000000, but this doesn't get rid of the .stab relocation truncations. Looking into it, .stab seems to be a obsolete debug symbol format, so I tried making NASM use DWARF with -Fdwarf and this seems to fix the relocation issues with that. Of course, it still doesn't work, but I'll try to figure out that on my own! Thank you very much again for your help and advice, and sorry for it being such a simple set of fixes |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |