GRUB refuses to load ...
GRUB refuses to load ...
I'm really furious at the moment because I'm trying this for 4 hours now ... and I do ALWAYS get GRUB error 7 - loading below 1MB is not supported.
I did objdump and it didn't show any sections that begin below 1MB. I tried ELF files and bare binaries. I tried compiling and loading the tutorial kernels on this site (all using BOCHS) - and it's always error 7. What the hell am I doing wrong ??? I mean, I just copied 1:1 what's written in the Wiki ... but I just doesn't work.
The most supid thing is, ONE TIME it worked. But I forgot what linker script I used that time ... and BOCHS instantly crashed upon loading the kernel.
The solution might even be trivial ... but I currently I have no idea why booting fails ALL THE TIME. Please ... help.
I did objdump and it didn't show any sections that begin below 1MB. I tried ELF files and bare binaries. I tried compiling and loading the tutorial kernels on this site (all using BOCHS) - and it's always error 7. What the hell am I doing wrong ??? I mean, I just copied 1:1 what's written in the Wiki ... but I just doesn't work.
The most supid thing is, ONE TIME it worked. But I forgot what linker script I used that time ... and BOCHS instantly crashed upon loading the kernel.
The solution might even be trivial ... but I currently I have no idea why booting fails ALL THE TIME. Please ... help.
Re:GRUB refuses to load ...
Please provide your linker script, your Makefile if available, and the code where you set the multiboot header.
Without further information, all I can say is that you're probably attempting to load below 1 MB.
Without further information, all I can say is that you're probably attempting to load below 1 MB.
Every good solution is obvious once you've found it.
Re:GRUB refuses to load ...
Well I'm currently trying to load one of the HigherHalfBareBones kernel, the linker script is this:
ENTRY(_loader)
OUTPUT_FORMAT(elf32-i386)
SECTIONS
{
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
*(.rodata*)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
}
.bss : AT(ADDR(.bss) - 0xC0000000)
{
_sbss = .;
*(COMMON)
*(.bss)
/* I added the following two entries because objdump showed them at address 0 ... why are they there anyway - I don't want them? */
*(.comment)
*(.note.GNU-stack)
_ebss = .;
}
}
Compilation:
nasm -f elf -o loader.o loader.asm
gcc -fno-builtin -nostdinc -c -o kernel.o kernel.c
ld -T link.ld -o kernel.bin kernel.o loader.o
EDIT: should I add the -magic-it-will-only-work-if-you-do-this switch?
objdump -h outputs:
kernel.bin: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000f8 c0100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00001000 c0101000 00101000 00002000 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 0000405e c0102000 00102000 00003000 2**2
ALLOC
EDIT: in this case I just copied:
http://www.osdev.org/osfaq2/index.php/H ... fBareBones
GRUB says ... below 1MB.
ENTRY(_loader)
OUTPUT_FORMAT(elf32-i386)
SECTIONS
{
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
*(.rodata*)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
}
.bss : AT(ADDR(.bss) - 0xC0000000)
{
_sbss = .;
*(COMMON)
*(.bss)
/* I added the following two entries because objdump showed them at address 0 ... why are they there anyway - I don't want them? */
*(.comment)
*(.note.GNU-stack)
_ebss = .;
}
}
Compilation:
nasm -f elf -o loader.o loader.asm
gcc -fno-builtin -nostdinc -c -o kernel.o kernel.c
ld -T link.ld -o kernel.bin kernel.o loader.o
EDIT: should I add the -magic-it-will-only-work-if-you-do-this switch?
objdump -h outputs:
kernel.bin: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000f8 c0100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00001000 c0101000 00101000 00002000 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 0000405e c0102000 00102000 00003000 2**2
ALLOC
EDIT: in this case I just copied:
http://www.osdev.org/osfaq2/index.php/H ... fBareBones
GRUB says ... below 1MB.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:GRUB refuses to load ...
gathering loader.asm, kernel.c, grub_disk.img, linker.ld from HigherHalfBareBones ...
then requesting "kernel /kernel.elf" nicely works for me...
i'd suggest you cross-check what you ask GRUB to load is what you expect it to load ...
For info,
and after i type "kernel /kernel.elf" in GRUB's command line, i get
So the tutorial works for me, with only the two "objcopy" commands added to get rid of annoying sections ...
Code: Select all
cp ../grub_disk.img barebones.img
gcc-3.3 -std=c99 -Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -c kernel.c
nasm -f elf loader.asm
ld -T linker.ld loader.o kernel.o -o kernel.elf
objcopy --remove-section .comment kernel.elf
objcopy --remove-section .note.GNU-stack kernel.elf
mcopy -i barebones.img kernel.elf ::
qemu -fda barebones.img
i'd suggest you cross-check what you ask GRUB to load is what you expect it to load ...
For info,
Code: Select all
tutorials/hhbarebones> objdump -h kernel.elf
kernel.elf: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000f8 c0100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00001000 c0101000 00101000 00002000 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00004000 c0102000 00102000 00003000 2**2
ALLOC
Code: Select all
[multiboot-elf, <0x100000:0xf8:0x0>, <0x101000:0x1000:0x4000>, shtab=0x106118, entry=0xc010000c]
Re:GRUB refuses to load ...
Thanks for answering.
I fiddled a bit with the linker (LD version 2.16.1) and tried to link data, text and bss sections of a simple endless loop file with multiboot header. I noticed that THIS works with GRUB :
while the following does produce a below-1-MB error :
The ONLY thing I've changed is the layout of memory and placed the text segment up in virtual memory and the setup segment at the beginning, in order to reproduce a 'higher half' kernel.
Why is it that GRUB rejects the file linked with the second script? Everything is OK it seems to me ...
EDIT: OBSERVATION:
GRUB will NOT load if my .text has a high virtual address (say 0xC0000000). It WILL load, however, if it's at the physical address (0x00100000).
best regards, Christoph
I fiddled a bit with the linker (LD version 2.16.1) and tried to link data, text and bss sections of a simple endless loop file with multiboot header. I noticed that THIS works with GRUB :
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
virt = 0xBFF00000;
phys = 0x00100000;
SECTIONS
{
. = phys;
.text : {
*(*.text)
}
text_end = .;
. += virt;
.data : AT(text_end) {
*(*.data)
}
data_end = .;
.setup : AT(data_end - virt) {
*(*.setup)
}
setup_end = .;
.bss : AT(setup_end - virt) {
*(*.bss)
}
bss_end = .;
}
while the following does produce a below-1-MB error :
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
virt = 0xBFF00000;
phys = 0x00100000;
SECTIONS
{
. = phys;
.setup :{
*(*.setup)
}
setup_end = .;
. += virt;
.text : AT(setup_end) {
*(*.text)
}
text_end = .;
.data : AT(text_end - virt){
*(*.data)
}
data_end = .;
.bss : AT(data_end - virt){
*(*.bss)
}
bss_end = .;
}
Why is it that GRUB rejects the file linked with the second script? Everything is OK it seems to me ...
EDIT: OBSERVATION:
GRUB will NOT load if my .text has a high virtual address (say 0xC0000000). It WILL load, however, if it's at the physical address (0x00100000).
best regards, Christoph
Re:GRUB refuses to load ...
OK ... careful (well, more or less) experimentation shows ... I CAN actually use the linker script with everything at a higher half virtual address except for one data segment which will be used to setup an initial GDT before paging is turned on.
BUT ... once I set 'virtual' to about 0x1000:0000, bochs says "running in bogus memory" and panics after loading the kernel.
When I get to 0xC000:0000 GRUB won't even load the kernel anymore.
Now ... how to fix this ...
EDIT: hmm ... I have set the entrypoint in the linker file ... and the code at the entrypoint does:
cli
hlt
jmp $
... so the EIP shouldn't run off anywhere. Naahrg.
As far as the debugger goes, BOCHS doesn't even arrive at my code ...
Ok it's obviously a bug in BOCHS because a REAL GRUB instantly says ... no loading below 1MB ...
EDIT:
ok ... even a minor of set in the above linker scripts from virt to phys causes BOCHS to wander off into nowhere ... I'm getting annoyed ... am I publishing my own stupidity here because it seems really odd to me that it's working with all of you and me not.
Enlighten me ... PLEASE ?
BUT ... once I set 'virtual' to about 0x1000:0000, bochs says "running in bogus memory" and panics after loading the kernel.
When I get to 0xC000:0000 GRUB won't even load the kernel anymore.
Now ... how to fix this ...
EDIT: hmm ... I have set the entrypoint in the linker file ... and the code at the entrypoint does:
cli
hlt
jmp $
... so the EIP shouldn't run off anywhere. Naahrg.
As far as the debugger goes, BOCHS doesn't even arrive at my code ...
Ok it's obviously a bug in BOCHS because a REAL GRUB instantly says ... no loading below 1MB ...
EDIT:
ok ... even a minor of set in the above linker scripts from virt to phys causes BOCHS to wander off into nowhere ... I'm getting annoyed ... am I publishing my own stupidity here because it seems really odd to me that it's working with all of you and me not.
Enlighten me ... PLEASE ?
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Re:GRUB refuses to load ...
Where did those two sections come from...? I never encountered them while developing the tutorial. Note that I'm using a cross-compiler based on GCC 3.4.1 and a "cross-compiled" binutils with ld version 2.15.91.Pype.Clicker wrote: So the tutorial works for me, with only the two "objcopy" commands added to get rid of annoying sections ...
@Calim:
Could you show us the code where you set up the Multiboot header and enable paging? The linker script you posted with the "setup" section seems to be based on the HigherHalfWithGdt example rather than HigherHalfBareBones. You shouldn't intermix anything from the two -- they are fundamentally different approaches.
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Re:GRUB refuses to load ...
OK ... at least what I programmed was correct. I can't believe it ... it took me about 4000 times starting up BOCHS (and I should have used QEMU when I didn't need debugging, it takes about 1/20 of the time to get to the GRUB menu compared to BOCHS) to notice that it's the old version of GRUB on the floppy image I used that caused the errors. The version (0.5x or so) didn't yet support differing VMA/LMA. I found a mailing list post about a patch to introduce this feature. Sorry ... now it works ... or, at least, I have the impression it does (well, it does ... but maybe I'm hallucinating).
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:GRUB refuses to load ...
doh ...
i remembered of that "cannot handle different VMA/LMA stuff" with early releases of GRUB, but i didn't warn you about it because it obviously worked with HigherHalfBareBones tut. (updating the FAQ)
i remembered of that "cannot handle different VMA/LMA stuff" with early releases of GRUB, but i didn't warn you about it because it obviously worked with HigherHalfBareBones tut. (updating the FAQ)