全部博文(46)
分类: LINUX
2010-08-31 20:43:19
内存管理:
1、页:内核把物理页作为内存管理的基本单位,尽管处理器的最小可寻址的单位通常为字,但是MMU通常以页为单位进行处理。体系结构不同,支持的页的大小也不同,在大多的32位平台上支持4KB的页,而64位的平台一般会支持8KB的页。支持4KB并有
2、区:由于硬件的限制,内核并不能对所有的页一视同仁,有些页位于内存中特定的物理地址,不能将其用于一些特定的任务。所以内核把页划分为不同的区(zones)。 Linux中使用了三种区: ZONE_DMA——这个区包含的页能用来执行DAM操作, X86上<16MB ZONE_NORMAL——这个区包含的页都是能正常映射的页,x86上16MB-896MB ZONE_HIGHEM——“高端内存“,其中的页并不能永久地映射到内核地址空间。X86上高于896MB的内存属于高端内存了。 每一个区都用 struct
zone 表示,在中 3、获得与释放页 内核提供了对页申请的底层机制,相关的API如下: alloc_page(gfp_mask)——只分配一页,返回指向页结构的指针 alloc_pages(gfp_mask,order)——分配2order个页,返回指向第一页页结构的指针 get_free_page(gfp_mask)——只分配一页,返回指向其逻辑地址的指针 __get_free_pages(gfp_mask,order)——分配2order个页,返回指向第一页逻辑地址的指针 get_zeroed_page(gfp_mask)——只分配一页,内容填充为0,返回其指向的逻辑地址的指针 释放:void
__free_pages(struct page *page,unsigned int order) void free_pages(unsigned long addr,unsigned int order) void free_page(unsigned long addr) 注意:释放时不能把别人申请的也给释放了,这样做会导致内核崩溃,所以实参要写对。 4、kmalloc()与kfree(),在 Void *kmalloc(size_t size ,int flags) Void kfree(const void *ptr) 在内核中我们分配空间一般都会用到这个两个函数,这两个函数相对于前面的页分配函数来说要高级一点啦,呵呵,而且,分配内存空间最好是在程序的最开头的时候。我写过的一个程序就是因为没有为设备结构体cdev分配存储空间而导致了Ooop的错误。纪念一下!!!! 5、gfp_mask标志 在分配内存的时候我们要指定标志是怎么样的。也就是说kmalloc的第二个参数。 这个标志算起来有三类:行为修饰符、区修饰符及类型修饰符。这些标志在 (1)行为修饰符: 表示内核应当如何分配所需的内存,主要有: __GFP_WAIT 分配器可以休眠 __GFP_HIGH 分配器可以访问紧急事件缓冲池 __GFP_IO 分配器可以启动磁盘I/O __GFP_FS 分配器可以启动文件系统I/O (2)区修饰符: 表示从哪里分配内存:可用于DMA的内存(__GFP_DMA)、常规内存以及高端内存(__GFP_HIGHMEM) (3)类型标志: 它是组合了行为修饰符和区修饰符,将各种可能用到的组合归纳为不同类型,简化了修饰符的使用。因此,最常使用的flags参数为GFP_KERNEL和GFP_ATOMIC。后者用在中断处理程序或其它运行于进程上下文之外的代码中,这时kmalloc方法不会休眠。 #include #define
GFP_KERNEL (__GFP_WAIT |
__GFP_IO | __GFP_FS) #define GFP_ATOMIC
(__GFP_HIGH)