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.
To answer your question, you need to understand more about Kernel and the techniques it employs to manage resources (CPU, memory, ...) and to provide elegant abstraction to the Application programs.
Firstly i want to make it clear that 'Virtual Memory' is a memory management technique employed by modern operating systems; which provides various benefits like process isolation, there by protection, allows multiple programs to run together, allows programs whose size is larger than the physical memory present in the system.
Under this technique, again there are two terms 'Virtual Memory' and 'Virtual Address Space'; which are not same, but still closely related.
(You would be wondering how is Virtual memory is both a technique as well as a concept under it, but yes that is correct and you will understand that below)
In computer science, the word 'memory' has 2 meanings. First one, is for something that you can use to store data (registers, cache, RAM, ROM, HDD, etc). Second one, is for synonymous with primary memory (i.e., RAM).
When you replace word by word, 'Virtual Memory' is nothing but 'Virtual RAM'. That is the total amount of space available at all times in the system, in which the programs are loaded for execution. So this is nothing but Physical RAM memory + the swap memory on the secondary storage allocated by the kernel.
So if you have 2GB of RAM and 4 GB of swap space set aside by kernel at installation time, then the Virtual memory of your system is 6GB. I am not going to explain more on the swap memory here, as this would deviate more from the topic.
Moving on to Virtual Address Space.
So to understand this you need to tune your mind a bit. As the name itself "Virtual" says, the address space is not present in reality! This is just an illusion created by kernel to the application programmers (to achieve lot of benefits as i mentioned in paragraph 2)
So each process is given a separate virtual address space by the kernel. (If there was no Kernel in the system and had you run your application program on the hardware then it would have used the physical address space, i.e., RAM as its address space)
So on a machine with 32 bit address registers, the kernel could provide a virtual address space of 2^32 = 4GB for each process. (So this virtual address space range changes with the HW architecture. Latest processors have 48 bit address registers so they can provide a virtual address space of 2^48 = 256TB)
And importantly this virtual address space is just in the air!! You would be thinking now, if it is just in the air, how can the code, data of the process be even executed. Yes, this need to be mapped to physical memory. How it is mapped with the physical memory is managed by kernel using the concept called paging.
So now you can see how the kernel has achieved process isolation using virtual address space. So the address that each process can generate is between 0 to 4GB (assuming the system has 32 bit address register for simplicity sake), so which is within its entirety. And it knows nothing about any other process running in the system. So it is like each process is packed in a separate space.
So kernel code is also like another process/entity. So if kernel were to reside in an entirely different address space. Then there was no means for an application programs to interact with kernel. If application cant communicate with kernel and kernel cant communicate with application then there is no usefulness of the kernel to drive the system.
So the question now is - How to make application processes to interact with the kernel?
An option would be - If kernel code was present in the virtual address space of the application process then they could interact with each other. That's the reason why kernel code is present in each of the process' virtual address space because every process need to communicate with the kernel. Don't worry kernel code is not physically duplicated for each process. As i mentioned earlier VAS is just an illusion, so there will be just one copy of kernel code present in physical memory and it will be reference by all of the virtual address spaces (through paging).
In case of linux, kernel would be placed on the upper address space between C000 0000 to FFFF FFFF (ie the reason 1GB is reserved for kernel in VAS) and rest 3GB (from 0000 0000 to BFFF FFFF) is allowed for the application program to use. The virtual address space where kernel resides is known as kernel space and where the application program resides is called user space.
If you had carefully observed, then you would have come up with the question that if both application code and kernel code is residing in the same virtual address space, and since the kernel resides in a well pre-defined address location then is it not possible for the application code to corrupt the kernel code! Oops, at first it looks to be possible, but it can't.
Reason being - this is protected using the help of HW. There will be flag on the processor which indicates whether the execution mode is SUPERVISOR MODE or USER MODE. Kernel space code should execute in SUPERVISOR MODE (setting that flag appropriately) and user space code should execute in USER MODE. So if you are in USER MODE and tries to access/modify code in kernel space then an exception is thrown! (processor gets to know it based on the address the instruction is trying to access. If it is higher than C000 0000 then it can easy detect it is trying to access kernel space code and the current execution mode doesn't have appropriate permission, since the flag is set with USER MODE permission). Just a note: In SUPERVISOR mode, processor provides access to additional set of instruction set.
I hope if you understand this concept you could answer yourself for your question. I have answered directly for many of your questions while explaining the concept itself.