Been looking around for answers but none come out satisfying so far, and very often misleading with mixed-up terminologies. Now here's the thing... Physical Memory is the kind of memory;
i. as seen by the CPU as the final memory on its address bus. That means it has already passed the MMU translation / paging, right?
ii. calculated based on the address bus width. If it is 48-bit wide, than it should be 256TB of physical memory addresses available for the system, right?
Now my question;
If I have 8GB of RAM, how on earth the much larger physical memory addresses generated by the CPU are mapped to the physical RAM? What translation unit is there between the Physical memory and the available RAM? From what I read, physical RAM has already passed the virtual / MMU translation phase.
And no, I am not talking about virtual memory. I am asking about the relationships between the physical memory (the one that appears on the CPU address bus) and the actual physical RAM.
Thanks.
Related
I was reading the textbook:Computer Systems A Programmer’s Perspective, in chapter 9.7.2:Linux Virtual Memory System (third edition) that talks about virtual memory.
I was a bit confused by the structure of virtual memory for linux process as shown below:
My question is: does kernel virtual memory preserve for kernel to run
and rest of the virtual memory preserve for user process? What does kernel code and data do? And what does the physical memory in kernel virtual memory?
does kernel virtual memory preserve for kernel to run and rest of the virtual memory preserve for user process?
Yes, there is a part of virtual memory that is always reserved for the kernel and another part that is left available to userspace processes. Every single process has its own virtual memory, but the kernel is always mapped in the higher part (higher addresses) of virtual memory. Whether or not this mapping is visible to the process depends on Kernel Page Table Isolation.
See also: Do the virtual address spaces of all the processes have the same content in their “Kernel” parts?
What does kernel code and data do?
Part of the high virtual memory is a direct mapping of the actual kernel image. That is, the kernel executable and all its data. You can see it in more detail here in this page of the kernel documentation, marked as "kernel text mapping, mapped to physical address 0".
See also: What's the use of having a kernel part in the virtual memory space of Linux processes?
And what does the physical memory in kernel virtual memory?
That part of the image is totally misleading. I don't know precisely what information the authors of the book were trying to convey, but physical memory is definitely not a part of kernel virtual memory. They were probably trying to address the fact that there is a direct mapping of all physical memory in the kernel virtual memory, which can be seen again on the same page of the kernel documentation, marked as "direct mapping of all physical memory".
Physical memory refers to the real memory of the system (i.e. the RAM). Each region of virtual memory is mapped to some region of physical memory. This virtual-to-physical mapping is totally transparent to processes and is managed by the kernel. For example, two executables that have the same file open in read-only mode are usually sharing the same physical memory region, while seeing two different virtual address.
This is a more accurate depiction of the relationship between virtual and physical memory:
Source: https://computationstructures.org/lectures/vm/vm.html
cited from the CSAPP book, 3rd version, section 9.7.2, where the picture is shown.
Interestingly, Linux also maps a set of contiguous virtual pages (equal in size to the total amount of DRAM in the system) to the corresponding set of contiguous physical pages. This provides the kernel with a convenient way to access any specific location in physical memory—for example, when it needs to access page tables or to perform memory-mapped I/O operations on devices that are mapped to particular physical memory locations.
I think the Physical memory in the picture just reflects what's described above: a virtual memory area that maps to the entire physical memory.
In a systems memory map (also called cpu memory map) the address ranges are allocated for RAM memory ranges, MMIO for PCI devices etc.
Lets take an example where address ranges for RAM is started from address 0 to upto 512MB which includes DOS compatibility memory space starts from 0 and goes upto 1MB.
Now when we say that this 512MB of region will be mapped into the memory, does this mean that the address 0 in the CPU address space will be mapped to address 0 in the Physical RAM and the same goes up to 512MB? If not then how the mapping is done?
Also does the memory address ranges allocated in CPU address space will be exactly equal to the size of the RAM installed in the system? If its not the case then how the mapping would take place in such case?
Also how will memory mapping of DOS compatibility region be done? Does this region will be unused into the memory if using an OS other than DOS?
Also does the memory mapping means that when the CPU generates the address from 0 to 512 MB only will be redirected into the RAM ? Any other address generated by CPU will never be directed into the RAM by MMU ? In such case all the application would have the address between ranges from 0 to 512MB inorder to access the Memory ?
I'm considering an x86 system here.
Before going into the question, it's worth taking a look into DRAM architecture.
Now when we say that this 512MB of region will be mapped into the memory, does this mean that the address 0 in the CPU address space will be mapped to address 0 in the Physical RAM and the same goes up to 512MB? If not then how the mapping is done?
There isn't exactly a concept of 'address 0' in DRAM, instead, there is an architecture of channels, DIMM, ranks, chips, banks, rows and columns, and the DRAM controller generates 'commands' that activates parts of the DRAM and selects data from the cells:
So the answer to the first question is no. As other people mentioned, the exact mapping is complicated and undocumented. If you are interested, AMD does provide documentation (Section 2.10 and 3.5), and there are attempts of reverse engineering Intel's mapping (Section 4).
Also does the memory address ranges allocated in CPU address space will be exactly equal to the size of the RAM installed in the system? If its not the case then how the mapping would take place in such case?
The answer is also no for many reasons. You answered one of them: the physical address space represents more than just RAM/memory, there are also PCIe devices, ROM (where BIOS is located), etc, and thus there are memory holes. To inspect what does the physical address correspond to in the system, in Linux take a look at /proc/iomem, as it has the mappings.
Also how will memory mapping of DOS compatibility region be done? Does this region will be unused into the memory if using an OS other than DOS?
Yes, I believe these are unused memory holes.
Also does the memory mapping means that when the CPU generates the address from 0 to 512 MB only will be redirected into the RAM ? Any other address generated by CPU will never be directed into the RAM by MMU ? In such case all the application would have the address between ranges from 0 to 512MB inorder to access the Memory ?
MMU serves a completely different purpose. Take a look at virtual address to physical address translation.
As far as I know , the paging system do eliminate external fragment in physical address space, but what about fragment in virtual address space?
In modern OSes the virtual address space is used per process (the kernel has it's own dedicated virtual range), which means that the demands are much lower compared to the whole OS. The virtual address space is usually large enough (2-3 GB per process on x86 and multiple TB (8 on Windows) on x64 machines), so that fragmentation is not such a big issue as for the OS-wide physical address space. Still the issue can arise, especially for long running and memory hungry applications on x86 or other 32 bit architectures. For this the OS provides mechanisms, for example in form of the heap code. An application usually reserves one or more memory ranges as heap(s) when it starts and allocates the required chunks of memory from there later (e.g. malloc). There are a varity of implementations that handle fragmentation of the heap in different ways. Windows provides a special low-fragmentation heap implementation that can be used, if desired. Everything else is usually up to the application or it's libraries.
Let me add a qualification to your statement. Paging systems nearly eliminate fragmentation in the physical address space when the kernel is pageable.
On some systems, the user mode page tables are themselves pageable. On others, they are are physical locations that are not pageable. Then you can get fragmentation.
Fragmentation in the virtual address space tends to occur in heap allocation. The challenge of heap managers is to manage the space while minimizing fragmentation.
I have been reading about how the PCI subsystem gets configured from Bootup, BIOS involvement and mapping of device addresses i.e the BAR's into system Memory.
From the diagram above I am assuming that the address space is physical 4GB RAM with 4GB physical addresses. So, As can be seen above 3GB the device memory is mapped. What happens to this memory on 2GB physical RAM addresses.
If suppose my assumption is wrong and the above map shows virtual address for a 32 bit system. Then how is the device memory mapped to physical addresses for DMA. Is the mapping permanent (non swappable and changeable).
Please help me understand this concept.
If I understand your question, nothing different happens on a 2GB system. There will simply be a "hole" in the physical address space between 2GB and 3GB; that is, there simply won't be a hardware device decoding the addresses here. But otherwise there is no significant difference with respect to PCI devices: they will still be assigned space in the region above 3GB.
It's important to note that the map you show above (physical address space) doesn't necessarily stop at 4GB (since about 1995). Most modern x86 processors have more than 32 address bits. This is why you now often get systems with more than 4GB RAM. And there may be additional holes in the address space above 4GB too.
Actually using the RAM above 4GB requires either the processor's 64-bit mode or PAE (Physical Address Extension) which offers a way to address more than 4GB of physical space in 32-bit mode. [There is also PSE-36 {Page Size Extension} but that's much less commonly used.]
The map you're showing above is specific to physical address space. The x86 virtual address space, (when the processor is operating in 32-bit mode) is 4GB in size, but it does not have all the reserved areas in your diagram. Indeed, the layout of the virtual address space is totally dependent on and determined by the operating system. The usual way that it's configured in linux reserves the part of the virtual address space below the 3GB line for user-mode, and the area above 3GB for kernel-mode. However, this configuration can be changed via the kernel config.
Mapping of the physical address space into virtual address space is managed by the operating system kernel on a page by page basis. A virtual page may be directed either to system RAM or to a PCI device. And note that the page size can vary too, depending on how the processor and page tables are configured.
I thought that virtual address space was a section of RAM allocated to a specific process. But the book I'm reading says that 4 gbs is the standard limit of virtual address space. Isn't that the entire amount of RAM? If that is the case then I'm confused at what virtual address space is. Can anyone enlighten me?
That's the whole point of virtual addresses: The OS handles the physical memory, the process handles its own, virtual memory which is mapped to any memory the OS has available, not necessarily RAM.
On a 32 bit operating system the virtual address space (VAS) is, as you say, usually 4 GiB. 32 bits give you (2^32) addresses (0 ... (2^32)-1), each addressing one byte.
You could have more or less physical RAM and still have a 4-GiB-VAS for each and every process running. If you have less physical RAM, the OS would usually swap to harddrives.
The process doesn't need to know any of this, it can use the full VAS it is given by the OS and it's the OS' job to supply the physical memory.
(This is actually just a dumbed-down version of the Wikipedia article on VAS.)