Page 1 of 1

GRUB: free magic is broken

Posted: Sat Jan 29, 2011 5:12 am
by Qeroq
Hello,

I tried to bring my AMD64 kernel into higher half (at 0xFFFFFF0000000000) using the following build script (Don't complain about the .text64 stuff, GRUB2 did not detect my kernel with the multiboot header
outside of .text):

Code: Select all

ENTRY(loader32)
OUTPUT_FORMAT(elf64-x86-64)
KERNEL_LMA = 0x100000;
KERNEL_VMA = 0xFFFFFF0000000000;
SECTIONS
{

    . = KERNEL_LMA;
    
    .text : 
    {
        *amd64/boot/loader32.o (.multiboot);
        *amd64/boot/loader32.o (.text);
        *amd64/boot/loader64.o (.text);
    }

    . += KERNEL_VMA;

    .text64 : AT(ADDR(.text) - KERNEL_VMA)
    {
        code = .; _code = .; __code = .;
        *(.multiboot)
        *(EXCLUDE_FILE(*amd64/boot/loader32.o *amd64/boot/loader64.o) .text)
        . = ALIGN(4096);
    }

    .data : AT(ADDR(.data) - KERNEL_VMA)
    {
        __CTOR_LIST__ = .;
        LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
        *(.ctors)
        LONG(0)
        __CTOR_END__ = .;

        __DTOR_LIST__ = .;
        LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
        *(.ctors)
        LONG(0)
        __DTOR_END__ = .;

        data = .; _data = .; __data = .;

        *(.data)
        *(.rodata)
        . = ALIGN(4096);
    }

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

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

    end = .; _end = .; __end = .;

    /DISCARD/ :
    {
        *(.comment)
    }
} 
As you see, I have two different loader binaries: loader32 and loader64. While the first sets up long mode and far jumps into the 64 bit loader (which is in lower half two), the latter one calls the kernel's main function. But I can't even get to this point: Booting the kernel GRUB dies with the following error message:

free magic is broken at 0x100100: 0x6db08fa4

That's kind of strange, as the lower memory part ends at 0x1000e4, and there's actually no 0x6db08fa4 in my kernel (at least not on a DWORD boundary)... Has someone of you guys already experienced this issue?

Re: GRUB: free magic is broken

Posted: Sat Jan 29, 2011 10:15 am
by xenos
Perhaps it would be useful to see the multiboot header definition in your code.

Re: GRUB: free magic is broken

Posted: Tue Feb 01, 2011 12:47 pm
by Qeroq
Sorry for the late response, but I've been quite busy the last couple of days...

Anyway, here is the code for the multiboot header (NASM):

Code: Select all

; Multiboot header
MBOOT_MODULEALIGN equ 1<<0                              ; Align loaded modules on page boundaries
MBOOT_MEMINFO     equ 1<<1                              ; Provide memory map
MBOOT_FLAGS       equ MBOOT_MODULEALIGN | MBOOT_MEMINFO ; Multiboot 'flag' field
MBOOT_MAGIC       equ 0x1BADB002                        ; Magic number used by the bootloader to find this
MBOOT_CHECKSUM    equ -(MBOOT_MAGIC + MBOOT_FLAGS)      ; Checksum for bootloader

; ...

section .multiboot
; The multiboot header
MultiBootHeader:
    dd MBOOT_MAGIC
    dd MBOOT_FLAGS
    dd MBOOT_CHECKSUM

Re: GRUB: free magic is broken

Posted: Tue Feb 01, 2011 4:30 pm
by xenos
Your multiboot header looks perfectly fine to me, so I don't think that's the problem...

According to the GRUB 2 sources, this error message in generated in GRUB's (heap) memory management functions (grub_real_malloc, grub_free, grub_mm_dump_free) and indicates that some data structure has been corrupted. I guess that really should not happen unless your RAM is broken or your GRUB version is buggy. Which GRUB version are you using? Have you tested your kernel with GRUB Legacy / a different version?

Re: GRUB: free magic is broken

Posted: Wed Feb 02, 2011 3:35 am
by Qeroq
I'm using some GRUB2 stage2 loader I've compiled on myself as an eltorito payload for a ISO9660. I don't know the exact version (is it mentioned somewhere in the files?) but its only a few months old. I've compiled the loader with these modules:

Code: Select all

biosdisk terminal iso9660 mmap multiboot boot normal halt sleep
I haven't tried with GRUB Legacy, because this in an 64 bit kernel (I didn't know about the patch), but i'm currently thinking about switching back to it, loading a 32 bit kernel, which loads the 64 bit one as a module after the switch to long mode and the mapping of the higher half... Quite strange it did work out with GRUB2 when I was linking the kernel to the lower one.