Virtual memory to physical memory - linux

I'm working with a trustzone (ARM) and unlike memory access in linux, the trusted applet does not have access to the virtual-physical memory mapping. It deals strictly with physical memory.
How would I go about translating from virtual to physical addresses?

So if i understand you don't know which memory area your application can use as it is detached from the virtual address space set in the CPU?
In my opinion you have only two choices:
Somehow tell the OS that a section of memory (physical) is reserved for the application. Let's say from 0xfff0 to 0xffff
The Page Table with the mapping is usually at the end of the kernel in memory. Try to get that address and you can search it for a free adress space (memory block).

Related

Is it possible to partially virtualize the physical address space?

I'm currently working on systems that include embedded Linux and FPGAs. We've various IP cores that support the AXI-Bus. To communicate with the IP cores of PL (programable logic), we need to map them onto the address space of the PS (processing system). For example, for the widely used Zynq PS the address space is as follows (UG585 - Section 4.1: Address Map)
0x0000_0000 to 0x7FFF_FFFF: Mapped to the physical memory. Either external DDR or on-chip memory
0x8000_0000 to 0xBFFF_FFFF: Mapped to the PL explained above
0xE000_0000 to 0xFFFF_FFFF: Various other devices on the chip
As you can see, only the first 1GB of the address space is reserved to the physical memory, and the rest is occupied by the devices either in PL or PS. So, if possible, the virtualization range can be applied only for the first 1GB to allow faster access to devices on the chip by skipping the MMU.
I know that by doing such a modification we allow any kind of process to access the physical devices of the system without any control of its privileges. So, the questions are
Is it possible to partially virtualize the physical address space in Linux or any other OS?
If it is possible, would it be rational to do it?

Virtual Memory and Virtual Address in Linux

I am currently studying about virtual memory in operating system and I have few questions.
Is swap partition or swap file same as virtual memory in terms of Linux?
If yes, then in case I've no swapping enabled in my Linux system, does that mean my system has no virtual memory?
I have also read that virtual memory makes system more secure because with virtual memory, CPU generates virtual addresses which are then translated to actual physical addresses by MMU, therefore securing the system because no process can actually interact with the actual physical memory. So if I just enable swapping on my Linux system, will my CPU start generating virtual addresses and currently it's directly generating physical addresses as I have no swap partition?
How does CPU know if virtual memory is present or not?
Having no swap file/partition doesn't imply that you don't have virtual memory. Modern operating-systems always use paging/virtual memory no matter what.
Is swap partition or swap file same as virtual memory in terms of Linux?
No swap file and virtual memory is not the same in terms of any OS. Virtual memory just says that all memory accesses are going to be translated by the MMU using the page tables. Modern OSes always use paging.
If yes, then in case I've no swapping enabled in my Linux system, does that mean my system has no virtual memory?
Your system certainly has virtual memory. To use long mode (64bits mode), the OS must enable paging. I doubt that you have a system old enough to not use paging. Page swapping to the hard-disk is not virtual memory. It is more like a feature of virtual memory that can be used to extend physical memory because a page which isn't required immediatly can be swapped to the hard-disk momentarily.
I have also read that virtual memory makes system more secure because with virtual memory, CPU generates virtual addresses which are then translated to actual physical addresses by MMU, therefore securing the system because no process can actually interact with the actual physical memory. So if I just enable swapping on my Linux system, will my CPU start generating virtual addresses and currently it's directly generating physical addresses as I have no swap partition?
Your computer certainly has paging/virtual memory enabled. Having no swap partition doesn't mean that you don't have virtual memory. Paging can also be used to avoid fragmentation of RAM and for security. You are right that paging is securing your system because the page tables prevent a process from accessing the memory of another process. It also has ring privilege on a page to page basis which allows to differentiate between kernel mode and user mode code.
How does CPU know if virtual memory is present or not?
The OS just enables paging by setting a bit in a control register. Then the CPU starts blindly translating every memory accesses using the MMU.
No. Swap file is not the same as virtual memory.
Once the firmware/kernel sets up the necessary registers and/or in-memory data structures and switches the processor mode, virtual memory mappings are used for accessing the physical memory.
Yes, the inability of processes to refer to memory locations without a mapping allows the kernel to employ isolation and access control mechanisms.
Through active mappings, different virtual addresses can map to the same physical memory region at different times. The kernel can maintain the illusion that a larger amount of memory is available that the capacity of the actual physical memory, where only a subset of the virtual memory resides in the physical memory at any given time. The rest is stored in the swap file.
Accesses to virtual addresses where the corresponding data is currently in the swap file are trapped by the kernel (via a page fault) and might lead to the kernel swapping the data in, and swapping some other data from physical memory out.
If you disable the swap file, the kernel has no place store the swapped out data. This reduces the amount of virtual memory available.

Windows Program Memory Vs Linux Program Memory

Linux creates virtual memory pages for every program to use, and the OS handles mapping the virtual addresses to genuine hardware addresses, correct?
But how does Windows do this? Do Windows programs actually have memory that translates to real hardware addresses? I'm also aware that windows can use hard disk memory when RAM is over used, and this process is again called virtual memory, but I believe this is an entirely different concept?
Windows and Linux (at least on Intel 32/64 bit systems) both implement virtual memory using the same mechanism: hardware supported page tables. The OS and the hardware cooperate together to do the address mapping.
The entire concept of separating the logical addresses a program uses from the physical addresses is what is called virtual memory. The use of the hard disk as a backing store is an implementation of virtual memory that uses a swap file to increase the amount of virtual memory to an amount greater than the physical memory installed in the system.
Virtual memory is a pretty deep and wide subject. Maybe start with this Wiki article an Memory Management and then hit the googles for a deeper understanding.

In linux kernel what is difference between page address, virtual address and physical address

In linux kernel what is difference between page address, virtual address and physical address? Also if I have struct page address how can I find its virtual address?
Could someone please explain it clearly with respect to Linux kernel version 3.10.
Thanks in advance for your answers.
A physical address is the address in RAM. Once you reach the limit of physical memory available, the kernel has to allocate somewhere, and that place is the virtual address space. Virtual memory is mapped such that you have much more available than you have physical memory, and this is done by breaking virtual memory into chunks called pages.
Each virtual address is mapped to a location in physical memory, where there is a 1 to many relationship between physical to virtual addresses i.e., there are many virtual addresses that map to the same physical location. This mapping is done by address translation in the page table.
A page is the smallest unit of virtual memory. The page size varies depending on architecture and implementation, but on x86 for Linux it is 4 KiB. When working with virtual memory, you must read the entire page, not just a chunk. When you say "page address", you may be referring to the index within a page where a specific virtual address can be found.
While fact-checking my answer, I came across some good pages that might help you understand virtual memory a little better. The first 2 are Wikipedia and fairly general, and the last two are Linux specific:
Virtual Memory
Paging
Memory Management for Linux page 1 and page 2

Linux allocates memory at specific physical address

I am testing a PCI Endpoint driver, I would like to do simple copy from the PCI RootPort side to the PCI Endpoint side. In PCI Endpoint side, we have address translation from PCI address to CPU physical address. We can configure the CPU physical address in the translation so that it maps to the specific DRAM region. The problem is how can we allocate a memory buffer at that specific CPU physical address to make sure the write from RootPort side really works?
Any recommendations are appreciated. Thanks a lot!
You need to first reserve the physical memory area. The easiest but ugly way to do that is to pass a "mem=" parameter to the kernel command line that precludes the physical memory range you are interested in from kernel memory management and then use ioremap() to get a virtual mapping of that.
For example if your machine has 256 Mb of RAM use mem=255M to reserve the last Mb to your uses and then map it via ioermap()
NOTE: original answer fixed based on feedback from #Adrian Cox.
If you can remap the translation on the fly, then you should work like any driver that uses DMA. Your basic reference for this is Chapter 15 of LDD3, plus the Linux DMA API.
What you are allocating is a DMA coherent buffer, via dma_alloc_coherent. On most platforms you should be able to pass in a null struct device pointer and get a generic DMA address. This will give you both a kernel virtual address to access the data, and a dma address which is the CPU physical address to map through your translation layer.
If your address translation is not very flexible, you may need to modify the platform code for your endpoint to reserve this buffer early on, in order to meet address alignment requirements. This is a bit more complicated, but there is an update of the bigphysarea patch to recent kernels that may help as a starting point.

Resources