chapter 7 - getting ahold of memory some ins/out of using memory in device drivers and elsewhere in the kernel. kmalloc/kfree - used for allocation of memory. questions: other ways to use memory in device drivers? how to make best use of system memory resources? not about segmentation/paging per se see Chapter 13, Memory Management in Linux the real story of kmalloc fast, may block, doesn't clear memory memory block is contiguous kmalloc flags kmalloc(size, flags) flags defined in GFP_KERNEL - calls get free pages hence GFP assumed to be during system call therefore can block kernel MAY swap to get memory can fail if no free memory. if called in interrupt handler, BH, should use GFP_ATOMIC flag. current process is NOT blocked may fail. GFP_BUFFER - for buffer cache, allows sleeping, fewer attempts made to free memory GFP_USER - low priority GFP_HIGHUSER - allocates from "hi memory" __GFP_DMA - memory must be useable in dma xfer. __GFP_HIGHMEM - highmem where supported memory zones __GFP_DMA and __GFP_HIGHMEM have platform dependent role 2.4 kernel knows about 3 memory zones: 1. dma-capable memory 2. normal 3. high dma-capable memory is memory that can be involved in dma data xfers with peripheral devices and buses. on x86, devices that plug into ISA bus can only address memory from 0..16MB. PCI bus does not have that limitation. High memory: PII virtual memory extension ... this only applies to x86 and sparc. mm/page_alloc.c implements memory zones. the size argument physical memory is allocated in pages. uses special page-oriented allocation technique. creates a set of pools of memory objects of fixed sizes. searches pool for object big enough. data sizes typically on power of 2 boundaries. exact values can be found in mm/kmalloc.c for 2.0 or mm/slab.c in current kernels. may change without notice kmalloc max is 128kbytes lookaside caches device driver may allocate blocks of same size over and over. can we have a special cache? USB/ISDN drivers in linux use caches. kmem_cache_t is type kmem_cache_t *kmem_cache_create(), see book p. 212 SLAB_NO_REAP - don't take memory from this cache when low SLAB_HWCACHE_ALIGM - align SLAB_CACHE_DMA - must be dma capable memory constructor called when memory for a set of objects is allocated destructors called some unknown future time, not immediately after object is freed. allocate with kmem_cache_alloc, and free with kmem_cache_free destroy with kmem_cache_destroy kernel keeps stats which can be obtained from /proc/slabinfo a scull based on slab caches: scullc p. 214 code get_free_page and friends if you need really big chunks of memory, better to be page-oriented. get_zeroed_page() - fill page with zeros and allocate it __get_free_page() - doesn't clear page __get_free_pages() - several contiquous pages, doesn't zero it __get_dma_pages() - dma memory, otherwise like get_free_pages get_free_pages(flags, order) order is power of 2, e.g., want 8 pages, pass 3. maximum value may be 2 MB free_page or free_pages to free a scull using whoe pagesP: scullp p. 216, use of get_free_pages there is no fragmentation here vmalloc and friends vmalloc allocates contiquous memory in the *virtual* address spaced returns 0 if an error occurs #include prototypes, see p. 217 kmalloc returns virtual addresses too BUT mapping is 1-1. page tables are not modified. vmalloc address range is completely synethetic, and page tables are modified. vmalloc addresses are in range VMALLOC_START ... VMALLOC_END defined in vmalloc is used for large buffers that only exist in software, not hardware more overhead ... both get memory, and build page tables create_module system call uses it to ... to load a module. iorepmap builds new page tables, but doesn't actually allocate memory used to map physical address of PCI buffer to virtual kernel space. can be used to access the frame buffer of a PCI video device. these are usually mapped at high addresses outside kernel's normal address range. use readb and other functions mentioned in chapter 8 for accessing such memory. vmalloc and ioremap have less limitations on memory size allocated. vmalloc must be in physical RAM range. vmalloc cannot be used at interrupt time. because it is built on top of kmallc(GFP_KERNEL) a scull using virtual addresses: scullv see code p. 219 boot-time allocation if you need a huge physical buffer, can allocate it at boot-time. modules cannot do this, only physically linked drivers can do it. use _alloc_bootmem and variations on that call can't free the buffer bigphysarea patch patch that allows physical allocation allocates memory at boottime, and makes it available to drivers at runtime. http://www.polyware.nl/~middlelink/En/hobv41.html frame grabber might want this reserving high RAM addresses bigphysarea reserves memory at beginning of memory, maybe you want it at the *end* of physical memory. must pass command line option to kernel at boot to limit mem used mem=126M to reserve 2 megs with system that has 128Megabytes use allocator from ORA site no need to apply bigphysarea patch