How to load a 64bit kernel in multiboot?

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
marty1885
Posts: 2
Joined: Tue Aug 12, 2014 7:59 pm

How to load a 64bit kernel in multiboot?

Post by marty1885 »

Hello everyone.
I tried to create a 64bit kernel using resources from the flowings.
http://wiki.osdev.org/Bare_Bones_with_NASM
http://wiki.osdev.org/Setting_Up_Long_Mode

What I have done is basically copy the Bare Bones example and apply the code to go into long mode
But I have run into a issue that I can't either compile 64bit or load my kernel. When I add some 64bit code into my asm file. NASM give me this error

Code: Select all

elf32 output format does not support 64-bit code
so, I set the output format from elf32 to elf64. But than ld give me this

Code: Select all

i386:x86-64 architecture of input file `src/kernel.o' is incompatible with i386 output
Than, I set the output format of ld to elf_x86_64
but than GRUB2 faild to find the multiboot header.
How can I fix this?

EDIT:
btw, I tried to put 32bit and 64bit code in different files. But that does no help

Compile enviroment:
Host OS : Ubuntu 14.10 AMD64
GRUB:2.02 - beta2.15(copied from Ubuntu's boot folder)
Assembiler:nasm 2.11

thanks for any help
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How to load a 64bit kernel in multiboot?

Post by iansjack »

Have a look at this thread for some ideas: http://f.osdev.org/viewtopic.php?f=1&t=22859

Using Grub2 to load the 64-bit code as a module works just fine for me.
marty1885
Posts: 2
Joined: Tue Aug 12, 2014 7:59 pm

Re: How to load a 64bit kernel in multiboot?

Post by marty1885 »

I'll try that out later.

Just curious tho. how XenOS load the elf64 kernel as he said:
Instead, I build my 64 bit kernel in such a way that it can be loaded by both GRUB 1 and 2. It is a 64 bit ELF file, but it has a Multiboot 1 header within the first 8k, which makes it look to GRUB as if it was just a flat 32 bit binary. GRUB then simply loads the file into memory without performing any ELF magic
How did he do that?
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: How to load a 64bit kernel in multiboot?

Post by xenos »

Exactly as written there. Have a look at the first part of my linker script:

Code: Select all

OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386:x86-64)
ENTRY(Entry)

userOffset   = 0xffff800000000000;
kernelOffset = 0xffffc00000000000;
heapStart    = 0xffffd00000000000;
heapTab      = 0xffffdf0000000000;
heapEnd      = 0xffffe00000000000;

kernelStart = kernelOffset + 0x100000;
initStart = kernelStart;
kernelElfHeader = kernelStart;

mb_magic     = 0x1badb002;
mb_flags     = 0x00010003;
mb_checksum  = -(mb_magic + mb_flags);

GROUP(libamd64.a ../libx86.a ../../../libkernel.a)
INPUT(libgcc.a)

PHDRS
{
	init PT_LOAD FILEHDR;
	user PT_LOAD;
	kernel PT_LOAD;
	dynamic PT_DYNAMIC;
}

SECTIONS
{
	.init (initStart + SIZEOF_HEADERS) : AT(ADDR(.init) - kernelOffset)
	{
		. = ALIGN(16);
		mb_address = .;
		LONG(mb_magic);
		LONG(mb_flags);
		LONG(mb_checksum);
		LONG(mb_address - kernelOffset);
		LONG(initStart - kernelOffset);
		LONG(dataEnd - kernelOffset);
		LONG(kernelEnd - kernelOffset);
		LONG(Entry - kernelOffset);
...(rest omitted here)
First of all, the output format is set to elf64. The last lines in this excerpt produce a multiboot 1 header with at "A.Out kludge", i.e., they also give information on which part of the file to load and where the entry point is. If GRUB finds this information in the multiboot header, it does not search for an elf32 header, and just plainly loads the file as if it was a flat binary file. In order to make sure that the elf headers are also loaded into memory, I load them along with the init section. Finally, the entry point is in an assembly file, which starts with some small 32 bit code that sets up paging, goes to long mode and finally calls the 64 bit C++ code.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Post Reply