Grub and PE based Kernels
Grub and PE based Kernels
Hi
Will Grub load a PE based Kernel, or just ELF ones. Tim Robinson's OS seems to be PE (although I'm not sure) and he uses grub, I just need this confirmed.
also
In order to build a completely os independant program with GCC, what switches for GCC would you recommend.
Thanks
srg
Will Grub load a PE based Kernel, or just ELF ones. Tim Robinson's OS seems to be PE (although I'm not sure) and he uses grub, I just need this confirmed.
also
In order to build a completely os independant program with GCC, what switches for GCC would you recommend.
Thanks
srg
Re:Grub and PE based Kernels
Grub only recognizes elf files. There is a way to get it to work with coff and aout, but I havent messed with it.Will Grub load a PE based Kernel, or just ELF ones. Tim Robinson's OS seems to be PE (although I'm not sure) and he uses grub, I just need this confirmed.
I compile my kernel to a PE .exe format and then use objcopy to convert it to .elf. Then grub will recognize the kernel.
Code: Select all
OUTPUT_FORMAT("pei-i386") in linker script
OBJC = objcopy -O elf32-i386 kernel.exe kernel.elf
Re:Grub and PE based Kernels
If I'm not mistaken, GRUB can be made to boot any binary file format as long as it contains an "aout kludge" in its multiboot header.
Re:Grub and PE based Kernels
GRUB will load PE fine. The tricks are:
- Use the aout kludge, because PE is not ELF
- Set the file alignment and the section alignment to the same value, probably 4096. GRUB loads the PE image into memory as-is, so if the file alignment were different from the section alignment, the sections would be in the wrong places in memory, and all the addresses would be slightly out.
Re:Grub and PE based Kernels
Thanks for all the helpfull comments.
I'm just reading the GRUB tutorial and am also using The Mobius source code a reference to get me started. I'm am trying to digest all this new information but it is a lot more complicated than I thought it would be. I thought it would simply be a few lines in a command line to compile a kernel that satisfies this multiboot specification, but I shall have to read up on Makefiles and linker scripts. The closest I've ever made to a proper make file was a batch file that ran nasm tcc and tlink.
Interestingly, there is a start.asm file in the kernel source. I thought that this sort of thing was handled by a crt0 module. If not, what does a crt0 module handle.
Thanks
srg
I'm just reading the GRUB tutorial and am also using The Mobius source code a reference to get me started. I'm am trying to digest all this new information but it is a lot more complicated than I thought it would be. I thought it would simply be a few lines in a command line to compile a kernel that satisfies this multiboot specification, but I shall have to read up on Makefiles and linker scripts. The closest I've ever made to a proper make file was a batch file that ran nasm tcc and tlink.
Interestingly, there is a start.asm file in the kernel source. I thought that this sort of thing was handled by a crt0 module. If not, what does a crt0 module handle.
Thanks
srg
Re:Grub and PE based Kernels
crt0 tends to be the C RunTime startup code, but it does the same job for the C runtime as my start.asm does for the kernel.
Re:Grub and PE based Kernels
ic, so as there is no runtime when developing a kernel, you can't use a crt0 unit. That's a lot clearer!
Re:Grub and PE based Kernels
I notice that in The Mobius, the Kernel Entry code calls ArchSetup which sets up the GDT etc etc.
Would it pe possible to just call the main function which then calls ArchSetup, or does the C languages need for using the stack provent this.
Would it pe possible to just call the main function which then calls ArchSetup, or does the C languages need for using the stack provent this.
Re:Grub and PE based Kernels
I did it this way because paging isn't set up until much later, and the kernel is linked at 3GB, so ArchSetup does the GDT trick. In later versions, start.asm (actually start.S as I have switched from nasm to gas) sets up paging and calls directly into KernelMain.
Re:Grub and PE based Kernels
Whats this /mn/lib in SEARCH_DIR in the linker script?? I can't find anything like this in the source I downloaded or in cygwin.
Thanks
srg
Thanks
srg
Re:Grub and PE based Kernels
My first success.
I have successfully managed to make a "Kernel" Proram with a single nasm made file that is loaded with grub from a floppy, it works.
There must be some sort of GDT and selectors there as I managed to write the letter 'K' to the first byte of display memory with out any faults.
But Now
I'm trying to now have a simple c file (called main.c). It compiles but the linker complains about undefined references to _alloca and __main
Have I forgotten something?
Thanks
srg
I have successfully managed to make a "Kernel" Proram with a single nasm made file that is loaded with grub from a floppy, it works.
There must be some sort of GDT and selectors there as I managed to write the letter 'K' to the first byte of display memory with out any faults.
But Now
I'm trying to now have a simple c file (called main.c). It compiles but the linker complains about undefined references to _alloca and __main
Have I forgotten something?
Thanks
srg
Re:Grub and PE based Kernels
That's right. Because GRUB puts you in protected mode, it must set up a basic GDT. The multiboot spec says that, although the GDT is loaded, the memory where it came from may no longer be valid, so you can't reload any segment registers.srg wrote:There must be some sort of GDT and selectors there as I managed to write the letter 'K' to the first byte of display memory with out any faults.
Cygwin gcc puts in a call to _alloca if you try to use more than 4096 bytes of local variables in a function. You shouldn't need to do this in the kernel. If you really, really want to use more than a page of stack per function, you can link against libgcc.a.I'm trying to now have a simple c file (called main.c). It compiles but the linker complains about undefined references to _alloca and __main
All versions of gcc put in a call to __main at the top of main for some unknown reason. __main may be defined in libgcc.a as well, but it's enough to write [tt]void __main() { }[/tt].
Re:Grub and PE based Kernels
4096 bytes in a single function!!
All I have is an int pointer variable.
void __main() {}
int main()
{
char *vid_mem = 0;
vid_mem = 0xb8000;
*vid_mem = "K";
for (;;){}
}
All I have is an int pointer variable.
void __main() {}
int main()
{
char *vid_mem = 0;
vid_mem = 0xb8000;
*vid_mem = "K";
for (;;){}
}
Re:Grub and PE based Kernels
Then the compiler shouldn't need to insert a call to _alloca...
Run your .o file through objdump and try and see where the call is being made.
Run your .o file through objdump and try and see where the call is being made.