Page 1 of 1

GRUB Error 28 When Booting Kernel

Posted: Tue Jun 15, 2010 10:09 am
by AaronMiller
Hello. I'm working on a kernel and have encountered an issue. I switched from a 32-bit Ubuntu installation to a 64-bit Ubuntu installation recently. (To be honest, it wasn't that recently; I no longer have any 32-bit Ubuntu discs I'm willing to use.) I've started a kernel from scratch. I've attempted to compile my kernel but have received GRUB error 28 (selected item won't fit in memory). I've tried two different versions of GRUB; 0.5~ and an unknown version (whichever version is in JamesM's tutorials). After searching through my code for several hours, correcting every little thing, trying different ways to assemble, compile, and link the kernel, and comparing to other kernels, I could not find a solution. I used Google to look up information on GRUB error 28, then did the same to look for references to that error on this site. I've found no useful information (most of it involved "invalid configuration of the Linux kernel").

My tools:
- Ubuntu 10.04 LTS
- GCC version 4.4.3 (a 2009 build)
- GNU Binutils 2.20.1-system.20100303; GNU gold 1.9 (seems to replace LD or is a different version of it; objdump confirms everything it outputs is correct)
- GNU Make 3.81
- NASM 2.07 ("compiled on Nov 5 2009")

Here's how the kernel gets compiled:

Code: Select all

nasm -felf32 -o obj/start.o src/arch/x86-32/start.asm
gcc -O2 -fexpensive-optimizations -fomit-frame-pointer -I./inc/ -Wall -pedantic -nostdinc -nostdlib -fno-builtin -fno-stack-protector -masm=intel -m32 -c -o obj/kmain.o src/kmain.c
ld -b elf32-i386 --oformat elf32-i386 -Tsrc/arch/x86-32/kernel.ld -o bin/kernel obj/start.o obj/kmain.o
Here's the (cut-down) assembly source; start.asm:

Code: Select all

; 32-bit mode
    bits                32
; Multiboot Flags
    MBF_PAGE_ALIGN      equ 0x01
    MBF_MEMORY_INFO     equ 0x02
; Multiboot Magic
    MBB_HEADER          equ 0x1BADB002
; Kernel Multiboot Fields
    KMB_FLAGS           equ (MBF_PAGE_ALIGN|MBF_MEMORY_INFO)
    KMB_CHECKSUM        equ -(MBB_HEADER+KMB_FLAGS)

; Globals and Externals here omitted, globals : start, multiboot; externals : code, bsss, end, kmain;

; Multiboot header
multiboot:
    ; Setup the multiboot header
    dd                  MBB_HEADER
    dd                  KMB_FLAGS
    dd                  KMB_CHECKSUM
    ; Flags does not include A.OUT kludge; I've tried this with and without the kludge and the flag (and combinations of them)

; Start of the program (marked as the entry point in the linker script)
start:
    ; Code here is irrelevant. It first disables interrupts, sets up the stack, calls the kernel with the multiboot structure address passed, and finally halts processor execution

; NOTE: OBJDUMP confirms that the multiboot header is at the 1st megabyte of memory, exactly.
I don't think it's relevant, but here's the C code for the kernel. OBJDUMP confirms kmain to be there. Running -S with all optimization options shows it still there.

Code: Select all

void kmain(void *pMultiboot)
{
    if (!pMultiboot)
        return;
}
As you can see, this is just a skeleton of a project. There's very little to go wrong. I suspect it's my environment, but I'll leave the diagnosis to you guys. If anyone needs any additional information, I'll give it.

Thanks in advance for the time you take to read this, and especially any thought that goes into my issues.

Cheers,
-Aaron

Re: GRUB Error 28 When Booting Kernel

Posted: Tue Jun 15, 2010 10:22 am
by Combuster
Did you define sections in your asm file?

Re: GRUB Error 28 When Booting Kernel

Posted: Tue Jun 15, 2010 10:25 am
by AaronMiller
No, I'll try that now, thanks. :)

EDIT: After defining the sections it had no effect.

Re: GRUB Error 28 When Booting Kernel

Posted: Tue Jun 15, 2010 11:01 am
by Tosi
I'm on ubuntu 64 too and I had problems with the output format. You could build a cross-compiler, but if you don't feel like it I think the following will work.

Change

Code: Select all

ld -b elf32-i386 --oformat elf32-i386 -Tsrc/arch/x86-32/kernel.ld -o bin/kernel obj/start.o obj/kmain.o
to

Code: Select all

ld -melf_i386 -b elf32-i386 --oformat elf32-i386 -Tsrc/arch/x86-32/kernel.ld -o bin/kernel obj/start.o obj/kmain.o
That puts LD into elf i386 emulation mode, otherwise it might try to spit out elf64 code.

Re: GRUB Error 28 When Booting Kernel

Posted: Tue Jun 15, 2010 11:13 am
by AaronMiller
Thanks Tosi. :)

Unfortunately that does not work. I've tried it. The LD documentation says "-m" is ignored, and provided only for compatibility. The kernel is in 32-bit format, I've verified this with OBJDUMP. I suppose I can build a cross-compiler.

Re: GRUB Error 28 When Booting Kernel

Posted: Thu Jun 17, 2010 10:49 am
by AaronMiller
I fixed it. For various unrelated reasons I installed a different Linux distro (from Ubuntu 10.04 to Slackware 13.1). I decided to try -m (I had previously discredited it for a different reason, but decided to give it a shot). I don't know if that's what did it specifically, or if the change in distro (and by extension compiler utilities) did it.

Thank you all for your time and help, it's very appreciated.

Cheers,
-Aaron