What is the purpose of logical address? Why should CPU generate logical address? it can directly access relocatable register base address and limit to exe a process. Why should MMU make a mapping between logical and physical address?
Why?
Because this gives the Operating System a way to securely manage memory.
Why is secure memory management necessary?
Imagine if there was no logical addressing. All processes were given direct access to physical addresses. A multi-process OS runs several different programs simultaneously. Imagine you are editing an important letter in MS Word while listening to music on YouTube on a very recently released browser. The browser is buggy and writes bogus values to a range of physical addresses that were being used by the Word program to store the edits of your letter. All of that information is corrupt!
Highly undesirable situation.
How can the OS prevent this?
Maintain a mapping of physical addresses allocated to each process and make sure one process cannot access the memory allocated to another process!
Clearly, having actual physical addresses exposed to programs is not a good idea. Since memory is then handled totally by the OS, we need an abstraction that we can provide to processes with a simple API that would make it seem that the process was dealing with physical memory, but all allocations would actually be handled by the OS.
Here comes virtual memory!
The need of logical address is to securely manage our physical memory.
Logical address is used to reference to access the physical memory location.
A logical address is generated so that a user program never directly access the physical memory and the process donot occupies memory which is acquired by another process thus corrupting that process.
A logical address gives us a surety that a new process will not occupy memory space occupied by any other process.
In execution time binding, the MMU makes a mapping from logical address to physical address because in this type of binding:
logical address is specifically referred to as virtual address
The address actually has no meaning because it is there to illusion the user that it has a large memory for its processes. The address actually bear meaning when mapping occurs and they get some real addresses which are present in physical memory.
Also I would like to mention that the base register and limit register are loaded by executing privileged instructions and privileged instructions are executed in kernel mode and only operating system has access to kernel mode and therefore CPU cannot directly access the registers.
So first the CPU will generate the logical address then the MMU of Operating system will take over and do the mapping.
The binding of instruction and data of a process to memory is done at compile time, load time or at execution time. Logical address comes into picture, only if the process moved during its execution time from one memory segment to another. logical address is the address of a process, before any relocation happens(memory address = 10). Once relocation happened for a process(moved to memory address = 100), just to redirect the cpu to correct memory location=> memory management unit(MMU), maintains the difference between relocated address and original address(100-10 = 90) in relocation register(base register acts as relocation register here) . once CPU have to access data in memory address 10, MMU add 90(value in relocation register) to the address, and fetch data from memory address 100.
Related
I understand that every process in a computer has an address space, which contains addresses for all the instructions of the process. I also understand that this address is a virtual one - meaning it maps to the physical RAM addresses, and doesn't actually exist.
When a process is to be executed, the CPU sends the MMU the virtual address of the instruction (the page I guess?) that it needs, and then MMU can provide the physical address of it in RAM, which is what the CPU fetches to execute the instruction.
What I don't get is who assigns that virtual address to the process in the first place - how does the CPU know the virtual address? I get that these virtual addresses are generic (I read: Difference between logical addresses, and physical addresses?, and it was very helpful in that aspect), but I don't get who assigns that to begin with. Where even are the page tables stored, and why is the swap space needed?
I've been trying to understand memory mapping for a few days now, mostly through youtube videos, but if anyone knows any good sources I'd really appreciate it!
On older time with virtual address, you have a fixed layout: some data at beginning, the program, the program data, libraries, and than stack. Sometime Kernel had the last bytes reserved. Note: ometime with different layout, but usually same structure on the same OS/version. We had also the possibility to prelink libraries, so you can have quick loading time. Virtual address allow this.
Now it is the kernel that randomize the addresses (to reduce the success rate of buffer overflow attack). So you may have libraries and programs in random places. It is not the MMU, the kernel choose the virtual addresses randomly.
So now you have the virtual address. Now the kernel should assign it to something. If you clone, the virtual address point to the parent process, or when you execute the program, your virtual address point to disk (where the binary reside), and some (the rest, and maybe some guard) are just unassigned, so that program will get a segmentation fault (really a protection exception of CPU). This "physical pointer" could change. Because of swapping the physical address could change, or the pointer could point to different part of disk, but also you may point to old process memory, and then to your modified memory, or to different part of disk.
So virtual addresses are defined by kernel and kernel will handle it (either having a physical address, or an exception, which kernel may check a different source [other process memory, disk]). If the page (virtual address block) has linked a physical address, it is the MMU which do the works (and updating also access count of the page), else it is the kernel (and so much slower).
In a modern PC, where will
MOV [0x0000], 7
put a 7? Is it the first byte of my RAM, or is it the first byte of the process's address space? Assuming it triggers a memory violation.
You mean assuming it doesn't trigger an access violation? Every process has it's own virtual address space. The first 64kiB are normally kept unmapped, so NULL-pointer accesses actually fault noisily, instead of letting programs silently do Bad Things.
In a user-space process on a typical OS, an absolute address of 0 does refer to the first byte of your process's virtual address space.
With paging enabled, there's no way even for the kernel to use physical addresses directly. To write to a given physical address, would have to create a page table entry mapping that physical page to a virtual page (or find an existing mapping), invlpg to make sure the TLB isn't caching a stale entry, and then use that virtual address.
it depends on the system architecture. Every architecture provides an instruction set and a memory layout. Furthermore it depends on the operating system you use. E.g. Real Time Operating systems often do not provide Virtual Memory.
greets
I'm aware that in most modern architectures the CPU sends read and write requests, to a memory management unit rather than directly to the RAM controller.
If other peripherals are also addressed, that is to say, read from and written to using an address bus, then are these addresses also accessed through a virtual address? In other words, to speak to a USB drive etc. does the CPU send the target virtual address to an MMU which translates it to a physical one? Or does it simply write to a physical address with no intermediary device?
I cant speak globally there may be exceptions. But that is the general idea, that being that the cpu memory interface goes completely through the mmu (And completely through a cache or layers of caches).
In order for peripherals really to work (caching a status register on the first read then subsequent reads getting the cached version not the real version) you have to set the address space for the peripheral to be not cached. So for example on an arm and no doubt others where you have separate i and d cache enables, you can turn on the i cache without the mmu, but to turn on the d cache and not have this peripheral problem you need the mmu on and the peripheral space in the tables and marked as not cached.
It us up to the software designers to decide if they want to have the virtual address for the peripherals match the physical or to move the peripherals elsewhere, both have pros and cons.
It is certainly possible to design a chip/system where an address space is automatically not sent through the mmu or cache, that can make the busses ugly, and/or the chip may have separate busses for peripherals from ram, or other solutions, so the above is not necessarily a universal answer, but for say an arm and I would assume an x86 that is how it works. On the arms I am familar with the mmu and l1 cache are in the core, the l2 is outside and l3 beyond that if you have one. the l2 is literally between the core and the world (if you have one (from arm)) but the axi/amba bus has cacheable settings so each transaction may or may not be marked as cacheable, if not cacheable then it passes right through the l2 logic. if enabled the mmu determines that if enabled on a per transaction basis.
Actually the virtual-to-physical translation is in the CPU for almost all modern (and at this point, even most old) architectures. Even the DRAM and PCIe controllers (previously in the Northbridge) made it onto the CPU. So a modern CPU doesn't even talk to a RAM controller, it directly talks to DRAM.
If other peripherals are also addressed, that is to say, read from and written to using an address bus, then are these addresses also accessed through a virtual address?
At least in the case of x86, yes. You can virtually map your memory mapped IO ranges anywhere. Good thing too, otherwise the virtual address space would necessarily mirror the weird physical layout with "holes" that you couldn't map real ram into because then you'd have two things in the same place.
Consider the following CPU instruction which takes the memory at address 16777386 (decimal) and stores it in Register 1:
Move &0x010000AA, R1
Traditionally programs are translated to assembly (machine code) at compile time. (Let's ignore more complex modern systems like jitting).
However, if this address allocation is completed statically at compile time, how does the OS ensure that two processes do not use the same memory? (eg if you ran the same compiled program twice concurrently).
Question:
How, and when, does a program get its memory addresses assigned?
Virtual Memory:
I understand most (if not all) modern systems use Memory Management Units in hardware to allow for the use of virtual memory. The first few octets of an address space being used to reference which page. This would allow for memory protection if each process used different pages. However, if this is how memory protection is enforced, the original question still persists, only this time with how page numbers are assigned?
EDIT:
CPU:
One possibility is the CPU can handle memory protection by enforcing that a process id be assigned by the OS before executing memory based instructions. However, this is only speculation, and requires support in hardware by the CPU architecture, something I'm not sure RISC ISAs would be designed to do.
With virtual memory each process has separate address space, so 0x010000AA in one process will refer to different value than in another process.
Address spaces are implemented with kernel-controlled page tables that processor uses to translate virtual page addresses to physical ones. Having two processes using the same address page number is not an issue, since the processes have separate page tables and physical memory mapped can be different.
Usually executable code and global variables will be mapped statically, stack will be mapped at random address (some exploits are more difficult that way) and dynamic allocation routines will use syscalls to map more pages.
(ignoring the Unix fork) The initial state of a processes memory is set up by the executable loader. The linker defines the initial memory state and the loader creates it. That state usually includes memory to static data, executable code, writeable data, and the stack.
In most systems a process can modify the address space by adding pages (possibly removing them as well).
[Ignoring system addresses] In virtual (logical) memory systems each process has an address space starting at zero (usually the first page is not mapped). The address space is divided into pages. The operating system maps (and remaps) logical pages to physical pages.
Address 0x010000AA in one process is then a difference physical memory address in each process.
example while writing a driver we do the following
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
We get the info about the memory allocated to the device.
So is it necessary that I use this memory using virtual address
virt_base = ioremap(res->start, resource_size(res));
Can't we use the physical address itself to address the memory?
If we can, so are there any specific advantages of using virtual memory or this is how kernel wants us to do...
Yes, it is absolutely necessary. (On x86) Once paging is enabled in the CPU, all addresses visible to the OS (so you, the driver developer) are virtual addresses. In other words, any address you read from or write to will be interpreted by the CPU as a virtual address. It will then go through the page table hierarchy to finally arrive at a physical address to put on the bus.
You can't use physical addresses - they will not be mapped, or mapped to something other than what you want. This is why ioremap must exist and be used.