📄 kernel_memory_allocation.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head> <title></title> <link rel="stylesheet" media="screen" type="text/css" href="./style.css" /> <link rel="stylesheet" media="screen" type="text/css" href="./design.css" /> <link rel="stylesheet" media="print" type="text/css" href="./print.css" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><a href=start.html>start</a></br><div class="toc"><div class="tocheader toctoggle" id="toc__header">Table of Contents</div><div id="toc__inside"><ul class="toc"><li class="clear"><ul class="toc"><li class="level2"><div class="li"><span class="li"><a href="#kernel_memory_allocation" class="toc">Kernel Memory Allocation</a></span></div><ul class="toc"><li class="level3"><div class="li"><span class="li"><a href="#kmalloc" class="toc">Kmalloc</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#get_free_page_s" class="toc">Get_Free_Page(s)</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#vmalloc" class="toc">Vmalloc</a></span></div></li></ul></li></ul></li></ul></div></div><h2><a name="kernel_memory_allocation" id="kernel_memory_allocation">Kernel Memory Allocation</a></h2><div class="level2"><p> There are two main ways of getting hold of Kernel Memory </p><ul><li class="level1"><div class="li"> kmalloc - used for smaller allocations</div></li><li class="level1"><div class="li"> get_free_page(s) - used for contiguous blocks of memory</div></li></ul><p> Also</p><ul><li class="level1"><div class="li"> vmalloc - used for larger allocations that need not be contiguous</div></li></ul></div><!-- SECTION [1-276] --><h3><a name="kmalloc" id="kmalloc">Kmalloc</a></h3><div class="level3"><p> KMalloc is used to grab small pieces of memory in kernel space.</p><p>Refer to the following source files: </p><ul><li class="level1"><div class="li"> linux-2.6.x/mm/slab.c</div></li><li class="level1"><div class="li"> linux-2.6.x/include/linux/slab.h</div></li><li class="level1"><div class="li"> linux-2.6.x/include/linux/kmalloc_sizes.h</div></li></ul><p>Max size normally 128K (131072) extended to 1M (1048576) with no MMU and 32M (33554432) with large allocs selected in the Kernel Configuration (CONFIG_LARGE_ALLOCS)</p><p>Memory is arranged in caches, normally of a power of 2 in size ( see include/linux/ kmalloc_sizes.h ). Memory is “stolen” from a larger cache if needed.</p><p>Typical use </p><pre class="code c"> <span class="co1">// get memory </span> <span class="kw4">char</span> * p = kmalloc<span class="br0">(</span>size, flags<span class="br0">)</span>; <span class="co1">// free memory </span> kfree<span class="br0">(</span>p<span class="br0">)</span>; p=<span class="kw2">NULL</span>; </pre><p><strong>kmalloc</strong> will return NULL if the allocation failed.</p><p>The flags argument may be one of: </p><ul><li class="level1"><div class="li"> GFP_USER - Allocate memory on behalf of user. May sleep.</div></li><li class="level1"><div class="li"> GFP_KERNEL - Allocate normal kernel ram. May sleep.</div></li><li class="level1"><div class="li"> GFP_ATOMIC - Allocation will not sleep. Use inside interrupt handlers.</div></li><li class="level1"><div class="li"> GFP_DMA - Allocation from the first 16MB of physical memory for some DMA devices</div></li></ul></div><!-- SECTION [277-1481] --><h3><a name="get_free_page_s" id="get_free_page_s">Get_Free_Page(s)</a></h3><div class="level3"><p> Get_free_page(s) is used to allocate larger contiguous blocks of memory.</p><p>The min page size is 1 page 4k (4096). The “normal” increment is by powers of 2 called the “order”.</p><p>Refer to the following sources: </p><ul><li class="level1"><div class="li"> linux-2.6.x/mm/page_alloc.c</div></li><li class="level1"><div class="li"> linux-2.6.x/include/linux/gfp.h</div></li></ul><p>The use of the kernel call is as follows:</p><pre class="code c"> <span class="kw4">char</span> * kbuf; kbuf = <span class="br0">(</span><span class="kw4">char</span> *<span class="br0">)</span>__get_free_page<span class="br0">(</span>GFP_KERNEL<span class="br0">)</span>; <span class="kw1">if</span> <span class="br0">(</span>!kbuf<span class="br0">)</span> <span class="kw1">return</span> -ENOMEM; <span class="kw4">char</span> * resp; <span class="kw4">int</span> order; order = <span class="nu0">2</span>; <span class="co1">//( 16K page please )</span> resp = <span class="br0">(</span><span class="kw4">char</span> *<span class="br0">)</span> __get_free_pages<span class="br0">(</span>GFP_KERNEL, order<span class="br0">)</span>; <span class="kw1">if</span> <span class="br0">(</span>!resp<span class="br0">)</span> <span class="kw1">return</span> -ENOMEM; </pre><p>This system uses the buddy allocator. The memory is contiguous. If no memory can be found the call may block unless the GFP_ATOMIC flag is specified. In this case the call will return a NULL pointer to indicate failure.</p></div><!-- SECTION [1482-2472] --><h3><a name="vmalloc" id="vmalloc">Vmalloc</a></h3><div class="level3"><p> Used on MMUFull systems. This allows the mapping of buffers greater than the kmalloc limit ( Normally 128K ). Memory is mapped one page at a time and the resultant virtual memory is logically contiguous but may not be actually physically contiguous. In an MMU based system, the physical memory is mapped into a special area reserved in the 4G kernel memory map for this sort of operation.</p><p>ON MMUless systems the vmalloc function is defined in a file called <strong>linux-2.6.x/mm/nommu.c</strong>. </p><p>This file is linked into the kernel instead of the MMU based files.</p></div><h4><a name="mmu_or_not" id="mmu_or_not">MMU or not</a></h4><div class="level4"><p>This extract from the Kernel Makefile shows the system build switches between MMU full and no MMU builds</p><p>The <strong>mmu-y</strong> option simply gets overwritten if there is an MMU in the configuration </p><pre class="code">mmu-y := nommu.ommu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ shmem.o vmalloc.o</pre><p>In general the transition between MMUfull and MMUless operation is restricted to a minimal number of changes in a few source files. </p><pre class="code"> These files provide more instances of using the CONFIG_MMU configuration option. ./drivers/char/mem.c ./drivers/ieee1394/dma.c ./drivers/video/fbmem.c ./fs/compat.c ./fs/exec.c ./kernel/fork.c ./mm/filemap.c ./mm/nommu.c ./mm/page_alloc.c ./mm/slab.c ./include/linux/blkdev.h ./include/linux/kmalloc_sizes.h ./include/linux/rmap.h ./include/linux/swap.h </pre></div><!-- SECTION [2473-] --></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -