⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 linux0.11 version(301k)
💻 C
📖 第 1 页 / 共 3 页
字号:
<a name=L128 href="source/mm/memory.c#L128">128</a>         }<a name=L129 href="source/mm/memory.c#L129">129</a>         <a href="ident?i=invalidate">invalidate</a>();<a name=L130 href="source/mm/memory.c#L130">130</a>         return 0;<a name=L131 href="source/mm/memory.c#L131">131</a> }<a name=L132 href="source/mm/memory.c#L132">132</a> <a name=L133 href="source/mm/memory.c#L133">133</a> <b><i>/*</i></b><a name=L134 href="source/mm/memory.c#L134">134</a> <b><i> *  Well, here is one of the most complicated functions in mm. It</i></b><a name=L135 href="source/mm/memory.c#L135">135</a> <b><i> * copies a range of linerar addresses by copying only the pages.</i></b><a name=L136 href="source/mm/memory.c#L136">136</a> <b><i> * Let's hope this is bug-free, 'cause this one I don't want to debug :-)</i></b><a name=L137 href="source/mm/memory.c#L137">137</a> <b><i> *</i></b><a name=L138 href="source/mm/memory.c#L138">138</a> <b><i> * Note! We don't copy just any chunks of memory - addresses have to</i></b><a name=L139 href="source/mm/memory.c#L139">139</a> <b><i> * be divisible by 4Mb (one page-directory entry), as this makes the</i></b><a name=L140 href="source/mm/memory.c#L140">140</a> <b><i> * function easier. It's used only by fork anyway.</i></b><a name=L141 href="source/mm/memory.c#L141">141</a> <b><i> *</i></b><a name=L142 href="source/mm/memory.c#L142">142</a> <b><i> * NOTE 2!! When from==0 we are copying kernel space for the first</i></b><a name=L143 href="source/mm/memory.c#L143">143</a> <b><i> * fork(). Then we DONT want to copy a full page-directory entry, as</i></b><a name=L144 href="source/mm/memory.c#L144">144</a> <b><i> * that would lead to some serious memory waste - we just copy the</i></b><a name=L145 href="source/mm/memory.c#L145">145</a> <b><i> * first 160 pages - 640kB. Even that is more than we need, but it</i></b><a name=L146 href="source/mm/memory.c#L146">146</a> <b><i> * doesn't take any more memory - we don't copy-on-write in the low</i></b><a name=L147 href="source/mm/memory.c#L147">147</a> <b><i> * 1 Mb-range, so the pages can be shared with the kernel. Thus the</i></b><a name=L148 href="source/mm/memory.c#L148">148</a> <b><i> * special case for nr=xxxx.</i></b><a name=L149 href="source/mm/memory.c#L149">149</a> <b><i> */</i></b><a name=L150 href="source/mm/memory.c#L150">150</a> int <a href="ident?i=copy_page_tables">copy_page_tables</a>(unsigned long from,unsigned long to,long size)<a name=L151 href="source/mm/memory.c#L151">151</a> {<a name=L152 href="source/mm/memory.c#L152">152</a>         unsigned long * from_page_table;<a name=L153 href="source/mm/memory.c#L153">153</a>         unsigned long * to_page_table;<a name=L154 href="source/mm/memory.c#L154">154</a>         unsigned long this_page;<a name=L155 href="source/mm/memory.c#L155">155</a>         unsigned long * from_dir, * to_dir;<a name=L156 href="source/mm/memory.c#L156">156</a>         unsigned long nr;<a name=L157 href="source/mm/memory.c#L157">157</a> <a name=L158 href="source/mm/memory.c#L158">158</a>         if ((from&amp;0x3fffff) || (to&amp;0x3fffff))<a name=L159 href="source/mm/memory.c#L159">159</a>                 <a href="ident?i=panic">panic</a>(<i>"copy_page_tables called with wrong alignment"</i>);<a name=L160 href="source/mm/memory.c#L160">160</a>         from_dir = (unsigned long *) ((from&gt;&gt;20) &amp; 0xffc); <b><i>/* _pg_dir = 0 */</i></b><a name=L161 href="source/mm/memory.c#L161">161</a>         to_dir = (unsigned long *) ((to&gt;&gt;20) &amp; 0xffc);<a name=L162 href="source/mm/memory.c#L162">162</a>         size = ((unsigned) (size+0x3fffff)) &gt;&gt; 22;<a name=L163 href="source/mm/memory.c#L163">163</a>         for( ; size--&gt;0 ; from_dir++,to_dir++) {<a name=L164 href="source/mm/memory.c#L164">164</a>                 if (1 &amp; *to_dir)<a name=L165 href="source/mm/memory.c#L165">165</a>                         <a href="ident?i=panic">panic</a>(<i>"copy_page_tables: already exist"</i>);<a name=L166 href="source/mm/memory.c#L166">166</a>                 if (!(1 &amp; *from_dir))<a name=L167 href="source/mm/memory.c#L167">167</a>                         continue;<a name=L168 href="source/mm/memory.c#L168">168</a>                 from_page_table = (unsigned long *) (0xfffff000 &amp; *from_dir);<a name=L169 href="source/mm/memory.c#L169">169</a>                 if (!(to_page_table = (unsigned long *) <a href="ident?i=get_free_page">get_free_page</a>()))<a name=L170 href="source/mm/memory.c#L170">170</a>                         return -1;      <b><i>/* Out of memory, see freeing */</i></b><a name=L171 href="source/mm/memory.c#L171">171</a>                 *to_dir = ((unsigned long) to_page_table) | 7;<a name=L172 href="source/mm/memory.c#L172">172</a>                 nr = (from==0)?0xA0:1024;<a name=L173 href="source/mm/memory.c#L173">173</a>                 for ( ; nr-- &gt; 0 ; from_page_table++,to_page_table++) {<a name=L174 href="source/mm/memory.c#L174">174</a>                         this_page = *from_page_table;<a name=L175 href="source/mm/memory.c#L175">175</a>                         if (!(1 &amp; this_page))<a name=L176 href="source/mm/memory.c#L176">176</a>                                 continue;<a name=L177 href="source/mm/memory.c#L177">177</a>                         this_page &amp;= ~2;<a name=L178 href="source/mm/memory.c#L178">178</a>                         *to_page_table = this_page;<a name=L179 href="source/mm/memory.c#L179">179</a>                         if (this_page &gt; <a href="ident?i=LOW_MEM">LOW_MEM</a>) {<a name=L180 href="source/mm/memory.c#L180">180</a>                                 *from_page_table = this_page;<a name=L181 href="source/mm/memory.c#L181">181</a>                                 this_page -= <a href="ident?i=LOW_MEM">LOW_MEM</a>;<a name=L182 href="source/mm/memory.c#L182">182</a>                                 this_page &gt;&gt;= 12;<a name=L183 href="source/mm/memory.c#L183">183</a>                                 <a href="ident?i=mem_map">mem_map</a>[this_page]++;<a name=L184 href="source/mm/memory.c#L184">184</a>                         }<a name=L185 href="source/mm/memory.c#L185">185</a>                 }<a name=L186 href="source/mm/memory.c#L186">186</a>         }<a name=L187 href="source/mm/memory.c#L187">187</a>         <a href="ident?i=invalidate">invalidate</a>();<a name=L188 href="source/mm/memory.c#L188">188</a>         return 0;<a name=L189 href="source/mm/memory.c#L189">189</a> }<a name=L190 href="source/mm/memory.c#L190">190</a> <a name=L191 href="source/mm/memory.c#L191">191</a> <b><i>/*</i></b><a name=L192 href="source/mm/memory.c#L192">192</a> <b><i> * This function puts a page in memory at the wanted address.</i></b><a name=L193 href="source/mm/memory.c#L193">193</a> <b><i> * It returns the physical address of the page gotten, 0 if</i></b><a name=L194 href="source/mm/memory.c#L194">194</a> <b><i> * out of memory (either when trying to access page-table or</i></b><a name=L195 href="source/mm/memory.c#L195">195</a> <b><i> * page.)</i></b><a name=L196 href="source/mm/memory.c#L196">196</a> <b><i> */</i></b><a name=L197 href="source/mm/memory.c#L197">197</a> unsigned long <a href="ident?i=put_page">put_page</a>(unsigned long page,unsigned long address)<a name=L198 href="source/mm/memory.c#L198">198</a> {<a name=L199 href="source/mm/memory.c#L199">199</a>         unsigned long tmp, *page_table;<a name=L200 href="source/mm/memory.c#L200">200</a> <a name=L201 href="source/mm/memory.c#L201">201</a> <b><i>/* NOTE !!! This uses the fact that _pg_dir=0 */</i></b><a name=L202 href="source/mm/memory.c#L202">202</a> <a name=L203 href="source/mm/memory.c#L203">203</a>         if (page &lt; <a href="ident?i=LOW_MEM">LOW_MEM</a> || page &gt;= <a href="ident?i=HIGH_MEMORY">HIGH_MEMORY</a>)<a name=L204 href="source/mm/memory.c#L204">204</a>                 <a href="ident?i=printk">printk</a>(<i>"Trying to put page %p at %p\n"</i>,page,address);<a name=L205 href="source/mm/memory.c#L205">205</a>         if (<a href="ident?i=mem_map">mem_map</a>[(page-<a href="ident?i=LOW_MEM">LOW_MEM</a>)&gt;&gt;12] != 1)<a name=L206 href="source/mm/memory.c#L206">206</a>                 <a href="ident?i=printk">printk</a>(<i>"mem_map disagrees with %p at %p\n"</i>,page,address);<a name=L207 href="source/mm/memory.c#L207">207</a>         page_table = (unsigned long *) ((address&gt;&gt;20) &amp; 0xffc);<a name=L208 href="source/mm/memory.c#L208">208</a>         if ((*page_table)&amp;1)<a name=L209 href="source/mm/memory.c#L209">209</a>                 page_table = (unsigned long *) (0xfffff000 &amp; *page_table);<a name=L210 href="source/mm/memory.c#L210">210</a>         else {<a name=L211 href="source/mm/memory.c#L211">211</a>                 if (!(tmp=<a href="ident?i=get_free_page">get_free_page</a>()))<a name=L212 href="source/mm/memory.c#L212">212</a>                         return 0;<a name=L213 href="source/mm/memory.c#L213">213</a>                 *page_table = tmp|7;<a name=L214 href="source/mm/memory.c#L214">214</a>                 page_table = (unsigned long *) tmp;<a name=L215 href="source/mm/memory.c#L215">215</a>         }<a name=L216 href="source/mm/memory.c#L216">216</a>         page_table[(address&gt;&gt;12) &amp; 0x3ff] = page | 7;<a name=L217 href="source/mm/memory.c#L217">217</a> <b><i>/* no need for invalidate */</i></b><a name=L218 href="source/mm/memory.c#L218">218</a>         return page;<a name=L219 href="source/mm/memory.c#L219">219</a> }<a name=L220 href="source/mm/memory.c#L220">220</a> <a name=L221 href="source/mm/memory.c#L221">221</a> void <a href="ident?i=un_wp_page">un_wp_page</a>(unsigned long * table_entry)<a name=L222 href="source/mm/memory.c#L222">222</a> {<a name=L223 href="source/mm/memory.c#L223">223</a>         unsigned long old_page,new_page;<a name=L224 href="source/mm/memory.c#L224">224</a> <a name=L225 href="source/mm/memory.c#L225">225</a>         old_page = 0xfffff000 &amp; *table_entry;<a name=L226 href="source/mm/memory.c#L226">226</a>         if (old_page &gt;= <a href="ident?i=LOW_MEM">LOW_MEM</a> &amp;&amp; <a href="ident?i=mem_map">mem_map</a>[<a href="ident?i=MAP_NR">MAP_NR</a>(old_page)]==1) {<a name=L227 href="source/mm/memory.c#L227">227</a>                 *table_entry |= 2;<a name=L228 href="source/mm/memory.c#L228">228</a>                 <a href="ident?i=invalidate">invalidate</a>();<a name=L229 href="source/mm/memory.c#L229">229</a>                 return;<a name=L230 href="source/mm/memory.c#L230">230</a>         }<a name=L231 href="source/mm/memory.c#L231">231</a>         if (!(new_page=<a href="ident?i=get_free_page">get_free_page</a>()))<a name=L232 href="source/mm/memory.c#L232">232</a>                 <a href="ident?i=oom">oom</a>();<a name=L233 href="source/mm/memory.c#L233">233</a>         if (old_page &gt;= <a href="ident?i=LOW_MEM">LOW_MEM</a>)<a name=L234 href="source/mm/memory.c#L234">234</a>                 <a href="ident?i=mem_map">mem_map</a>[<a href="ident?i=MAP_NR">MAP_NR</a>(old_page)]--;<a name=L235 href="source/mm/memory.c#L235">235</a>         *table_entry = new_page | 7;<a name=L236 href="source/mm/memory.c#L236">236</a>         <a href="ident?i=invalidate">invalidate</a>();<a name=L237 href="source/mm/memory.c#L237">237</a>         <a href="ident?i=copy_page">copy_page</a>(old_page,new_page);<a name=L238 href="source/mm/memory.c#L238">238</a> }       <a name=L239 href="source/mm/memory.c#L239">239</a> <a name=L240 href="source/mm/memory.c#L240">240</a> <b><i>/*</i></b><a name=L241 href="source/mm/memory.c#L241">241</a> <b><i> * This routine handles present pages, when users try to write</i></b><a name=L242 href="source/mm/memory.c#L242">242</a> <b><i> * to a shared page. It is done by copying the page to a new address</i></b><a name=L243 href="source/mm/memory.c#L243">243</a> <b><i> * and decrementing the shared-page counter for the old page.</i></b><a name=L244 href="source/mm/memory.c#L244">244</a> <b><i> *</i></b><a name=L245 href="source/mm/memory.c#L245">245</a> <b><i> * If it's in code space we exit with a segment error.</i></b><a name=L246 href="source/mm/memory.c#L246">246</a> <b><i> */</i></b><a name=L247 href="source/mm/memory.c#L247">247</a> void <a href="ident?i=do_wp_page">do_wp_page</a>(unsigned long error_code,unsigned long address)<a name=L248 href="source/mm/memory.c#L248">248</a> {<a name=L249 href="source/mm/memory.c#L249">249</a> #if 0<a name=L250 href="source/mm/memory.c#L250">250</a> <b><i>/* we cannot do this yet: the estdio library writes to code space */</i></b><a name=L251 href="source/mm/memory.c#L251">251</a> <b><i>/* stupid, stupid. I really want the libc.a from GNU */</i></b><a name=L252 href="source/mm/memory.c#L252">252</a>         if (<a href="ident?i=CODE_SPACE">CODE_SPACE</a>(address))<a name=L253 href="source/mm/memory.c#L253">253</a>                 <a href="ident?i=do_exit">do_exit</a>(<a href="ident?i=SIGSEGV">SIGSEGV</a>);<a name=L254 href="source/mm/memory.c#L254">254</a> #endif<a name=L255 href="source/mm/memory.c#L255">255</a>         <a href="ident?i=un_wp_page">un_wp_page</a>((unsigned long *)<a name=L256 href="source/mm/memory.c#L256">256</a>                 (((address&gt;&gt;10) &amp; 0xffc) + (0xfffff000 &amp;<a name=L257 href="source/mm/memory.c#L257">257</a>                 *((unsigned long *) ((address&gt;&gt;20) &amp;0xffc)))));<a name=L258 href="source/mm/memory.c#L258">258</a> <a name=L259 href="source/mm/memory.c#L259">259</a> }<a name=L260 href="source/mm/memory.c#L260">260</a> <a name=L261 href="source/mm/memory.c#L261">261</a> void <a href="ident?i=write_verify">write_verify</a>(unsigned long address)<a name=L262 href="source/mm/memory.c#L262">262</a> {<a name=L263 href="source/mm/memory.c#L263">263</a>         unsigned long page;<a name=L264 href="source/mm/memory.c#L264">264</a> <a name=L265 href="source/mm/memory.c#L265">265</a>         if (!( (page = *((unsigned long *) ((address&gt;&gt;20) &amp; 0xffc)) )&amp;1))<a name=L266 href="source/mm/memory.c#L266">266</a>                 return;<a name=L267 href="source/mm/memory.c#L267">267</a>         page &amp;= 0xfffff000;<a name=L268 href="source/mm/memory.c#L268">268</a>         page += ((address&gt;&gt;10) &amp; 0xffc);<a name=L269 href="source/mm/memory.c#L269">269</a>         if ((3 &amp; *(unsigned long *) page) == 1)  <b><i>/* non-writeable, present */</i></b><a name=L270 href="source/mm/memory.c#L270">270</a>                 <a href="ident?i=un_wp_page">un_wp_page</a>((unsigned long *) page);<a name=L271 href="source/mm/memory.c#L271">271</a>         return;<a name=L272 href="source/mm/memory.c#L272">272</a> }<a name=L273 href="source/mm/memory.c#L273">273</a> <a name=L274 href="source/mm/memory.c#L274">274</a> void <a href="ident?i=get_empty_page">get_empty_page</a>(unsigned long address)<a name=L275 href="source/mm/memory.c#L275">275</a> {<a name=L276 href="source/mm/memory.c#L276">276</a>         unsigned long tmp;<a name=L277 href="source/mm/memory.c#L277">277</a> <a name=L278 href="source/mm/memory.c#L278">278</a>         if (!(tmp=<a href="ident?i=get_free_page">get_free_page</a>()) || !<a href="ident?i=put_page">put_page</a>(tmp,address)) {<a name=L279 href="source/mm/memory.c#L279">279</a>                 <a href="ident?i=free_page">free_page</a>(tmp);         <b><i>/* 0 is ok - ignored */</i></b><a name=L280 href="source/mm/memory.c#L280">280</a>                 <a href="ident?i=oom">oom</a>();<a name=L281 href="source/mm/memory.c#L281">281</a>         }<a name=L282 href="source/mm/memory.c#L282">282</a> }<a name=L283 href="source/mm/memory.c#L283">283</a> <a name=L284 href="source/mm/memory.c#L284">284</a> <b><i>/*</i></b><a name=L285 href="source/mm/memory.c#L285">285</a> <b><i> * try_to_share() checks the page at address "address" in the task "p",</i></b>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -