Hi all,
I'm working on my operating system on Mac OS X, and all is setup and running fine (well, as a side note, except for qemu's tendency to start without focus, which is a bit of a pain, if anyone has any idea .
Anyways, I'm trying to move to 64 bits and want to have my kernel in an ELF64 file. My pre-installed grub legacy floppy image doesn't support ELF64, and I believe grub2 does. However, I can't get grub2 to install on my Mac. I did try installing it on my Linux laptop but I couldn't get a bootable image with ELF64 support.
I'll keep on trying, and I don't have any specific questions regarding how to create it yet, but I do have some questions:
- Does anyone know/have a working grub2 image with ELF64 support available? Floppy or harddrive doesn't matter.
- Does anyone know another multiboot boot loader that supports ELF64, because grub2 feels... painful to use... (I particularly liked about it complaining an argument wasn't specified even though it was, turned out it was ignoring all arguments at some point, I gave up trying to make sense of it, as I just want a stupid image so I can get on with development).
Thanks in advance!
Grub2 image (ELF64 bootloader)
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Grub2 image (ELF64 bootloader)
Multiboot 1 does not support 64-bit elf, so by trying that you're making a non-multiboot binary for most loaders in the first place.
You can stick to multiboot and embed mostly 64-bit code into a 32-bit ELF file, and enter long mode manually (outlined here.)
You can stick to multiboot and embed mostly 64-bit code into a 32-bit ELF file, and enter long mode manually (outlined here.)
Re: Grub2 image (ELF64 bootloader)
Thanks for your reply!
I've actually been trying hard getting this to work, but it's simply not working. So my question: how do I compile this?
I managed to get it to run, but the debug symbols never quite turn out correct, causing gdb to ignore breakpoints. The assembly files work just fine - no special compile flags, just ".code32" does the trick, it's just that g++ doesn't work. I've tried every combination of "-m32", "-mx32", "-march=..." flags that I could imagine, without luck.
So, any ideas on how I would compile this?
I've actually been trying hard getting this to work, but it's simply not working. So my question: how do I compile this?
I managed to get it to run, but the debug symbols never quite turn out correct, causing gdb to ignore breakpoints. The assembly files work just fine - no special compile flags, just ".code32" does the trick, it's just that g++ doesn't work. I've tried every combination of "-m32", "-mx32", "-march=..." flags that I could imagine, without luck.
So, any ideas on how I would compile this?
-
- Member
- Posts: 5590
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Grub2 image (ELF64 bootloader)
Are you using a cross-compiler?
Re: Grub2 image (ELF64 bootloader)
Yes, I'm using an x86_64-elf compiler, and it works fine for a purely 32-bit kernel. I do have an i686-elf cross compiler as well, but I don't think that would make a difference.Octocontrabass wrote:Are you using a cross-compiler?
Re: Grub2 image (ELF64 bootloader)
The trick is making GRUB think your ELF64 kernel is a ELF32 multiboot kernel. You basically do this:
Don't randomly try combinations compile options. That doesn't lead to a reliable solution, you need to understand the low-level semantics of what is going on, so you can design a solution that works. Use tools like readelf(1) and objdump(1) to inspect the created binaries. Study the GRUB source code so you understand what is happening.
- Write your pure 64-bit kernel.
- Make it slightly unpure by having the entry point (_start) contain 32-bit assembly instructions. These instructions switch to long mode and set up paging (identity map the areas you care about early on). It then jumps to the real 64-bit entry point.
- Compile and link this almost-pure 64-bit kernel into an ELF64 object that contains a few 32-bit instructions and a lot of 64-bit instructions.
- Run x86_64-elf-objcopy myos.elf64 -O elf32-i386 myos.elf32. This converts the ELF container to a 32-bit container (which GRUB understands) but doesn't actually change the code. The result is a nice 32-bit kernel using multiboot that GRUB understand, which immediately switches to long mode and jumps to 64-bit instructions.
- Feed your fake 32-bit kernel to GRUB as you would with a 32-bit multiboot kernel. It should now boot if everything went well.
Don't randomly try combinations compile options. That doesn't lead to a reliable solution, you need to understand the low-level semantics of what is going on, so you can design a solution that works. Use tools like readelf(1) and objdump(1) to inspect the created binaries. Study the GRUB source code so you understand what is happening.
Re: Grub2 image (ELF64 bootloader)
Thanks for your replies, guys!
I did get it to work with only assembly - I just would rather be allowed to use C++ for this portion as well. But it sounds like it's too much of a hassle, so I'll stick to assembly, unless anybody has any idea on how to set it up for C++ as well?
I did actually use readelf/objdump to inspect the results, btw, which is where I found out about the issues (that, and gdb).
I did get it to work with only assembly - I just would rather be allowed to use C++ for this portion as well. But it sounds like it's too much of a hassle, so I'll stick to assembly, unless anybody has any idea on how to set it up for C++ as well?
I did actually use readelf/objdump to inspect the results, btw, which is where I found out about the issues (that, and gdb).