views:

101

answers:

5

Hi. As is widely known, a program running under 32-bit Windows OS has only 2GB of virtual memory available. Also it is known that the other 2GB are reserved as Kernel space. But what is actually in that kernel space?

I could understand reserve needed for kernel itself, but why kernel space in VAS of process? Thanks.

+7  A: 

Get the Windows Internals book, it describes this in gory detail. For the short summary though, some things that are in the kernel virtual address (KVA) space:

1) The kernel and HAL

2) The device drivers

3) The kernel mode heaps (called the executive pools, which I always find amusing)

4) The objects exported to user mode via handles (process, thread, event, mutex, etc. objects)

5) System PTEs, which map all kinds of interesting things away from the grubby user mode apps (e.g. the execution stacks that threads use when running in kernel mode)

6) The file system cache

And the list goes on and on...Like I said, read Windows Internals.

-scott

snoone
Don´t tak me wrong, but for example kernel would be located outside of process VAS. Device drivers as well. Maybe you misunderstood my question. I explicitly mean 2GB that are reserved for OS use referenced as Kernel, but are inside proces VAS. Many things on your list would be off that space.
B.Gen.Jack.O.Neill
@b-gen-jack-o-neill: That 2GB is actually a mapping of the kernel's own memory - containing all of the things mentioned in this answer. It is mapped identically in every process.
caf
caf is correct, that *is* what the 2GB is. Everything I mentioned is in that 2GB mapped into every process.-scott
snoone
+1  A: 

Program written in high-level language, like C++, is finally translated to OS API calls, specifically, Windows API for Windows OS. Many Windows API, like CreateFile, are actually talk with kernel-mode drivers. Kernel space in the process address space is used for allocating kernel resources for this process. For example, driver IOCTL calls contain input-output buffers, passed between user-mode API and driver. Such buffers are allocated in the process kernel space.

Generally, kernel space contains resources allocated by kernel-mode components on behalf of this process.

Alex Farber
Also very nice answer. So in kernel adress space are contain process vital structes needed for driver to properly designate and commnicate with your app?
B.Gen.Jack.O.Neill
@b-gen - You're making this overly complicated on yourself and some of these comments aren't helping (I've deleted a bunch of responses before settling on just writing this one). Just get the Windows Internals or any driver development book and read it. If something isn't clear there, ask specific questions. It's going to serve you better to do it right.
snoone
+1  A: 

Your question seems to be "why" not "what" as put forward in the title.

Also, your question presumes 32-bit. 64-bit versions of windows are quite different (for example, the VAS is 8TB, or 7TB on an itanium system).

As for "why", how would you pass pointers from a kernel function (like a driver) that are not contained in the VAS of the process? A good book to read to figure this out would be Windows Internals.

Philip Rieck
I like your answer. OK, so you say its partially for example to pass variable blocks thru page change in CPU MMU thus evading process adress space? So the limit is to prevent dismissing any valid process page?
B.Gen.Jack.O.Neill
+2  A: 

In my opinion there is another little known fact about the 2GB boundary. Many applications typically work with lots of pointer arithmetic (especially applications written in C, C++, ...). In these applications it is quite common to add offsets to pointers, or even to subtract pointers.

If your available virtual address space is 2GB, you are guaranteed that subtracting two pointers is always between -2147483647 and +2147483648 (these are the limits for 32-bit signed values).

If your address space would be 3GB, the possible difference would be bigger than any value that can be represented in a 32-bit signed value.

If you know that your application is safe, and not subtracting totally unrelated pointers (and your arrays are less than 2GB!), you can tell Windows that your application can work with an address space larger than 2GB, by setting the linker flag LARGEADDRESSAWARE (or set this with the EDITBIN utility).

With XP (not quite sure about Vista and W7) you can boot into a mode where the 'kernel space' is only 1GB, and 3GB in the virtual address space is left for the application. If your application is LARGEADDRESSAWARE, you get the full 3GB. If not, you only get 2GB.

On 64-bit Windows, LARGEADDRESSAWARE 32-bit applications even get 4GB, since Windows does not need substantial address space in the 32-bit area (after all, it's a 64-bit OS).

Patrick
In 64-bit apps, the LARGEADDRESSAWARE flag is set by default. The amount of address space that gets you depends a bit on your Windows version and edition. (In Win7 Pro, you can have up to 8TB, but you can only have 192GB of actual memory in the system - the rest would have to be swap or mapped files.)
cHao
+2  A: 

The reason that kernel memory is mapped into the virtual address space of every process is so that a context switch into kernel mode does not have to change the process page tables. The current privilege level is merely lifted to 0, which immediately makes those pages accessible.

The page tables only have to be switched when a different process is switched to. Since this is an expensive operation (eg. it requires a TLB flush), minimising the frequency of it is a win.

Additionally, if you did switch in special kernel page tables went you switched to kernel space, you'd have to pick a part of the userspace address space to replace. This would make those userspace addressess inaccessible to the kernel, which would necessitate bounce buffers or more address space mucking about when data in those areas was to be transferred to or from the kernel.

caf