Page 1 of 1

Booting a 64bit kernel

Posted: Wed Dec 24, 2008 3:14 am
by giszo
Hi!

Today I just tried to create a 64bit kernel executable and load it with GRUB. I followed the method described by AlexExtreme here: post

Here is how my multiboot header looks:

Code: Select all

.section .multiboot_header

multiboot_header:
.long MB_HEADER_MAGIC /* magic */
.long ( MB_FLAG_ALIGN_MODULES | MB_FLAG_MEMORY_INFO | (1<<16) ) /* flags */
.long -( MB_HEADER_MAGIC + ( MB_FLAG_ALIGN_MODULES | MB_FLAG_MEMORY_INFO | (1<<16) ) ) /* checksum */
.long multiboot_header
.long __text_start
.long __data_end
.long __kernel_end
.long _start
My linker script is the following:

Code: Select all

OUTPUT_FORMAT("elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)

ENTRY(_start)

SECTIONS {
    . = 0x100000;
    __text_start = .;
    .text : {
        *(.multiboot_header);
        *(.text);
    }
    .data : {
        . = ALIGN(0x1000);
        *(.data);
    }
    __data_end = .;
    .bss : {
        . = ALIGN(0x1000);
        *(.bss);
    }
    . = ALIGN(0x1000);
    __kernel_end = .;
}
And I compile the source files with the following GCC cmd line parameters:

Code: Select all

-m64 -Wall -nostdinc -nostdlib -fno-builtin
After linking the object files together with the linker script to a kernel binary when I try to load it with grub (from a CD with stage2_eltorito) I got a message saying that my kernel is "invalid or unsupported executable format".

As I saw in the above linked thread this method works for others so I think I'm doing something wrong. If you have an idea what could be wrong please tell me :)

Thanks,
giszo

Re: Booting a 64bit kernel

Posted: Sun Dec 28, 2008 11:29 pm
by JohnnyTheDon
GRUB won't load 64-bit elf files. It also doesn't put your kernel in long mode. To load 64-bit elfs, you need to use GRUB 2 (I don't recommend it) or load the kernel as a module and make a separate multiboot file with 32-bit to 64-bit bootstrap code. You will still need to write code to get to long mode from protected mode either way.

From the wiki: http://wiki.osdev.org/Creating_a_64-bit_kernel

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 2:55 am
by Love4Boobies
It's on the next version of the Multiboot spec's TODO list and that can also be seen in the draft.

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 3:13 am
by xyzzy
Well obviously it can load ELF64 files because I've been doing it for months ;)

giszo: What version of GRUB are you using? Try using the latest GRUB legacy SVN revision. There was a change to the booting code after the 0.97 release that makes sure the a.out kludge is used if supplied in the multiboot header, even if the image is an ELF file. I think this is necessary for my method to work (as I use the a.out kludge to specify where to load things).

Yes, I know I said on my original post it didn't require any GRUB patches, but AFAIK a lot of distros patch GRUB up to a newer SVN so I didn't realize this change was needed.

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 3:46 am
by giszo
AlexExtreme wrote:giszo: What version of GRUB are you using? Try using the latest GRUB legacy SVN revision. There was a change to the booting code after the 0.97 release that makes sure the a.out kludge is used if supplied in the multiboot header, even if the image is an ELF file. I think this is necessary for my method to work (as I use the a.out kludge to specify where to load things).
Thanks for the info, I used 0.97. I'll checkout the latest version from SVN and I hope it will work ;)

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 4:18 am
by giszo
I just compiled a latest GRUB stage2_eltorito from the SVN. Unfortunately the boot results are the same as before.

Do you have any other idea what could be wrong, AlexExtreme?

giszo

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 8:09 am
by xyzzy
In your linker script, try replacing:

Code: Select all

    . = 0x100000;
with

Code: Select all

    . = 0x100000 + SIZEOF_HEADERS;

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 8:21 am
by giszo
AlexExtreme wrote:In your linker script, try replacing:

Code: Select all

    . = 0x100000;
with

Code: Select all

    . = 0x100000 + SIZEOF_HEADERS;
The results are still the same :( This is from GRUB:

Code: Select all

Error 13: Invalid or unsupported executable format
giszo

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 9:15 am
by xyzzy
Very odd... I suggested that because when I take off the SIZEOF_HEADERS, I get the same error. Try linking at 0x200000 instead of 0x100000, which is the physical address I load my kernel at. So:

Code: Select all

. = 0x200000 + SIZEOF_HEADERS;

Re: Booting a 64bit kernel

Posted: Tue Dec 30, 2008 6:40 pm
by JohnnyTheDon
Well obviously it can load ELF64 files because I've been doing it for months ;) ... There was a change to the booting code after the 0.97 release that makes sure the a.out kludge is used if supplied in the multiboot header, even if the image is an ELF file.
If you use the a.out header, its not actually interpreting the file as an elf64, its just interpreting your headers. I meant that it will not take an elf64 with just the basic multiboot header and load it.

Re: Booting a 64bit kernel

Posted: Wed Dec 31, 2008 6:47 am
by xyzzy
Ah, OK. Anyway, we solved this problem on IRC - you need to link at 2MB, but also for some reason one of the header fields had been deleted in the source, which is why it wasn't working at 2MB before.