Hi
I'm using Bochs-2.3 compiled with the --enable-gdb-stub option under mandriva 10.2 linux, with gcc 3.4.3 and nasm 0.98.39.
Basically, I'm trying to debug a simple kernel to find where a fault is triggered, using gdb remotely.
My kernel (a mixture of C and ASM) is loaded by Grub, and this works fine normally. However, if I compile with the -g option in gcc (I believe this to be the correct switch to compile with debugging information, please tell me if I'm wrong), grub complains that the kernel does not fit in memory.
I find this strange as the kernel is only ~20kb, and the emulated memory size is 128mb.
I am aware that it sometimes reports this message even if the error is something else, but what other scenarios cause this error?
I tried using 'strip -d kernel.bin -o kernel.debug', but this does not affect the size of the kernel.bin binary (or the error message for that matter). I'm unfamiliar with this tool though, so I am possibly doing something stupid.
My kernel format is elf32-i386, and it is loaded at 0x00100000.
Hope I've provided enough information. Do you need to see my makefile/link script?
Even suggestions/guesses/hunches are welcome
Thanks
Grub: error loading a kernel when compiled with -g
There is something strange going on...
As I explained, when I compile my code normally, it all works fine. However, now I've also discovered that if I comment a few lines out, I get the dreaded "Error 28: Selected item cannot fit into memory" again. Why should that be?
With those lines uncommented, it loads fine, but when they are commented, grub complains that it does not fit in memory! It is so bizarre!
Thanks again
As I explained, when I compile my code normally, it all works fine. However, now I've also discovered that if I comment a few lines out, I get the dreaded "Error 28: Selected item cannot fit into memory" again. Why should that be?
Code: Select all
void main()
{
InitVideo();
SetupGDT();
SetupIDT();
InstallISRs();
//__asm__ __volatile__ ("sti");
//ClearScreen(0x1E);
//PrintString("Hello world");
}
Thanks again
Re: Grub: error loading a kernel when compiled with -g
Ten times out of nine, that happens because some section in the binary is marked for loading and has it's physical address set to some non-sensical value. Typical examples of this happening are stuff like trying to link kernel at 3GB and forgetting to tell the linker what it's not really where the binary will be loaded.BluReaver wrote:grub complains that the kernel does not fit in memory.
Now, "objdump -h <binary>" will show the relevant headers. You get output something like this:
Code: Select all
kernel: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00009eb2 00100000 00100000 00001000 2**5
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00001710 00109ec0 00109ec0 0000aec0 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .bss 0001c818 00110000 00110000 0000d000 2**15
ALLOC
3 .note.GNU-stack 00000000 00000000 00000000 0000d000 2**0
CONTENTS, READONLY
4 .comment 000005d8 00000000 00000000 0000d000 2**0
CONTENTS, READONLY
There are various other flags to objdump get various other kinds of header information (-p gives program header if you've got an ELF kernel)...
Most likely you'll find some section which is supposed to be loaded at some crazy address. Mostly likely it's either a problem with your linker script, or the parameters you give to your linker..
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
If you give your linker script, your Makefile (or at least linker command line) and the output of objdump with either -h or -p (or both) for the failing kernel (say, one with debugging symbols), it'll be easier to figure out what exactly could be the problem.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Thanks very much for you response
This is the output from objdump:
My linker script is fairly simple and was just copied out a tutorial (ashamedly)
And my makefile
./disk is where i mounted the disk image, and sync is there because it doesn't seem to take effect immediately without it.
Thanks again
This is the output from objdump:
Code: Select all
[root@neptune OS2]# objdump -h ./disk/boot/kernel.bin
./disk/boot/kernel.bin: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00001000 00100000 00100000 00001000 2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00001000 00101000 00101000 00002000 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00002844 00102000 00102000 00003000 2**5
ALLOC
3 .note.GNU-stack 00000000 00000000 00000000 00003000 2**0
CONTENTS, READONLY
4 .comment 000000c8 00000000 00000000 00003000 2**0
CONTENTS, READONLY
5 .rodata 00000279 000000c8 000000c8 000000c8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
[root@neptune OS2]# objdump -p ./disk/boot/kernel.bin
./disk/boot/kernel.bin: file format elf32-i386
Program Header:
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
filesz 0x00000341 memsz 0x00000341 flags r--
LOAD off 0x00001000 vaddr 0x00100000 paddr 0x00100000 align 2**12
filesz 0x00001000 memsz 0x00001000 flags r-x
LOAD off 0x00002000 vaddr 0x00101000 paddr 0x00101000 align 2**12
filesz 0x00001000 memsz 0x00003844 flags rw-
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rwx
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
Code: Select all
kernel.bin: makefile kernel_asm.o kernel.o screen.o pm.o isr_asm.o isr.o
ld -T link.ld -o ./disk/boot/kernel.bin kernel_asm.o kernel.o screen.o pm.o isr_asm.o isr.o
sync
kernel_asm.o: kernel.asm
nasm -f aout -o kernel_asm.o kernel.asm
kernel.o: kernel.c
gcc -Wall -g -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o kernel.o kernel.c
...similar lines for the rest of the objects have been omitted...
Thanks again
try adding rodata to your linker script
Code: Select all
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata)
. = ALIGN(4096);
}