Interaction between kernel memory and BIOS

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.
Post Reply
midir
Member
Member
Posts: 46
Joined: Fri Jun 13, 2008 4:09 pm

Interaction between kernel memory and BIOS

Post 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?
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Interaction between kernel memory and BIOS

Post by Nessphoro »

So, following your logic,

How would a 16-bit application access 0xFFF00000?
midir
Member
Member
Posts: 46
Joined: Fri Jun 13, 2008 4:09 pm

Re: Interaction between kernel memory and BIOS

Post 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? :-k
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Interaction between kernel memory and BIOS

Post 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.
If a trainstation is where trains stop, what is a workstation ?
midir
Member
Member
Posts: 46
Joined: Fri Jun 13, 2008 4:09 pm

Re: Interaction between kernel memory and BIOS

Post 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.
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: Interaction between kernel memory and BIOS

Post by invalid »

BIOS ROM starts at FFFF:0000 in real-mode segmentation, which is 000FFFF0 linear address.
User avatar
Combuster
Member
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: Interaction between kernel memory and BIOS

Post 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.
"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 ]
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Interaction between kernel memory and BIOS

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Interaction between kernel memory and BIOS

Post 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
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.
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: Interaction between kernel memory and BIOS

Post 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.
midir
Member
Member
Posts: 46
Joined: Fri Jun 13, 2008 4:09 pm

Re: Interaction between kernel memory and BIOS

Post 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.
Post Reply