linux内核设计与实现 LINUX内核源代码情景分析( 七 )

  • mb方法提供了“读写”屏障
  • 七. 内存管理1. 内核对内存的管理1.1 页
    • 内核把物理页作为内存管理的基本单元 。
    • 内存管理单元:MMU,管理内存,并把虚拟地址转换为物理地址的硬件
    • 页大小跟体系结构不同而不同,大多数32为体系支持4KB的页,64位体系支持8KB的页
    • 物理页的数据结构位于中的struct page 。page与物理页相关,而不是虚拟页
    sturct page{
    unsigned long flags; // 页的状态,是否脏,是否被锁定 。可表示32种状态 。定义与
    atomic_t count; // 页的引用计数,被使用了多少次 。为0时,新的分配就可以使用它
    struct list_head list;
    struct address_space *mapping; //指向与该页有关的address_space对象
    unsigned long index;
    struct list_head lru;
    union{
    struct pte_chain *chain;
    pte_addr_t direct; }pte;
    unsigned long private;
    void *virtual; //页虚拟地址,虚拟内存地址
    }
    1.2 区
    • 由于硬件限制,有些页位于内存中特定的物理地址上,不能用于特定的任务,所以把也划分为不同的区(zones) 。
    • 区对有相似特性的页进行分组 。区的划分没有任何物理意义,仅仅是为了管理页采取的逻辑分组
    • linux使用三种区: ZONE_DMA:能执行DMA(直接内存访问)的区 ZONE_NORMAL:能正常映射的区 ZONE_HIGHEM:不能永久映射到内核地址空间的“高端内存”
    • 区的数据结构位于的struct zone
    2. 页相关接口
    • 内核提供了一种请求内存的底层机制,提供了访问接口,接口都以页为端午分配内存,定义与中
    // 分配2^order个连续的物理页,并返回指针
    struct page* alloc_pages(unsigned int gfp_mask, unsigned int order)
    // 将页转换为逻辑地址,页是连续的,其他页紧随其后
    unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
    // 只获取一页,高端地址分配需要使用此函数
    struct page* alloc_page(unsigned int gfp_mask)
    unsigned long get_free_page(unsigned int gfp_mask)
    //获取填充内容为0的页
    unsigned long get_zeroed_page(unsigned int gfp_mask)
    //释放页
    void __free_pages(struct page *page, unsigned int order)
    void free_pages(unsigned long addr, unsigned int order)
    void free_page(unsigned int order)
    // 与用户空间的malloc函数类似,最通用的接口 。提供用于获得以字节为单位的一块内核内存
    // 定义与中
    void *kmalloc(size_t siez, int flags)
    // kmalloc相反函数,释放空间
    void kfree(const void *ptr)
    // 确保分配的页在物理地址上是连续的
    // 定义与
    void* vmalloc(unsigned long size)
    //释放空间
    void vfree(void *addr)
    • gfp_mask标志,在中,分为三类:行为修饰符,区修饰符和类型 行为修饰符:内核如何分配所需的内存 区修饰符:从哪儿分配内存 类型:组合了行为修饰符和区修饰符
    3. slab
    • slab提供通用数据结构缓存层的角色,slab会给每个处理器维持一个对象告诉缓存(空闲链表)
    • 适用于需要创建和销毁很大的数据结构
    • slab层把不同的对象划分为所谓告诉缓存组,每个告诉缓存都存放不同类型的对象(每种对象类型对应一个高速缓存)
    • 每个slab处于三种状态之一:慢,部分或空
    • 多个salb组成一个高速缓存,各种数据结构: slab的:struct slab 高速缓存:kmem_cache_s 满链表:slabs_full 部分链表:slabs_partial 空链表:slabs_empty
    4. 高端内存的映射
    • 高端内存的页不能永久映射到内核地址空间中,所以某种标志获得的页不可能有逻辑地址
    • x86系统上,高端内存中的页被映射到3GB-4GB的逻辑地址
    • 映射相关接口:
    //映射一个给定的page结构到内核地址空间:
    void kmap(sturct page *page)
    //解除映射关系
    void kunmap(struct page* page)
    //临时映射
    void *kmap_atomic(sturct page *page, enum km_type type)
    八. 虚拟文件系统1. 基本概念