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

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
dlarudgus20
Member
Member
Posts: 36
Joined: Sat Oct 26, 2013 4:14 am

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

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

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

Post 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
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.
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: Where do you map 0xc0000000 - 0xffffffff in higher half?

Post 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.
"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 ]
dlarudgus20
Member
Member
Posts: 36
Joined: Sat Oct 26, 2013 4:14 am

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

Post 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??)
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

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

Post 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.
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: Where do you map 0xc0000000 - 0xffffffff in higher half?

Post by Combuster »

Who would want to run your OS if the kernel in the first place when it is 1GB big? :wink:
"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 ]
dlarudgus20
Member
Member
Posts: 36
Joined: Sat Oct 26, 2013 4:14 am

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

Post 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.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

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

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