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.
I have created and loaded the: IDT and GDT. There are no exceptions or interrupts before the computer reboots. My stack is located at 0x100000, the current ESP was 0x100087 before I made the calls. My kernel is loaded at 0x1400000. I have also tried my kernel in a emulator such as BOCHS and QEMU with the same problem (reboot).
I have inserted test code to ensure that the functions are being called correctly, and that the problem is after the interrupt instruction. I have put BOCHS into debug mode and stepped through the function call to also verify that the problem happens after the interrupt instruction... but there are so many instructions afterwards that I can never step through all of them to find exactly where the problem happens.
I have also tested my IDT by causing a "divide by zero" exception, and issued software interrupts also with success. I have tested my GDT with a long jump and changing the DS and SS segments with success (and issuing memory accesses with the DS and SS segments).
If you're using it as a multiboot bootloader, yes. If you're using it as a chainloader, no. I'm not sure about the other boot protocols it supports ("Linux zImage or bzImage, FreeBSD a.out, NetBSD a.out, etc.", according to the manual).
GRUB supports a few boot protocols . Multiboot is the preferred one though, the rest is mostly for (backward?) compatibility IIRC (so it would actually be useful without requiring everyone to switch to Multiboot).
1) Load the segment registers with real-mode compatible values..
2) Reset the Protection Enable (PE) bit in CR0..
3) Load the segment registers with real mode values..
4) Inhibit A20 from the address bus (gate A20 off)..
Note that leaving protected mode requires loading the segment registers twice..
The segment registers are loaded the first time to assure that real-mode compatible values are stored in the hidden descriptor cache registers -- as the descriptor cache registers "honour" the access attributes, and segment size limit, from protected mode, even when loaded in real mode. The segment registers are loaded the second time to define them with real-mode segment values.
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
@Pyrofan1: Don't bother with the segment limit and A20. There isn't any reason why you should. That brynet-inc is a purist doesnt mean you are not allowed to make your life easier by running unreal mode instead. Also, the BIOS should be sensible enough to not depend on one specific A20 setting. More so for the VGA bios
- you'd need to set up a GDT with both 32 and 16 bit code+data segments
- then you'd need to reload cs to enter 16 bit protected mode. You need a far jump for this. Since GRUB won't allow loading to <1M you have to copy code to the realmode area yourself.
- then you need to clear PE
- then you need to reload CS again so that it holds a real-mode value.
- reload the remaining segment registers. This'll mean you end up in unreal mode, but since that doesnt change anything from the bios' perspective, why bother.
- you might as well enable interrupts by now
now you can call bios interrupts
then,
- disable interrupts
- set PE bit again
- flush cs and jump back to 32-bit code
- reload the remaining segments registers
You might want to consider asking GRUB to set a mode for you instead (see documentation), or postpone changing modes to a later stage when you can run Virtual 8086 tasks. Graphics mode is hardly a prerequisite for a functional system.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]