Grub Error 13: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
No edit summary
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
Line 17: Line 17:
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)
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)


<source lang="ASM">
<syntaxhighlight lang="ASM">
;; Remove the section .text you copy/pasted from the Bare Bones tutorial ;)
;; Remove the section .text you copy/pasted from the Bare Bones tutorial ;)
section .__mbHeader
section .__mbHeader
Line 25: Line 25:


;; Reposition the section .text here.
;; Reposition the section .text here.
</syntaxhighlight>
</source>


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.
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.
Line 34: Line 34:


'''yourLinkerScript.ld'''
'''yourLinkerScript.ld'''
<source lang="C">
<syntaxhighlight lang="C">
/*This is the SECTIONS command in your ld script. Locate it.*/
/*This is the SECTIONS command in your ld script. Locate it.*/
SECTIONS {
SECTIONS {
Line 48: Line 48:
/*...*/
/*...*/
}
}
</syntaxhighlight>
</source>


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.
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.
Line 54: Line 54:
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:
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:


<source lang="C">
<syntaxhighlight lang="C">
.__mbHeader : AT( ADDR(.__mbHeader) - YOUR_KERNEL\'S_VIRTUAL_OFFSET_HERE ) {
.__mbHeader : AT( ADDR(.__mbHeader) - YOUR_KERNEL\'S_VIRTUAL_OFFSET_HERE ) {
</syntaxhighlight>
</source>


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.
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.

Latest revision as of 04:30, 9 June 2024

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