Since I'm having trouble getting GRUB to pass me VBE information so I can use the PM interface to switch modes (see this topic), I thought I'd try to call the realmod (BIOS) interrupts. However, how do I do that? My kernel is not yet in a stage that I can think about v86. So how do I switch back to realmode, after my kernel has been booted by GRUB (or any other multiboot compliant bootloader for that matter)? GRUB already sets me up in PM, so how to switch back? Yeah, I know about bit 0 of CR0 and such, but how do I get the correct realmode segments? Any help would be much appreciated.
JAL
Calling realmode ints after multiboot (without v86)
Re: Calling realmode ints after multiboot (without v86)
Hi,
The basic idea is to copy some code from where GRUB loaded it to below 1 MB. Then jump/call this code below 1 MB, setup a new GDT, change all segment registers (including CS and SS) so they point to 16-bit protected mode segments, then clear the PE bit in CR0. Now you're in real mode or "unreal" mode (it's just as easy to leave 4 GB segment limits on data segment registers). Do a far JMP to reload CS and flush the pipeline, then do STI to enable interrupts.
Now you should be able to use the BIOS functions like normal.
Note: for segment registers, the only thing that really matters is that CS and SS are 16-bit protected mode segments before you clear the PE flag in CR0 (and that all segment limits are 64 KB or larger).
There is one (small) problem though. The Multi-boot specification says that the boot loader (e.g. GRUB) must keep the firmware in a working state, however, it doesn't say the firmware must be PC BIOS. If GRUB was booted by different firmware (e.g. LinuxBIOS or EFI) then you'll crash when you try to use PC BIOS functions.
Cheers,
Brendan
I've done this before (for the same reason you're doing it).jal wrote:Since I'm having trouble getting GRUB to pass me VBE information so I can use the PM interface to switch modes (see this topic), I thought I'd try to call the realmod (BIOS) interrupts. However, how do I do that? My kernel is not yet in a stage that I can think about v86. So how do I switch back to realmode, after my kernel has been booted by GRUB (or any other multiboot compliant bootloader for that matter)? GRUB already sets me up in PM, so how to switch back? Yeah, I know about bit 0 of CR0 and such, but how do I get the correct realmode segments? Any help would be much appreciated.
The basic idea is to copy some code from where GRUB loaded it to below 1 MB. Then jump/call this code below 1 MB, setup a new GDT, change all segment registers (including CS and SS) so they point to 16-bit protected mode segments, then clear the PE bit in CR0. Now you're in real mode or "unreal" mode (it's just as easy to leave 4 GB segment limits on data segment registers). Do a far JMP to reload CS and flush the pipeline, then do STI to enable interrupts.
Now you should be able to use the BIOS functions like normal.
Note: for segment registers, the only thing that really matters is that CS and SS are 16-bit protected mode segments before you clear the PE flag in CR0 (and that all segment limits are 64 KB or larger).
There is one (small) problem though. The Multi-boot specification says that the boot loader (e.g. GRUB) must keep the firmware in a working state, however, it doesn't say the firmware must be PC BIOS. If GRUB was booted by different firmware (e.g. LinuxBIOS or EFI) then you'll crash when you try to use PC BIOS functions.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Calling realmode ints after multiboot (without v86)
Well, I don't believe GRUB classic supports EFI or LinuxBIOS, and I'm running in Bochs for the moment, so no problem there. Thanks for the information, I'll try to hack something together to see if that works.Brendan wrote:There is one (small) problem though. The Multi-boot specification says that the boot loader (e.g. GRUB) must keep the firmware in a working state, however, it doesn't say the firmware must be PC BIOS. If GRUB was booted by different firmware (e.g. LinuxBIOS or EFI) then you'll crash when you try to use PC BIOS functions.
JAL