When say 3 programs (executables) are loaded into memory the layout might look something like this:
alt text http://img97.imageshack.us/img97/3460/processesm.jpg
I've following questions:
Is the concept of Virtual Memory limited to user processes? Because, I am wondering where does the Operating System Kernel, Drivers live? How is its memory layout? I want to know more about kernel side memory. I know its operating system specific make your choice (windows/linux).
Is the concept of Virtual Memory per process basis? I mean is it correct for me to say 4GB of process1 + 4GB of process2 + 4GB of process3 = 12GB of virtual memory (for all processes). This does't sound right. Or from a total of 4GB space 1GB is taken by kernel & rest 3GB is shared b/w all processes.
They say, on a 32 bit machine in a 4GB address space. Half of it (or more recently 1GB) is occupied by kernel. I can see in this diagram that "Kernel Virtual memory" is occupying 0xc0000000 - 0xffffffff (= 1 GB). Are they talking about this? or is it something else? Just want to confirm.
What exactly does the Kernel Virtual Memory
of each of these processes contain? What is its layout?
When we do IPC we talk about shared memory. I don't see any memory shared between these processes. Where does it live?
Resources (files, registries in windows) are global to all processes. So, the resource/file handle table must be in some global space. Which area would that be in?
Where can I know more about this kernel side stuff.
When a system uses virtual memory, the kernel uses virtual memory as well. Windows will use the upper 2GB (or 1GB if you've specified the /3GB switch in the Windows bootloader) for its own use. This includes kernel code, data (or at least the data that is paged in -- that's right, Windows can page out portions of the kernel address space to the hard disk), and page tables.
Each process has its own VM address space. When a process switch occurs, the page tables are typically swapped out with another process's page table. This is simple to do on an x86 processor - changing the page table base address in the CR3
control register will suffice. The entire 4GB address space is replaced by tables replacing a completely different 4GB address space. Having said that, typically there will be regions of address space that are shared between processes. Those regions are marked in the page tables with special flags that indicate to the processor that those areas do not need to be invalidated in the processor's translation lookaside buffer.
As I mentioned earlier, the kernel's code, data, and the page tables themselves need to be located somewhere. This information is located in the kernel address space. It is possible that certain parts of the kernel's code, data, and page tables can themselves be swapped out to disk as needed. Some portions are deemed more critical than others and are never swapped out at all.
See (3)
It depends. User-mode shared memory is located in the user-mode address space. Parts of the kernel-mode address space might very well be shared between processes as well. For example, it would not be uncommon for the kernel's code to be shared between all processes in the system. Where that memory is located is not precise. I'm using arbitrary addresses here, but shared memory located at 0x100000
in one process might be located at 0x101000
inside another process. Two pages in different address spaces, at completely different addresses, can point to the same physical memory.
I'm not sure what you mean here. Open file handles are not global to all processes. The file system stored on the hard disk is global to all processes. Under Windows, file handles are managed by the kernel, and the objects are stored in the kernel address space and managed by the kernel object manager.
For Windows NT based systems, I'd recommend Windows Internals, 5ed by Mark Russinovich and David Solomon
Response to comment:
And now this 3GB is shared b/w all processes? or each process has 4GB space?
It depends on the OS. Some kernels (such as the L4
microkernel) use the same page table for multiple processes and separate the address spaces using segmentation. On Windows each process gets its own page tables. Remember that even though each process might get its own virtual address space, that doesn't mean that the physical memory is always different. For example, the image for kernel32.dll
loaded in process A is shared with kernel32.dll
in process B. Much of the kernel address space is also shared between processes.
Why does each process have kernel virtual memory?
The best way to think of this is to ask yourself, "How would a kernel work if it didn't execute using virtual memory?" In this hypothetical situation, every time your program caused a context switch into the kernel (let's say you made a system call), virtual memory would have to be disabled while the CPU was executing in kernel space. There's a cost to doing that and there's a cost to turning it back on when you switch back to user space.
Furthermore, let's suppose that the user program passed in a pointer to some data for its system call. This pointer is a virtual address. You've got virtual memory turned off, so that pointer needs to be translated to a physical address before the kernel can do anything with it. If you had virtual memory turned on, you'd get that for free thanks to the memory-management unit on the CPU. Instead you'd have to manually translate the addresses in software. There's all kinds of examples and scenarios that I could describe (some involving hardware, some involving page table maintenance, and so on) but the gist of it is that it's much easier to have a homogeneous memory management scheme. If user space is using virtual memory, it's going to be easier to write a kernel if you maintain that scheme in kernel space. At least that has been my experience.
there will be only one instnace of OS kernel right? then why each process has seperate kernel virtual space?
As I mentioned above, quite a bit of that address space will be shared across processes. There is per-process data that is in the kernel space that gets swapped out during a context switch between processes, but lots of it is shared because there is only one kernel.