Page 1 of 1
Interaction between kernel memory and BIOS
Posted: Thu Feb 23, 2012 5:50 pm
by midir
It's been a long time since I was thinking about this stuff, but I'm confused about the interaction between the ways the kernel and virtual 8086 mode and the BIOS use memory.
Let's assume a basic 32-bit kernel starting at 0xC0000000 and occupying the entire upper quarter of the address space, and user applications take the lower three quarters.
I know the kernel's quarter is supposed to stay mapped in the page directories of all process's memory spaces. I'm not entirely sure why it has to stay there but I'll accept it as a rule.
Now, in virtual 8086 mode you can call BIOS functions, true? And the BIOS ROM may typically be mapped at high physical addresses, e.g., 0xFFF00000 (last meg). I've seen reserved memory around that place on many system's memory maps. But if the kernel quarter needs to stay mapped in all address spaces, doesn't that include the space of v8086 tasks?
Does that mean that virtual memory is not as pristine and elegant as it seems? I was going to map some pages at the very end of the 32-bit virtual space. I thought I could plan the virtual space without considering the underlying physical layout, but now I'm not sure.
I don't know why I might need the BIOS (I'm using GRUB's handy kernel loading and memory map provisions, so that much is taken care of), but if I might need the BIOS, do I need to be quite conservative in where the kernel puts things in its virtual space in order to avoid getting in the way of the BIOS in its physical space?
Is this really a problem and how do you solve it?
Re: Interaction between kernel memory and BIOS
Posted: Thu Feb 23, 2012 6:27 pm
by Nessphoro
So, following your logic,
How would a 16-bit application access 0xFFF00000?
Re: Interaction between kernel memory and BIOS
Posted: Thu Feb 23, 2012 7:39 pm
by midir
Nessphoro wrote:So, following your logic,
How would a 16-bit application access 0xFFF00000?
Um. That's a good question.
Is that the answer, that it can't access it anyway? But isn't the reboot vector all the way up there?
Re: Interaction between kernel memory and BIOS
Posted: Thu Feb 23, 2012 7:52 pm
by gerryg400
The BIOS ROM is a physical piece of hardware. If it is at address 0xFFF00000 (last meg), that is a physical address.
You kernel is in the upper quarter of the virtual/linear address space.
These are entirely different and the mapping between them is decided by you.
Re: Interaction between kernel memory and BIOS
Posted: Thu Feb 23, 2012 8:04 pm
by midir
gerryg400 wrote:The BIOS ROM is a physical piece of hardware. If it is at address 0xFFF00000 (last meg), that is a physical address.
You kernel is in the upper quarter of the virtual/linear address space.
I know. My query is if one runs the BIOS in a virtual 8086 monitor then it is inside a virtual memory environment -- one that it doesn't know anything about. And it's going to expect to be able to access 0xFFF00000 as (if?) normal.
Re: Interaction between kernel memory and BIOS
Posted: Thu Feb 23, 2012 10:18 pm
by invalid
BIOS ROM starts at FFFF:0000 in real-mode segmentation, which is 000FFFF0 linear address.
Re: Interaction between kernel memory and BIOS
Posted: Fri Feb 24, 2012 1:45 am
by Combuster
ydoom wrote:BIOS ROM starts at FFFF:0000 in real-mode segmentation, which is 000FFFF0 linear address.
Lies. Read the above posts and then the manual if you don't believe it.
A part of it is copied to RAM (not a typo!) at 0x000F0000 and then made read-only so that it can pretend to be the old real mode bios.
Re: Interaction between kernel memory and BIOS
Posted: Fri Feb 24, 2012 3:38 am
by turdus
midir wrote:I know the kernel's quarter is supposed to stay mapped in the page directories of all process's memory spaces. I'm not entirely sure why it has to stay there but I'll accept it as a rule.
It's because any process can make a syscall, and if kernel wouldn't been mapped, there would be no code to jump to.
But gerry is right, kernel uses virtual address, while BIOS uses physical. Since you won't call any syscall from a v8086 (which uses real mode instruction encoding and segments), it's safe not having mapped the upper quarter there (which contains protmode code). You will need some special isrs though, but you can place them in a safe lower area. They do differ to normal isrs in upper quater anyway, so it's not a problem at all.
Re: Interaction between kernel memory and BIOS
Posted: Fri Feb 24, 2012 4:07 am
by Brendan
Hi,
Combuster wrote:ydoom wrote:BIOS ROM starts at FFFF:0000 in real-mode segmentation, which is 000FFFF0 linear address.
Lies. Read the above posts and then the manual if you don't believe it.
A part of it is copied to RAM (not a typo!) at 0x000F0000 and then made read-only so that it can pretend to be the old real mode bios.
Yes.
Split the BIOS into 2 parts. The first part is the actual BIOS ROM, which ends at (physical address) 0xFFFFFFFF and contains power-on/reset code, things like the BIOS configuration screen, and code to setup the second part. When the CPU is turned on it starts running at 0xFFFFFFF0, which is within this first part.
The second part is the "run-time" part of the BIOS in the area from 0x000F0000 to 0x000FFFFF. This area is usually RAM (not ROM). The first part of the BIOS typically decompresses the second part and copies it to this area; then tells the memory controller to ignore writes to this area of RAM (so that it acts like ROM even though it's actually RAM). For backward compatibility, this second part contains a "BIOS warm start vector thing" at 0x000FFFF0 (or 0xF000:0xFFF0).
For virtual8086, you only care about the "run-time" part of the BIOS. You can ignore the existence of the first part of the BIOS and the actual ROM. You'd want to create a fake/virtual address space that identity maps everything from the start of the EBDA to 0x000FFFFF and the BDA (at physical address 0x0000000); then add any RAM you want to use in virtual8086 mode to the virtual address space (this does *not* need to be identity mapped RAM - any pages of RAM at any physical address that are free will do); and will need to include pages for a real mode stack (and maybe some real mode code that calls BIOS functions, etc).
Once the virtual address space is setup for virtual8086, you're ready to switch to virtual8086 mode and generate lots of general protection faults (and then modify your GPF handler until it correctly emulates all the things that cause problems in virtual8086 mode).
After you've done all that and tested it to make sure it works perfectly, you'll realise the BIOS is crap and replace it with native drivers, discarding all the virtual8086 stuff (and making it much easier to port your OS to long mode and UEFI while doing it).
Cheers,
Brendan
Re: Interaction between kernel memory and BIOS
Posted: Fri Feb 24, 2012 8:19 am
by invalid
Combuster wrote:ydoom wrote:BIOS ROM starts at FFFF:0000 in real-mode segmentation, which is 000FFFF0 linear address.
Lies. Read the above posts and then the manual if you don't believe it.
A part of it is copied to RAM (not a typo!) at 0x000F0000 and then made read-only so that it can pretend to be the old real mode bios.
Ok, I promise not to post late at night/early in the morning
Anyways, since I found this site, everyday I learn something new.
Re: Interaction between kernel memory and BIOS
Posted: Fri Feb 24, 2012 9:13 am
by midir
turdus wrote:Since you won't call any syscall from a v8086 (which uses real mode instruction encoding and segments), it's safe not having mapped the upper quarter there (which contains protmode code).
I thought it needed to stay mapped so the virtual 8086 monitor could work. (?)
Brendan wrote:For virtual8086, you only care about the "run-time" part of the BIOS. You can ignore the existence of the first part of the BIOS and the actual ROM.
That's good news.
Brendan wrote:After you've done all that and tested it to make sure it works perfectly, you'll realise the BIOS is crap and replace it with native drivers, discarding all the virtual8086 stuff (and making it much easier to port your OS to long mode and UEFI while doing it).
I guess that's good news too.
Thanks Brendan.
One other thing:
Brendan wrote:The second part is the "run-time" part of the BIOS in the area from 0x000F0000 to 0x000FFFFF.
Is that (64 k) really enough space for the BIOS code? What if disk access on a particular motherboard is quite complicated? Could the BIOS ever need to hack itself control of the CPU via SMM or something, or is it truly isolated while in a virtual8086 task? I assume it would be transparent to the OS in any case; I'm just curious.