Page 1 of 1

Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 3:02 am
by dlarudgus20
When we make higher half kernel, we usually map our kernel to logical address 0xc0000000 - 0xffffffff. However, there's originally reserved memory, commonly for I/O area - e.g. I/O APIC, graphic memory, etc...

Then, to use that, we must map physical address 0xc0000000 - 0xffffffff wherever. I'm trying to find appropriate address which I will like, but it's harder than I expect..

Where do you map in your kernel? Could you tell me?

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 3:10 am
by Brendan
Hi,
dlarudgus20 wrote:When we make higher half kernel, we usually map our kernel to logical address 0xc0000000 - 0xffffffff. However, there's originally reserved memory, commonly for I/O area - e.g. I/O APIC, graphic memory, etc...
The reserved areas are in the physical address space, and have nothing to do with any virtual address space.
dlarudgus20 wrote:Where do you map in your kernel? Could you tell me?
I typically map the kernel starting at 0xC0000000, then use the last 4 MiB (from 0xFFC00000 to 0xFFFFFFFF) for a "recursive page table mapping" thing. All of the space in between the end of the kernel and 0xFFC00000 gets divided up for all the different pieces of kernel data (kernel stacks, thread data structures, message queues, etc), and most of that is not mapped to anything at all until/unless it actually is used.


Cheers,

Brendan

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 3:13 am
by Combuster
Short answer: you don't.

If there's more than 1G of RAM, you can't possibly map it all into the 32-bit kernel space anyway for the sake of being able to access it any time. So you have to map it whenever you need it. The same goes for devices: if you need an area, map it for the driver that needs it. You can easily do that by simply using the next free block of virtual address space. And there's typically quite a few addresses in the 3G-4G block of physical memory that doesn't actually point to anything.

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 3:25 am
by dlarudgus20
Umm, it seems that I don't speak clearly. What I say is that it is required to map physical address 0xc0000000 - 0xffffffff to some logical address - for example:

Code: Select all

phyical address         |  | logical address
0xffffffff              |  | 0xffffffff
memory I/O, etc...      |  | kernel
0xc0000000              |  | 0xc0000000
                        |  | memory I/O, etc...
user-space area         |  | 0x80000000
                        |  |
0x00200000              |  | user-space area
kernel                  |  |
0x00100000              |  | 0x00100000
unused lower-memory     |  | unused
0x00000000              |  | 0x00000000
In that case, physical address 0xc0000000 - 0xffffffff is mapped to logical address 0x80000000 - 0xc0000000.

(I thought about that, but I give up because user-space area is small - only 2GB??)

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 3:59 am
by alexfru
AFAIR, Intel defines the selector:offset pair as a logical address. That one is subject to GDT/LDT-assisted transformations and after them becomes a linear/virtual address. That one is subject to page translation (if enabled) and after the transformations becomes a physical address.

Further, x86 page tables don't map physical addresses to virtual addresses. They map virtual addresses to physical addresses. It may seem like there's no difference, but the difference is there and it's manifold. For one thing, you can have multiple virtual addresses to resolve to the same physical address while you can't have the opposite (multiple physical addresses somehow backing up one virtual address).

Now, unless you intend to use the virtual 8086 mode, it's entirely up to you how you use the virtual address space. You can put the kernel at the beginning and the user at the end. You can put the user at the beginning and the kernel at the end. You can do anything. Learn about page translation.

Also, memory-mapped devices live in the physical address space and are generally unaware of page translations occurring inside the CPU.

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 4:04 am
by Combuster
Who would want to run your OS if the kernel in the first place when it is 1GB big? :wink:

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 4:09 am
by dlarudgus20
alexfru wrote:AFAIR, Intel defines the selector:offset pair as a logical address. That one is subject to GDT/LDT-assisted transformations and after them becomes a linear/virtual address. That one is subject to page translation (if enabled) and after the transformations becomes a physical address.

Further, x86 page tables don't map physical addresses to virtual addresses. They map virtual addresses to physical addresses. It may seem like there's no difference, but the difference is there and it's manifold. For one thing, you can have multiple virtual addresses to resolve to the same physical address while you can't have the opposite (multiple physical addresses somehow backing up one virtual address).

Now, unless you intend to use the virtual 8086 mode, it's entirely up to you how you use the virtual address space. You can put the kernel at the beginning and the user at the end. You can put the user at the beginning and the kernel at the end. You can do anything. Learn about page translation.

Also, memory-mapped devices live in the physical address space and are generally unaware of page translations occurring inside the CPU.
I know, but I want to do higher-half - because of both curiosity of how other higher-half kernel does and it looks good for me.

And I'm trying not to use segmentation to manage and separate memory - I want to use the same (or similar) way in both 32-bit and 64-bit. As you know, we can't use segmentation for that in Long Mode.

Re: Where do you map 0xc0000000 - 0xffffffff in higher half?

Posted: Fri Jun 06, 2014 7:39 am
by JAAman
dlarudgus20 wrote: I know, but I want to do higher-half - because of both curiosity of how other higher-half kernel does and it looks good for me.

And I'm trying not to use segmentation to manage and separate memory - I want to use the same (or similar) way in both 32-bit and 64-bit. As you know, we can't use segmentation for that in Long Mode.
you seem to be missing the point:

it doesn't matter where you map it, and in fact, you probably shouldn't map it at all!!

if you are worried about hardware, the hardware will work perfectly fine if it isn't mapped at all, and if your driver needs access to that particular part of the physical address space (to write to hardware, for instance) than that portion (and only that specific portion) that it needs access to can be mapped anywhere in that drivers address space (and thus is only mapped anywhere when that particular driver is running, and when other programs are running it is not mapped at all) -- of course if all drivers are running in global kernel space, then all areas that all drivers require need to be mapped into the virtual address space, but none of it should be done in a "general" way, rather wait until the driver asks to be given certain physical memory, then assign the requested physical memory to any available virtual memory area -- just like any other memory request