|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-BDB847A2-557A-5902-AA6D-C1AE10D8E493" xml:lang="en"><title>Code |
|
13 Paging Guide</title><shortdesc>Code paging is the application of demand paging to executable code. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <section id="GUID-CD6AC3BC-AF81-4342-9B66-34ACDD573093"><title>Purpose</title> <p>This document explains the principles of |
|
15 code paging in Symbian platform. </p> <p><b>Intended |
|
16 Audience:</b> </p> <p>This document is intended to be read by those interested |
|
17 in the Symbian platform kernel. </p> </section> |
|
18 <section id="GUID-FC1B1DC9-133A-43BA-BAEC-711718817B82"><title>Basics of code paging</title> <p>Code paging means the use |
|
19 of demand paging to executable code. Demand paging increases the apparent |
|
20 size of available RAM on a device by loading data into RAM when needed. Since |
|
21 the memory locations used by the code cannot be determined before it is loaded, |
|
22 the code needs to be modified when it is paged into RAM. </p> <p>Classes explained |
|
23 here. </p> <p>Executable code is paged in and out of memory in accordance |
|
24 with the demand paging algorithm which is discussed in the document. The algorithm |
|
25 involves four basic operations: </p> <ul> |
|
26 <li id="GUID-AE260EC1-A9F4-53B9-A0B7-1681FAFA42A5"><p>paging in, </p> </li> |
|
27 <li id="GUID-F870B9A6-6B57-5988-93D7-C87A58B8F94D"><p>aging, </p> </li> |
|
28 <li id="GUID-4C9897F4-8A64-556E-939A-0687E775E4EC"><p>rejuvenating, and </p> </li> |
|
29 <li id="GUID-E9CF60A1-162C-540A-839A-475D99802B85"><p>freeing. </p> </li> |
|
30 </ul> <p>The remainder of this document discusses the kernel side implementation |
|
31 of each of these operations in turn. Most of the work is done by the <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref> class. </p> </section> |
|
32 <section id="GUID-FC5D5EE4-EEE2-4630-8321-0BB3855CB300"><title>Paging in paged code</title> <p>When a program accesses an |
|
33 item of paged code for the first time the code needs to be paged into RAM. |
|
34 The initial call generates a data abort: this is caught by the exception handler |
|
35 which calls the <xref href="GUID-1AA89F20-7D14-35DB-92FE-06670B2BA484.dita"><apiname>HandleFault()</apiname></xref> function of the <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref> class. |
|
36 The function call performs the paging in as follows. </p> <ul> |
|
37 <li id="GUID-B944B6DF-3DC9-5FF4-92B1-2F6A5298767A"><p>Checks the MMU page |
|
38 table entry for the address which caused the data abort. If the entry is not <xref href="GUID-4C8E5466-82E2-3B45-81C5-980FC521DD3A.dita"><apiname>KPteNotPresentEntry</apiname></xref> then |
|
39 there is no memory mapped at that address and it may need paging in. </p> </li> |
|
40 <li id="GUID-DB0C8B0C-A38D-555C-98F7-08040771AD65"><p>Verifies that the exception |
|
41 was caused by an access to the code chunk memory region. </p> </li> |
|
42 <li id="GUID-F00DF257-8807-5F31-9FED-4626746ED421"><p>Finds the code segment |
|
43 which is at the current address. </p> </li> |
|
44 <li id="GUID-7A5442AF-A66D-56CA-8921-B7BA3907B624"><p>Verifies that the code |
|
45 segment is the one being demand paged. </p> </li> |
|
46 </ul> <p>The <xref href="GUID-1AA89F20-7D14-35DB-92FE-06670B2BA484.dita"><apiname>HandleFault()</apiname></xref> function of <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref> then |
|
47 calls the <xref href="GUID-A7C5F674-CF18-308B-A07F-6C057AB29180.dita"><apiname>PageIn()</apiname></xref> function of <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref>, |
|
48 which performs the following steps. </p> <ul> |
|
49 <li id="GUID-EAE80357-A36C-5DF6-BCA5-C1F704388DCF"><p>Obtains a <xref href="GUID-535DF46C-C681-3167-9AE1-E927D3B3B928.dita#GUID-535DF46C-C681-3167-9AE1-E927D3B3B928/GUID-E9132C24-94CE-35FE-8E32-943C2134BD1C"><apiname>DemandPaging::DPagingRequest</apiname></xref> object |
|
50 by calling <xref href="GUID-535DF46C-C681-3167-9AE1-E927D3B3B928.dita#GUID-535DF46C-C681-3167-9AE1-E927D3B3B928/GUID-D70D74D4-EEDD-3F58-AF6D-160E9DF707DC"><apiname>DemandPaging::AcquireRequestObject()</apiname></xref>. </p> </li> |
|
51 <li id="GUID-08CE4C36-B2BD-5DB8-BBB5-D3259D63C496"><p>Obtains a physical page |
|
52 of RAM by calling <xref href="GUID-535DF46C-C681-3167-9AE1-E927D3B3B928.dita#GUID-535DF46C-C681-3167-9AE1-E927D3B3B928/GUID-BF59E426-A1C8-3491-9AC8-929A1DF8EE42"><apiname>DemandPaging::AllocateNewPage()</apiname></xref>. </p> </li> |
|
53 <li id="GUID-33BA3BF8-999B-5691-B8A6-8905ED3E7B61"><p>Maps the RAM at the |
|
54 temporary location <xref href="GUID-E9132C24-94CE-35FE-8E32-943C2134BD1C.dita#GUID-E9132C24-94CE-35FE-8E32-943C2134BD1C/GUID-53AF13F7-94B7-3EDE-B0FF-6F33FF16D208"><apiname>DemandPaging::DPagingRequest::iLoadAddr</apiname></xref>. </p> </li> |
|
55 <li id="GUID-5AA0C439-42E3-5E70-BC65-B2E7D7C38909"><p>Reads the correct contents |
|
56 into the RAM page by calling <xref href="GUID-535DF46C-C681-3167-9AE1-E927D3B3B928.dita#GUID-535DF46C-C681-3167-9AE1-E927D3B3B928/GUID-4CBDC66C-B779-3894-9B32-726911E3D9E2"><apiname>DemandPaging::ReadCodePage()</apiname></xref>. </p> </li> |
|
57 <li id="GUID-4217C1A9-5930-505E-9E8C-864691C68B35"><p>Initialises the <xref href="GUID-C5F2C8BC-9C8E-3BC1-AB24-99E23A38152B.dita"><apiname>SPageInfo</apiname></xref> structure |
|
58 for the physical page of RAM and marks it as type <xref href="GUID-BB093184-8193-3157-883B-9264CD6389C7.dita"><apiname>EPagedCode</apiname></xref>. </p> </li> |
|
59 <li id="GUID-13948D5A-1C02-5A0D-A1F7-0C13E8B700F2"><p>Maps the page at the |
|
60 correct address in the current process. </p> </li> |
|
61 <li id="GUID-903E5F84-C4C2-509A-BB31-073780C895A7"><p>Adds the <xref href="GUID-C5F2C8BC-9C8E-3BC1-AB24-99E23A38152B.dita"><apiname>SPageInfo</apiname></xref> to |
|
62 the beginning of the live page list. </p> </li> |
|
63 </ul> <p>When these calls have completed they return control to the program |
|
64 which caused the data abort. </p> </section> |
|
65 <section id="GUID-C6956FFF-0138-45B9-87AA-66B7609B2B3E"><title>Aging paged code</title> <p>The demand paging algorithm defines |
|
66 pages in the live list to be either young or old. When a page changes status |
|
67 from young to old, the kernel changes the MMU mappings for the page to make |
|
68 it inaccessible. It does so by calling the <xref href="GUID-2625AEBC-E316-3CC4-B840-DF2148BCAD65.dita"><apiname>SetOld()</apiname></xref> function |
|
69 of the <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref> class. The implementation of |
|
70 this procedure is different in the Moving Memory Model and the Multiple Memory |
|
71 Model. </p> <p>In the Moving Memory Model, the call to <xref href="GUID-2625AEBC-E316-3CC4-B840-DF2148BCAD65.dita"><apiname>SetOld()</apiname></xref> acts |
|
72 as follows: </p> <ul> |
|
73 <li id="GUID-B01591FD-2D3F-5752-B38B-5BC69B9FAE49"><p>Finds the MMU page table |
|
74 entry for the page and clears the bits <xref href="GUID-37E290ED-FFF8-3A6B-9CA9-07863E340F0D.dita"><apiname>KPtePresentMask</apiname></xref>. </p> </li> |
|
75 </ul> <p>In the Multiple Memory Model, <xref href="GUID-2625AEBC-E316-3CC4-B840-DF2148BCAD65.dita"><apiname>SetOld()</apiname></xref> calls the |
|
76 kernel function <xref href="GUID-EAF2FEE1-BA70-32E5-8D6A-E55F0A814E4B.dita"><apiname>DoSetCodeOld()</apiname></xref> which acts as follows: </p> <ul> |
|
77 <li id="GUID-7573F92E-441B-55AD-AB0D-D4341AF22E3A"><p>Examines the bit array <xref href="GUID-DD3F8638-685C-3246-A493-34C8BBA51566.dita#GUID-DD3F8638-685C-3246-A493-34C8BBA51566/GUID-241CBE5A-0A84-3F26-BAFD-7FCC33F788E7"><apiname>DMemModelCodeSegMemory::iOsAsid</apiname></xref> s |
|
78 to determine the processes into which the code segment is loaded. </p> </li> |
|
79 <li id="GUID-3AFE85EA-6967-5E89-B277-CDBD17315B06"><p>Updates each mapping |
|
80 in turn. </p> </li> |
|
81 </ul> <p>The status of a page may change during a call to <xref href="GUID-EAF2FEE1-BA70-32E5-8D6A-E55F0A814E4B.dita"><apiname>DoSetCodeOld()</apiname></xref>, |
|
82 either because it has been rejuvenated or paged out. In these cases <xref href="GUID-EAF2FEE1-BA70-32E5-8D6A-E55F0A814E4B.dita"><apiname>DoSetCodeOld()</apiname></xref> simply |
|
83 ends, as the aging operation is no longer appropriate. </p> </section> |
|
84 <section id="GUID-1B0F49F2-4B9C-4B60-AFA6-521C33951576"><title>Rejuvenating paged code</title> <p>When a program accesses |
|
85 a program held in an old page, it generates a data abort because the kernel |
|
86 made the page inaccessible when it was set to old. The data abort is caught |
|
87 by the exception handler which calls the <xref href="GUID-1AA89F20-7D14-35DB-92FE-06670B2BA484.dita"><apiname>HandleFault()</apiname></xref> function |
|
88 of the <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref> class. It is this call which |
|
89 performs the rejuvenation as follows. </p> <ul> |
|
90 <li id="GUID-4494FF5B-8F24-5973-9178-F1134A3B7313"><p>Gets the MMU page table |
|
91 entry for the address which caused the abort. If the bits <xref href="GUID-37E290ED-FFF8-3A6B-9CA9-07863E340F0D.dita"><apiname>KPtePresentMask</apiname></xref> are |
|
92 clear then the page needs rejuvenating. If all the bits are clear then the |
|
93 page needs to be paged in, not rejuvenated. </p> </li> |
|
94 <li id="GUID-4708382F-4E31-5448-B958-A919C1E2C31A"><p>Finds the <xref href="GUID-C5F2C8BC-9C8E-3BC1-AB24-99E23A38152B.dita"><apiname>SPageInfo</apiname></xref> for |
|
95 the page, using the physical address stored in the page table entry. </p> </li> |
|
96 <li id="GUID-E235D0FB-7A9B-5A1C-BC84-782A9F8A29FD"><p>If it finds that the |
|
97 state of the page is <xref href="GUID-9C190095-2B44-31A5-A898-E362FCC19EDC.dita"><apiname>EStatePagedDead</apiname></xref> then the page is dead |
|
98 rather than old and needs to be paged in, not rejuvenated. </p> </li> |
|
99 <li id="GUID-B1AE6505-05B7-5ACA-B284-C95AF360AADE"><p>Updates the page table |
|
100 entry to make the page accessible. </p> </li> |
|
101 <li id="GUID-D39CCEFF-087C-5F07-B935-B52877D35817"><p>Moves the <xref href="GUID-C5F2C8BC-9C8E-3BC1-AB24-99E23A38152B.dita"><apiname>SPageInfo</apiname></xref> for |
|
102 the page to the beginning of the live list, making it the youngest page in |
|
103 the list. </p> </li> |
|
104 </ul> <p>These steps are performed with the system lock held. </p> </section> |
|
105 <section id="GUID-C53B418C-46BC-43C5-940D-94667DD00872"><title>Freeing paged code</title> <p>When a physical page of RAM |
|
106 holding demand-paged code is needed for other purposes, it must be freed up. |
|
107 The kernel does this by calling the <xref href="GUID-9C1DEEB8-2C7E-3AD1-97B1-58E64AAAF1B1.dita"><apiname>SetFree()</apiname></xref> function |
|
108 of the <xref href="GUID-B718F920-45E2-3DD6-927F-0465B156993D.dita"><apiname>MemModelDemandPaging</apiname></xref> class. The implementation of |
|
109 this procedure is different in the Moving Memory Model and the Multiple Memory |
|
110 Model. </p> <p>In the Moving Memory Model, the call to <xref href="GUID-9C1DEEB8-2C7E-3AD1-97B1-58E64AAAF1B1.dita"><apiname>SetFree()</apiname></xref> acts |
|
111 as follows: </p> <ul> |
|
112 <li id="GUID-57E4C0C5-0D5D-5C0F-B324-46F4E7AD6739"><p>Finds the MMU page table |
|
113 entry for the page and sets it to <xref href="GUID-4C8E5466-82E2-3B45-81C5-980FC521DD3A.dita"><apiname>KPteNotPresentEntry</apiname></xref>. </p> </li> |
|
114 </ul> <p>In the Multiple Memory Model, the call to <xref href="GUID-9C1DEEB8-2C7E-3AD1-97B1-58E64AAAF1B1.dita"><apiname>SetFree()</apiname></xref> calls |
|
115 the kernel function <xref href="GUID-D16A900C-A40C-3D6A-A77E-4008376DBAAE.dita"><apiname>DoSetCodeFree()</apiname></xref> which acts as follows: </p> <ul> |
|
116 <li id="GUID-F1CDC949-F1FC-5E87-A4B2-A5F12F099B9A"><p>Examines the bit array <xref href="GUID-DD3F8638-685C-3246-A493-34C8BBA51566.dita#GUID-DD3F8638-685C-3246-A493-34C8BBA51566/GUID-30F9613A-C06F-3185-94B5-4CAE20B7A052"><apiname>DMemModelCodeSegMemory::iOsAsids</apiname></xref> to |
|
117 determine the processes into which the code segment is loaded. </p> </li> |
|
118 <li id="GUID-4D104936-767C-514C-9253-1F8CC80B92A9"><p>Makes each page inaccessible |
|
119 in turn. </p> </li> |
|
120 </ul> </section> |
|
121 </conbody><related-links> |
|
122 <link href="GUID-E21E7992-607A-5A49-B022-189ECA9E76D1.dita"><linktext>Code Paging |
|
123 Overview</linktext></link> |
|
124 <link href="GUID-B35A70D2-1BC8-51DE-95BF-F315DB394582.dita"><linktext>Demand Paging |
|
125 Overview</linktext></link> |
|
126 </related-links></concept> |