Grub Error 13

From OSDev Wiki
Jump to navigation Jump to search

GRUB Error 13: Invalid or unsupported executable format:

GRUB is a reference implementation of the GNU Multiboot specification, commonly used by most 32 bits OS developers. It has the advantages of being a(n) (obviously) pre-written bootloader with more code to handle quirks of various BIOSs than it is worthwhile for any individual to do by himself or herself.

See the following thread for a bit more info: http://forum.osdev.org/viewtopic.php?f=1&t=21158&start=0.

However, many people have problems getting the GRUB to recognize their kernel's executable image.

The following is a solution for GRUB's infamous Error 13 pertaining to ELF files.

Example Source

The GNU Multiboot Specification requires the Multiboot Header to be aligned on a 4 byte boundary within the first 8 KB of the kernel executable file. should your kernel's image not fit this description, GrUB will promptly issue an Error 13.

The Linker Script gives the linker details on how to position the executable sections of your kernel within the kernel executable file. You are not restricted (using ELF; there are Executable formats which restrict you to certain format-specific sections) to just the ELF recommended sections. You may define as many sections as you please within your kernel executable image, and position them as you see fit, using your linker script. We assume the use of the GNU ld linker for this article.

Within the asm source file where you have defined your Multiboot Header options, edit the Multiboot Header to look like this: (This article is not going into detail about the GNU Multiboot spec. I'm just telling you minor changes to make around the header)

;; Remove the section .text you copy/pasted from the Bare Bones tutorial ;)
section .__mbHeader

align 0x4
;; Copy/Paste your current Multiboot Header here

;; Reposition the section .text here.

What does this do? We have placed the Multiboot header into a separate ELF section in the relocatable file generated by NASM. When the linker is going through the Object files, it places the section symbols in each object file in their corresponding output sections in the eventual kernel image.

How do we tell the linker to place the .__mbHeader ELF section in the 1st 8 KB of the kernel image? Technically, there is no way to guarantee that it will be there if the kernel file grows exorbitantly large. At that point, you may have to invent a special technique of editing your output object file manually, and placing the Multiboot header in the first 8 K. However you do that is ...however you manage to do it. The simple solution is to ensure that your kernel image doesn't grow too large. Again, technically, even a monolithic kernel's image shouldn't grow that large, even if you try.

The linker is told to use the .__mbHeader section as the first section in the output file like this:

yourLinkerScript.ld

/*This is the SECTIONS command in your ld script. Locate it.*/
SECTIONS {
   /* There is a command with the following general form in your linker script:
    * . = 0xXXXXXXXX;
    * You are to leave this in place, and put the section for .__mbHeader beneath that line.
    **/
   .__mbHeader : {
      *(.__mbHeader)
   }

   /* The other sections are here. After you edit the script. If you copy/pasted the Bare Bones ld script, then your .text sections follows here.*/
   /*...*/
}

In other words, we simply insert the lines for the .__mbHeader section at the top of the SECTIONS command, telling ld to place the .__mbHeader section first.

One or two notes, since the copy/paste horde wouldn't actually notice these points: We assume that your kernel is not virtually linked to a higher address. If it is, then you should edit the first line of the .__mbHeader linker command to look like this:

.__mbHeader : AT( ADDR(.__mbHeader) - YOUR_KERNEL\'S_VIRTUAL_OFFSET_HERE ) {

Should you do this right, (and it shouldn't be that difficult), your kernel shouldn't emit that Error 13 message anymore, and provided you linked you kernel in the right format, and whatnot, GRUB should be able to load your kernel nicely.

See Also

Articles

Forum Threads

External Links