Grub and PE based Kernels

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
srg

Grub and PE based Kernels

Post by srg »

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
beyondsociety

Re:Grub and PE based Kernels

Post by beyondsociety »

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.
Grub only recognizes elf files. There is a way to get it to work with coff and aout, but I havent messed with it.

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
Hope this helps.
nullify

Re:Grub and PE based Kernels

Post by nullify »

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.
Tim

Re:Grub and PE based Kernels

Post by Tim »

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.
srg

Re:Grub and PE based Kernels

Post by srg »

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. :o 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
Tim

Re:Grub and PE based Kernels

Post by Tim »

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.
srg

Re:Grub and PE based Kernels

Post by srg »

ic, so as there is no runtime when developing a kernel, you can't use a crt0 unit. That's a lot clearer!
srg

Re:Grub and PE based Kernels

Post by srg »

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.
Tim

Re:Grub and PE based Kernels

Post by Tim »

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.
srg

Re:Grub and PE based Kernels

Post by srg »

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
Tim

Re:Grub and PE based Kernels

Post by Tim »

It's not used.
srg

Re:Grub and PE based Kernels

Post by srg »

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
Tim

Re:Grub and PE based Kernels

Post by Tim »

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.
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.
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
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.

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].
srg

Re:Grub and PE based Kernels

Post by srg »

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 (;;){}
}
Tim

Re:Grub and PE based Kernels

Post by Tim »

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.
Post Reply