I have code very much like Barebones on the osdevfaqwiki that I want to compile and link into an executable format that supports long mode instructions on the AMD64. I have no trouble doing this, as I've built a cross compiler. The trouble comes when I try to boot it.
I'm creating the multiboot header correctly (as shown in barebones as well), and I'm using the aout kludge. No matter what output_format I specify in my linker script, I cannot get grub to load the executable correctly. I'm not using anything 64 bit yet, so I can still compile/link into elf32, and grub will load this with no complaints.
First few lines of loader.asm, following 'global's and 'extern's:
Code: Select all
start:
jmp _loader
...
;setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
AOUT_KLUDGE equ 1<<16
FLAGS equ MODULEALIGN | MEMINFO | AOUT_KLUDGE ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
BASE equ 0x100000
section .text
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
dd MultiBootHeader ; these are PHYSICAL addresses
dd code ; start of kernel .text (code) section
dd bss ; end of kernel .data section
dd end ; end of kernel BSS
dd start ; kernel entry point (initial EIP)
;Use a 16K stack for the kernel
STACKSIZE equ 0x4000
_loader:
mov esp, stack+STACKSIZE ;Set up the stack
push eax ;Pass the multiboot magic number to _main
push ebx ;Pass the multiboot info structure to _main
...
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY (start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys)
{
code = .;
*(.text)
. = ALIGN(4096);
}
.rodata : AT(phys + (rodata - code))
{
rodata = .;
*(.rodata)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
start_ctors = .;
*(.ctor*)
end_ctors = .;
start_dtors = .;
*(.dtor*)
end_dtors = .;
*(.data)
_edata = .;
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
. = ALIGN(4096);
}
end = .;
}
Code: Select all
Booting 'My Kernel'
root (fd0)
Filesystem type is fat, using whole disk
kernel /kernel.bin
[Multiboot-kludge, loadaddr=0x100000, text-and-data=0x5000, bss=0x7000, entry=0x100000]
When I link to elf64-little, Grub tells me this:
Code: Select all
Booting 'My Kernel'
root (fd0)
Filesystem type is fat, using whole disk
kernel /kernel.bin
[Multiboot-kludge, loadaddr=0x100000, text-and-data=0x5000, symtab=0x2, strtab=0x11301fc(bad), entry=0x100000]
Error 30: Invalid argument
Press any key to continue...