免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1539 | 回复: 0
打印 上一主题 下一主题

[内核入门] 《LINUX内核源代码情景分析》第2章笔记 [复制链接]

论坛徽章:
2
双鱼座
日期:2014-05-10 15:58:14未羊
日期:2014-05-18 11:36:43
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-06 16:30 |只看该作者 |倒序浏览
本帖最后由 fireaway7 于 2014-05-11 14:47 编辑

第2章
2.3节重要数据结构归纳(缺注释的成员含义,等搞明白不断添加,请知道的朋友给个提示,也请指出不对的地方):
a. 每个物理页面都有一个page结构:
   typedef struct page {
       struct list_head list;                     // 链入管理区zone_t的空闲区域free_area[x].free_list
       struct address_space *mapping;   // 记录内存页面与磁盘文件的映射关系(mmap()),结构定义将在2.6节出现
       unsigned long index;                    // 从盘区换入时,记录来自页面在文件中的序号;换出盘区时,记录动向
       struct page *next_hash;              // 2.6节,add_page_to_hash_queue()函数中使用到
       atomic_t count;                           // 估计是连续个数,如果count=2^n,则list会链入free_area[n].free_list
       unsigned long flags;
       struct list_head lru;                   // 链入LRU(最近最少使用)队列
       unsigned long age;                    // 页面“年龄”,为换出到磁盘提供依据
       wait_queue_head_t wait;
       struct page **pprev_hash;        // 2.6节,add_page_to_hash_queue()函数中使用到
       struct buffer_head * buffers;
       void *virtual;
       struct zone_struct *zone;          // 所属管理区
   } mem_map_t;
   
b. 页面管理区结构:
   #define MAX_ORDER 10
   typedef struct zone_struct {
       spinlock_t lock;
       unsigned long offset;                          // 在mem_map[]中的起始页面号
       unsigned long free_pages;                  // 空闲页面个数
       unsigned long inactive_clean_pages;    // 不活跃干净页面个数
       unsigned long inactive_dirty_pages;    // 不活跃脏页面个数
       unsigned long pages_min, pages_low, pages_high;  // 水位情况
      
       struct list_head inactive_clean_list;      // 不活跃干净页面队列
       free_area_t free_area[MAX_ORDER];   // 空闲区域,不同下标对应不同的“页面连续规模”
      
       // 管理区名字??
       char *name;
       unsigned long size;
          
       struct pglist_data *zone_pgdat;        // 所属存储结点pglist_data结构,zone_struct为zone_pgdat一个子集
       unsigned long zone_start_paddr;
       unsigned long zone_start_mapnr;
       struct page *zone_mem_map;
   } zone_t;
       
   页面管理区空闲区域结构:
   typedef struct free_area_struct {
       struct list_head free_list;       // page队列,page后有2^n-1个连续的页面
       unsigned int *map;
   } free_area_t;

c. 均质存储结构(UMA)、非均质存储结构(NUMA)
   #define ZONE_DMA 0
   #define ZONE_NORMAL 1
   #define ZONE_HIGHMEM 2
   #define MAX_NR_ZONES 3
       
   pglist_data存储结点结构,每个结点对应一个UMA(mem_map[],以及划分为三个管理区),并且相互连在一起:
   typedef struct pglist_data {
       zone_t node_zones[MAX_NR_ZONES];       // 每个模块可能有三种管理区
       zonelist_t node_zonelists[NR_GFPINDEX];  // 分配策略,但MAX_NR_ZONES种区域,能排除组合NR_GFPINDEX这麽多情况吗??
       struct page *node_mem_map;                  // 指向mem_map[] page数组
       unsigned long *valid_addr_bitmap;
       struct bootmem_data *bdata;
       unsigned long node_start_paddr;
       unsigned long node_start_mapnr;
       unsigned long node_size;
       int node_id;                               // 结点编号
       struct pglist_data *node_next;    // 一下个pglist_data存储结点
   } pg_data_t;
       
d. 分配策略结构:
   #define NR_GFPINDEX 0x100          // 最多可以规定256种策略,不要被3种管理区组合不出来256种情况迷惑,因为pglist_data可能有多个
   typedef struct zonelist_struct {
       zone_t * zones [MAX_NR_ZONES+1]; // 以NULL结束,依次从zones[0]、zone[1]..分配,最多也只会有3种管理区
       int gfp_mask;    // 标号,node_zonelists[]下标
   } zonelist_t;

e. 虚拟空间信息结构(需要哪些),对应每个属性(vm_page_prot、vm_flags)相同,地址连续(vm_start->vm_end)的页面集合:
   struct vm_area_struct {
       struct mm_struct * vm_mm; // 上级结构,进程完整虚拟空间,vm_area_struct为mm_struct一个子集

       // [vm_start, vm_end),什么区间?当然是虚拟地址区间
       unsigned long vm_start;      // 虚拟空间区间开始地址
       unsigned long vm_end;        // 虚拟空间区间结束地址
       
       // 单向链表(虚拟地址由高到低排列),mm_struct->mmap
       struct vm_area_struct *vm_next;
      
       pgprot_t vm_page_prot;    // 页面属性
       unsigned long vm_flags;    // 页面标志
      
       // AVL树结点(进程使用虚拟空间区间较多时才需要建AVL树),mm_struct->mmap_avl
       short vm_avl_height;
       struct vm_area_struct * vm_avl_left;
       struct vm_area_struct * vm_avl_right;
      
       struct vm_area_struct *vm_next_share;     // 与磁盘文件交换或映射时用到
       struct vm_area_struct **vm_pprev_share;  // 与磁盘文件交换或映射时用到
      
       struct vm_operations_struct * vm_ops;      // 一组函数指针
       unsigned long vm_pgoff;     // 下标偏移,扩张时,-grow
       struct file * vm_file;             // 交换或映射到的磁盘文件
       unsigned long vm_raend;
       void * vm_private_data;
   };
       
f. 进程整个虚拟空间信息结构:
   struct mm_struct {
       struct vm_area_struct * mmap;           // vm_area_struct结构结点队列
       struct vm_area_struct * mmap_avl;     // vm_area_struct结构结点树
       struct vm_area_struct * mmap_cache; // 最近使用的vm_area_struct结构结点,程序使用的地址带有局部性,35%概率下一次仍用该结点
       pgd_t * pgd;   // 进程页面目录位置,内核将其写入CR3,便可切换到该进程执行
       // 一个进程只使用一个mm,但一个mm可能被多个进程使用,如vfork()、clone()
       atomic_t mm_users; // mm所属用户进程计数
       atomic_t mm_count; // mm被引用计数
       int map_count;        // 包含虚拟空间区间个数
       // 保护mm在不同上下文中受访问,http://www.cnblogs.com/Anker/p/3269106.html
       struct semaphore mmap_sem;
       spinlock_t page_table_lock;
      
       struct list_head mmlist; /* List of all active mm's */
      
       // 该进程代码段、数据段、存储堆、堆栈段等的起点和终点
       unsigned long start_code, end_code, start_data, end_data;
       unsigned long start_brk, brk, start_stack;
       unsigned long arg_start, arg_end, env_start, env_end;
               
       unsigned long rss, total_vm/*页面总数*/, locked_vm;
       unsigned long def_flags;
       unsigned long cpu_vm_mask;
       unsigned long swap_cnt; /* number of pages to swap on next pass */
       unsigned long swap_address;
      
       mm_context_t context;
   };
       
   struct vm_operations_struct {
       void (*open)(struct vm_area_struct * area);   // 虚存打开
       void (*close)(struct vm_area_struct * area);   // 虚存关闭
       // 缺页异常处理函数
       struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int write_access);
   };


*struct page mem_map[],分为ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM(http://blog.csdn.net/zhengaw/article/details/4537070)三个区,又由于要将各小范围的UMA区分开,又定义了更上层的结构pglist_data
*page、zone_struct描述供应,mm_struct、vm_area_struct描述需求,还得与“仓库”提供的物理页面映射,才能真正得到存储空间,页面目录、中间目录、页面表为两者的桥梁
*ZONE_DMA区里面的页面供DMA专用,原因:1.页面换出操作本身需要物理页面,而且换出时,肯定是页面资源紧张了,所以要“预留”;2.DMA不经过MMU提供的地址映射(不理解);3.保证DMA得到的页面是一定是连续的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP