Linking kernel at 0xFFFF800000000000 (AMD64)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
dosfan
Member
Member
Posts: 65
Joined: Tue Oct 14, 2008 1:18 pm
Location: Scotland

Linking kernel at 0xFFFF800000000000 (AMD64)

Post by dosfan »

Hi

I've been working on a long mode kernel for a couple of weeks now. I use the a.out kludge to load a a 64bit ELF with GRUB. My 32bit stub makes it into long mode and reaches my C entry point no problem when linked at 0xFFFFFFFF80010000.

I can't seem to link at 0xFFFF800000010000!!. I've read a few moans on this forum about this but no real solution. Anyone know what causes this :

Code: Select all

arch/amd64/entry.o: In function `_multiboot':
(.text+0xc): relocation truncated to fit: R_X86_64_32 against `.text'
My linker script is as the 64bit kernel wiki page.

I'm using a x86_64-elf cross compiler on Cygwin I built myself. GCC 4.3.3.

The function its moaning about is actually the multiboot header for GRUB.
KERNEL_VMA = 0xFFFF800000000000

Code: Select all

_multiboot:
    .long 0x1BADB002
    .long 0x00010002
    .long  (0 - 0x1badb002 - 0x00010002)
    .long (_multiboot-KERNEL_VMA)
    .long (_code-KERNEL_VMA)
    .long (_data_end-KERNEL_VMA)
    .long (_end-KERNEL_VMA)
    .long (_entry-KERNEL_VMA)
Bearing in mind this all works fine when using the higher address........ :shock:
Cheers!
All your base are belong to us.
User avatar
AndreaOrru
Member
Member
Posts: 50
Joined: Fri Apr 25, 2008 2:50 pm
Location: New York

Re: Linking kernel at 0xFFFF800000000000 (AMD64)

Post by AndreaOrru »

Add -mcmodel=large to your CFLAGS.
Close the world, txEn eht nepO
dosfan
Member
Member
Posts: 65
Joined: Tue Oct 14, 2008 1:18 pm
Location: Scotland

Re: Linking kernel at 0xFFFF800000000000 (AMD64)

Post by dosfan »

Sorry should have included that. I already have -mcmodel=large in my CFLAGS.
All your base are belong to us.
whowhatwhere
Member
Member
Posts: 199
Joined: Sat Jun 28, 2008 6:44 pm

Re: Linking kernel at 0xFFFF800000000000 (AMD64)

Post by whowhatwhere »

I'm not sure as this is guessing, but I believe on amd64, ".long" gives the equivalent of a unsigned 32 bit integral value. When it gets thrown in with the VMA mod, I think the value + the offset is too large for the ".long" directive. When I had this problem, someone suggested using ".quad" however, that would just give an unsigned 64 bit integral value. The real issue is that the multiboot section must be placed at an absolute load address < 2GB for the compiler to "like" it.

Code: Select all

OUTPUT_FORMAT(elf64-x86-64)
ENTRY(kmain)
SECTIONS
{
    /* This should place the multiboot header just */
    /* about 32 bytes above the program headers. */
    .multiboot : AT(SIZEOF_HEADERS+32) {
        _multiboot = .;
        *(.multiboot)
        . = ALIGN(4096);
    }
    . = KERNEL_VMA;

    .text : AT(ADDR(.text) - KERNEL_VMA)
    {
        _code = .;
        *(.text)
        *(.rodata*)
        . = ALIGN(4096);
    }

   .data : AT(ADDR(.data) - KERNEL_VMA)
   {
        _data = .;
        *(.data)
        . = ALIGN(4096);
   }

   .ehframe : AT(ADDR(.ehframe) - KERNEL_VMA)
   {
       _ehframe = .;
       *(.ehframe)
        . = ALIGN(4096);
   }

   .bss : AT(ADDR(.bss) - KERNEL_VMA)
   {
       _bss = .;
       *(.bss)
       . = ALIGN(4096);
   }

   _end = .;

   /DISCARD/ :
   {
        *(.comment)
   }
}
I'm not sure if this will work, because it's been about a year since I did any serious OSDev work. I won't be held liable if it blows up your computer, causes black holes, causes space time inversions or eats pets or loved ones. (Other Disclaimer Here)
Post Reply