First, off, this being my first post, a kind hello to everyone!
Okay -- briefly, here's my setup:
- boot.asm loads the kernel to 0x7e00 and jumps there (using JMP08:0x8000)
- kernel.c contains a function called kmain()
Simple enough. Here's the commands I use to make everything:
nasm -o boot.bin boot.asm
gcc -c -ffreestanding -fwritable-strings -o kernel.o kernel.c
ld --oformat binary -Ttext 0x7e00 -e _kmain -o kernel.bin kernel.o
From there, I move boot.bin and kernel.bin to a floppy image (BOCHS).
The problem lies with using -fwritable-strings for GCC. I had to add this in case kmain() used any constants -- I found out soon enough that constants are declared before the functions that use them, and in my case would end up right at 0x7e00. So, without this flag, code like:
void kmain()
{
char *t = "Hello there";
DoStuff();
while (1);
}
...wouldn't work.
My question is this: is there a more convenient way of dealing with this problem that I've overlooked? I've considered the following, but don't quite have the inherent skill to implement them -- moreover, I'd like to know what the 'status-quo' is on what must be a common procedure:
- somehow telling LD where the EXACT location of kmain() is (after any constant declarations)
- using a proper object format with a coinciding makefile to properly relocate everything
- writing a first function (without constants) in kernel.c that calls kmain() explicitly (yuck)
- writing an asm stub to call kmain() (yuck again)
Mind you, with -fwritable-strings everything is working, but I'm not in the mood to have to settle for kludges so early in my OS development (not to mention what other side effects might crop up from using this flag that I'm not aware of).
Thanks all in advance -- this forum is certainly a goldmine of useful, nay, necessary 'know-how' for budding OS developers!
Help with NASM+DJGPP loader/kernel
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Help with NASM+DJGPP loader/kernel
as you seem to have guessed already, the problem comes from the fact constant strings are placed in .text in some distributions of GCC (namely Djgpp, as it uses COFF and COFF has nothing like a .rodata section).
let's consider the options...
let's consider the options...
- you can roll with -fwritable-strings. for a kernel, this is not really a problem: the environment you're setting up is unlikely to be able to protect the .text section against overwriting in a first time, so your strings will be writable, whatever you ask the compiler to do ...
- you can use something else than 'binary' output format (for instance A.OUT), or at least a file format that will be able to keep the 'real' starting point address. With the binary format, your nice '-E _kmain' argument just goes to /dev/null ... That's the approach i personnally chose (letting LD doing the linking & relocating job, then using some custom tool of mine pre-pending {MAGIC, load-size, alloc-size, start-point} header in front of the raw binary text/data)
- you can create a veryvery simple asm stub in the linker script itself.
before any .text should do the trick ...
Code: Select all
BYTE(0xEA); /* check intel manuals to make sure this is 'jmp' opcode (absolute address, not the relative-one) */ LONG(_start) /* if _start is your entry point ;)
Re:Help with NASM+DJGPP loader/kernel
Excellent. Thanks.
I can't seem to kind any documentation on using commands such as BYTE() or LONG() with LD, so I think I'll just use -fwritable-strings and be content with that. After all, I would only need the flag for the entry point C file, right? The rest should link properly...?
Hey, I've got all the fun things ahead of me: interrupts, paging, mm, vmm, task switching/scheduling, ATA access, etc....fun fun fun... I should take a moment to relax and envy myself while my kernel is still nothing more than "Hello, finally!"
I can't seem to kind any documentation on using commands such as BYTE() or LONG() with LD, so I think I'll just use -fwritable-strings and be content with that. After all, I would only need the flag for the entry point C file, right? The rest should link properly...?
Hey, I've got all the fun things ahead of me: interrupts, paging, mm, vmm, task switching/scheduling, ATA access, etc....fun fun fun... I should take a moment to relax and envy myself while my kernel is still nothing more than "Hello, finally!"