Page 1 of 1

JamesM Tutorial in 64 bit

Posted: Sun Oct 06, 2013 5:54 pm
by beastDivision
Hey Guys,

I've been trying to convert JamesM roll your own unix clone tutorial to 64bit, but have been running into trouble into various areas.

The closest thing I've found is this:
http://forum.osdev.org/viewtopic.php?f= ... 06&start=0

Anyways, I was wondering if there is a complete example of his tutorial in 64bit (or similar) so I can figure out where I'm getting hung up? I don't want to bother you guys with what are probably stupid mistakes.

Thanks

Re: JamesM Tutorial in 64 bit

Posted: Mon Oct 07, 2013 1:26 am
by zhiayang
beastDivision wrote:Hey Guys,

I've been trying to convert JamesM roll your own unix clone tutorial to 64bit, but have been running into trouble into various areas.

The closest thing I've found is this:
http://forum.osdev.org/viewtopic.php?f= ... 06&start=0

Anyways, I was wondering if there is a complete example of his tutorial in 64bit (or similar) so I can figure out where I'm getting hung up? I don't want to bother you guys with what are probably stupid mistakes.

Thanks
You can't expect a tutorial for everything, that's not how OSDev works.
I'd suggest you finish his 32-bit tutorial first. Most of 64-bit is similar to 64-bit, except a couple of things (that I can remember now)

1. You need to use either GRUB2, load your 64-bit kernel from disk, or objcopy your 64-bit kernel into a 32-bit ELF.
2. Some flags/values in the GDT and IDT change. Read the manuals (I'd suggest AMD manuals)
3. The TSS has a different purpose/use now, and hardware task switching is not available. (again, check manuals)
4. V86 is not available, you either do whatever video stuff you need in RM/PM before going to LM, or write native drivers.

It would help if you specify what bit you're getting stuck at –– there are several getting started guides for 64-bit kernels on the wiki.

Re: JamesM Tutorial in 64 bit

Posted: Mon Oct 07, 2013 2:06 am
by sortie
Have you completed the 32-bit version? Note that this community strongly recommends that you use the Bare Bones tutorial as the base, as the old JamesM tutorial doesn't use a cross-compiler and uses troublesome compiler options. Indeed, you should take its recommendations with a grain of salt and try to integrate it whenever Bare Bones doesn't disagree. Note that the JamesM tutorial is to known to give some very bad advise, such as "forking the kernel stack" which is just asking for trouble and is completely not needed.

So yeah, get it working in 32-bit first and later build a x86_64 cross-compiler. You'll then need to find out how to build your 64-bit kernel, which unfortunately isn't trivial. GRUB, for instance, only boots 32-bit multiboot kernels. My recommended solution is to create a beautiful fully 64-bit kernel that contains a few 32-bit instruction at _start, which will initialize the CPU to 64-bit long mode and set up some minimal identity paging for the kernel. You can then x86_64-elf-objcopy mykernel.elf64 -O elf32-i386 mykernel.elf32 to convert your 64-bit kernel to use a 32-bit container format. This fake 32-bit kernel contains a few instructions to set up 64-bit mode and become the 64-bit kernel it actually is. You should read the AMD documentation to find out what exact instructions are needed to switch to long mode.

Finally, you'd want to modify the kernel proper to 64-bit. This is a bit tricky and requires that you read the official CPU documentation to get a good knowledge of what's going on.

Re: JamesM Tutorial in 64 bit

Posted: Mon Oct 07, 2013 2:20 am
by beastDivision
Yeah, I've completed the 32 bit version. Not my first time doing OS stuff, just the first time playing with 64 bit on x86-64. I used the 64 bit higher half with grub2 as the base and started translating the stuff I liked from his 32 bit tutorial over. Getting into 64 bit isn't at all the problem. I'm getting stuck on the IDT, and no it's not iretq vs iret problem. I think it indirectly lies in how I'm implementing a memset style function, maybe. That's why I was just asking if there was a more complete example of 64bit stuff anywhere so I could poke my head around and see what other people are doing.

Re: JamesM Tutorial in 64 bit

Posted: Mon Oct 07, 2013 2:41 am
by sortie
Be sure to pass the -mno-red-zone option for all code (including kernel libc) that'll run in kernel mode, btw, if you aren't. Otherwise, interrupts will corrupt the stack - this once broke my memcpy function in very rare cases.

Re: JamesM Tutorial in 64 bit

Posted: Mon Oct 07, 2013 6:55 am
by bluemoon
Beside the noted red zone, you probable also want to disable SSE things in kernel code unless you want to use them in kernel and have properly handled them (eg. in context switch).
My kernel is compiled using the following along with the warning flags:

Code: Select all

-ffreestanding -masm=intel -std=c99 -O2 -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow

Re: JamesM Tutorial in 64 bit

Posted: Mon Oct 07, 2013 7:45 am
by sortie
You probably don't want to use -masm=intel as that changes the compiler assembly backend, which you probably shouldn't mess with. Also note, it's probably a very good idea to read up on -mcmodel=kernel and understand it.

Re: JamesM Tutorial in 64 bit

Posted: Thu Oct 10, 2013 1:55 am
by beastDivision
Thanks for the input guys. I'll take a look at all the suggestions and see what I can come up with.