{"id":410,"date":"2020-08-18T19:23:47","date_gmt":"2020-08-18T20:23:47","guid":{"rendered":"http:\/\/www.linux-tutorial.info\/?page_id=77"},"modified":"2020-08-22T19:26:41","modified_gmt":"2020-08-22T20:26:41","slug":"this-is-the-page-title-toplevel-243","status":"publish","type":"page","link":"http:\/\/www.linux-tutorial.info\/?page_id=410","title":{"rendered":"Virtual Memory"},"content":{"rendered":"\n<title>Virtual Memory<\/title>\n<p>\n<h3>An Abstract Model of Virtual Memory<\/h3>\n<p>\n<p>\n<img decoding=\"async\" src=\"vm.gif\">s\n<p>\nFigure: Abstract model of Virtual to Physical address mapping\n<p>\n<p>Before considering the methods that Linux uses to support virtual memory it is useful\nto consider an abstract model that is not cluttered by too much detail.\n<p>\nAs the processor executes a program it reads an instruction from memory and decodes it.\nIn decoding the instruction, the processor may need to fetch or store the contents of a location in memory.\nThe processor then executes the instruction and moves on to the next instruction in the program.\nIn this way the processor is always accessing memory either to fetch\ninstructions or to fetch and store data.\n<p>\nIn a virtual memory system all of these addresses are virtual addresses and not physical\naddresses. These virtual addresses are converted into physical addresses by the\nprocessor based on information held in a set of tables maintained by the operating system.\n<p>\nTo make this translation easier, virtual and physical memory are divided into handy sized chunks\ncalled <em>pages<\/em>. These pages are all the same size. They need not be but if they were not,\nthe system would be very hard to administer. Linux on Alpha AXP&nbsp;systems uses 8 KiB pages\nand on Intel x86 systems it uses 4 KiB pages. Each of these pages is given a\nunique number: the page frame number (PFN).\n<p>\nIn this paged model, a virtual address is composed of two parts: an offset and a virtual page\nframe number. If the page size is 4 KiB, bits 1-10 of the virtual address contain the offset\nand bits 12 and above are the virtual page frame number.\nThe processor extracts the virtual page frame number and offset from a virtual\naddress every time it encounters one. Then it matches the virtual page frame number\nto a physical page and uses the offset to specify how far to go into the page.\nThe processor uses <em>page tables<\/em> to match the virtual page frame\nnumber to the physical page.\n<p>\nThe figure above shows the virtual address spaces of two processes, process <em>X<\/em>\nand process <em>Y<\/em>, each with their own page tables.\nThese page tables map each process&#8217; virtual pages into physical\npages in memory. This shows that process <em>X&#8217;s<\/em> virtual page frame number 0 is\nmapped into memory in physical page frame number 1 and that process\n<em>Y&#8217;s<\/em> virtual page frame number 1 is mapped into physical page frame number 4.\nEach entry in the page table contains the following information:\n<ul>\n<p>\n<li>Valid flag.  This indicates if this page table entry (PTE) is valid,\n<li>The physical page frame number that this entry describes\n<li>Access control information.  This describes how the page may be used.\n\tCan it be written to?   Does it contain executable code?\n<\/ul>\n<p>\nThe page table is accessed using the virtual page frame number as an offset.\nVirtual page frame 5 would be the 6th element of the table (0 is the first element).\n<p>\nTo translate a virtual address into a physical one, the processor must first\nwork out the virtual address&#8217; page frame number and the offset within that virtual page.\nBy making the page size a power of 2 this can be easily done by masking and shifting.\nLooking again at the figures and assuming a page size of <em>0x2000<\/em> bytes\n(which is decimal 8192) and an address\nof <em>0x2194<\/em> in process <em>Y&#8217;s<\/em> virtual address space then the processor\nwould translate that address into offset <em>0x194<\/em> into virtual page frame number 1.\n<p>\nThe processor uses the virtual page frame number as an index into the\nprocess&#8217; page table to retrieve its page table entry.\nIf the page table entry at that offset is valid, the processor takes the physical\npage frame number from this entry.\nIf the entry is invalid, the process has accessed a non-existent area of its virtual memory.\nIn this case, the processor cannot resolve the address and must pass control to the\noperating system so that it can fix things up.\n<p>\nJust how the processor notifies the operating system that the correct process has\nattempted to access a virtual address for which there is no valid translation is\nspecific to the processor.\nHowever the processor delivers it, this is known as a <em>page fault<\/em> and the operating\nsystem is notified of the faulting virtual address and the reason for the page fault.\n<p>\nFor a valid page table entry,\nthe processor takes that physical page frame number and multiplies it by the page size\nto get the address of the base of the page in physical memory.\nFinally, the processor adds in the offset to the instruction or data that it needs.\n<p>\nUsing the above example again, process <em>Y&#8217;s<\/em> virtual page frame number 1 is\nmapped to physical page frame number 4 which starts at <em>0x8000<\/em> (4 x <em>0x2000<\/em>).\nAdding in the <em>0x194<\/em> byte offset gives us a final physical address\nof <em>0x8194<\/em>.\n<p>\nBy mapping virtual to physical addresses this way,\nthe virtual memory can be mapped into the system&#8217;s physical pages\nin any order.\nIn the figure above, process <em>X&#8217;s<\/em>\nvirtual page frame number 0 is mapped to\nphysical page frame number 1, whereas virtual page frame number 7 is mapped to physical page\nframe number 0 although it is higher in virtual memory than virtual page frame number 0.\nThis demonstrates an interesting byproduct of virtual memory; the pages of\nvirtual memory do not have to be present in physical memory in any\nparticular order.\n<p>\n<h3>Shared Virtual Memory<\/h3>\n<p>\nVirtual memory makes it easy for several processes to share memory.\nAll memory access are made via page tables and each process has its own separate page table.\nFor two processes sharing a physical page of memory, its physical page frame number must appear\nin a page table entry in both of their page tables.\n<p>\nThe figure above shows two processes that each share physical page frame number 4.\nFor process <em>X<\/em> this is virtual page frame number 4 whereas for process <em>Y<\/em>\nthis is virtual page frame number 6.\nThis illustrates an interesting point about sharing pages: the shared physical page does not\nhave to exist at the same place in virtual memory for any or all of the processes sharing\nit.\n<p>\n<h3>Physical and Virtual Addressing Modes<\/h3>\n<p>\nIt does not make much sense for the operating system itself to run in virtual\nmemory.\nThis would be a nightmare situation where the operating system must\nmaintain page tables for itself.\nMost multi-purpose processors support the notion of a physical address mode as well\nas a virtual address mode.\nPhysical addressing mode requires no page tables and the processor does not attempt\nto perform any address translations in this mode.\nThe Linux kernel is linked to run in physical address space.\n<p>\nThe Alpha AXP&nbsp;processor does not have  a special physical addressing mode.\nInstead, it divides up the memory space into several areas and designates\ntwo of them as physically mapped addresses.\nThis kernel address space is known as KSEG address\nspace and it encompasses all addresses upwards from <em>0xfffffc0000000000<\/em>.\nIn order to execute from code linked in KSEG (by definition, kernel code)\nor access data there, the code must be executing in kernel mode.\nThe Linux kernel on Alpha is linked to execute from address\n<em>0xfffffc0000310000<\/em>.\n<p>\n<h3>Access Control<\/h3>\n<p>\nThe page table entries also contain access control information.\nAs the processor is already using the page table entry to map a process&#8217; virtual address\nto a physical one, it can easily use the access control information to check that the\nprocess is not accessing memory in a way that it should not.\n<p>\nThere are many reasons why you would want to restrict access to areas of memory.\nSome memory, such as that containing executable code, is naturally read only memory; the\noperating system should not allow a process to write data over its executable code.\nBy contrast, pages containing data can be written to, but attempts to execute that memory\nas instructions should fail.\nMost processors have at least two modes of execution: <em>kernel<\/em> and <em>user<\/em>.\nThis adds a level of security to your operating system.\nBecause it is the core of the operating system and therefore can do most anything,\nkernel code is only run when the CPU is in kernel mode.\nYou would not want kernel code executed by a user or kernel data structures to be\naccessible except when the processor is running in kernel mode.\n<p>\n<img decoding=\"async\" src=\"pte.gif\"><br \/>\n<p>\nFigure: Alpha AXP&nbsp;Page Table Entry\n<p>\n<p>The access control information is held in the PTE and\nis processor specific; the figure above shows the PTE for Alpha AXP.\nThe bit fields have the following meanings:\n<dl compact>\n<p>\n\t<dt><b>V<\/b><\/dt><dd> Valid, if set this PTE is valid,\n\t<dt><b>FOE<\/b><\/dt><dd> &#8220;Fault on Execute&#8221;, Whenever an attempt to execute instructions in this\n\t\tpage occurs, the processor reports a page fault and passes control\n\t\tto the operating system,\n\t<dt><b>FOW<\/b><\/dt><dd> &#8220;Fault on Write&#8221;, as above but page fault on an attempt\n\t\tto write to this page,\n\t<dt><b>FOR<\/b><\/dt><dd> &#8220;Fault on Read&#8221;, as above but page fault on an attempt\n\t\tto read from this page,\n\t<dt><b>ASM<\/b><\/dt><dd> Address Space Match.  This is used when the operating\n\t\tsystem wishes to clear only some of the entries from the\n\t\tTranslation Buffer,\n\t<dt><b>KRE<\/b><\/dt><dd> Code running in kernel mode can read this page,\n\t<dt><b>URE<\/b><\/dt><dd> Code running in user mode can read this page,\n\t<dt><b>GH<\/b><\/dt><dd> Granularity hint used when mapping an entire block with\n\t\ta single Translation Buffer entry rather than many,\n\t<dt><b>KWE<\/b><\/dt><dd> Code running in kernel mode can write to this page,\n\t<dt><b>UWE<\/b><\/dt><dd> Code running in user mode can write to this page,\n\t<dt><b>page frame number<\/b><\/dt><dd> For PTEs with the <b>V<\/b> bit set, this field contains\n\t\tthe physical Page Frame Number for this PTE.  For invalid\n\t\tPTEs, if this field is not zero, it contains information about\n\t\twhere the page is in the swap file.\n<\/dl>\n<p>\nThe following two bits are defined and used by Linux:\n<dl compact>\n<p>\n\t<dt><b>_PAGE_DIRTY<\/b><\/dt><dd> if set, the page needs to\n\t\tbe written out to the swap file,\n\t<dt><b>_PAGE_ACCESSED<\/b><\/dt><dd> Used by Linux to mark a page as having been\n\t\taccessed.\n<\/dl>\n","protected":false},"excerpt":{"rendered":"<p>Virtual Memory An Abstract Model of Virtual Memory s Figure: Abstract model of Virtual to Physical address mapping Before considering the methods that Linux uses to support virtual memory it is useful to consider an abstract model that is not &hellip; <a href=\"http:\/\/www.linux-tutorial.info\/?page_id=410\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-410","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=410"}],"version-history":[{"count":1,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/410\/revisions"}],"predecessor-version":[{"id":785,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/410\/revisions\/785"}],"wp:attachment":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}