如何划分与组织内存(上)?

1)本节我们要接触内存了,那我们用最通俗的语言来类比操作系统和内存的关系应该是怎样的?

  • 操作系统是政府,内存是土地。政府必须合理规划好土地,人民才能安居乐业。

2)既然要规划内存,那我们规划的基本单位有哪两种?

  • 分段和分页

3)分段和分页有什么区别呢?我们设计操作系统的时候应该怎样选择?

  • 表示方式和状态确定角度:段的大小不一样,用什么数据结构表示不太好表示,并且该段是空闲的还是繁忙的也不太好表示。但是页的大小是固定的,我们用位图的1或者0来表示分配和空闲。

  • 内存碎片的利用:段的长度大小不一,容易产生内存碎片。而页的话是固定的,差生内存碎片的几率小。

  • 从内存和硬盘交换效率考虑:内存不足的时候,会把一部分数据写进磁盘里面去,段的话长短不一样,花费的时间也不一样。硬盘空间分配也会产生碎片,导致系统性能抖动。如果每次交换一个页的话,就没这些问题。

 

4)页在内存中长什么样?

  • 用分页模型来管理内存,把物理内存分成4KB大小。

    image-20220407191637368

  • 但是要注意一个要点,我们真实的物理内存空间不是连续的,中间可能有空洞,可能是显存之类的。

5)现在我们知道了页长什么样,那怎样来表示它呢?

  • 可以考虑用一个位图或者整型数组。位值为1表示页已分配,位值为0表示页空闲。整型数组中的值来表示页的状态。那么分配释放的话其实就是数组的删除和插入。但是这个是最低效的方式

  • 上面的方案低效,因为它仅仅保存是内存分配还是空闲的信息,其它像页的状态,页的地址,页的类型我们都不知道,看下来的话我们可以使用C语言的结构体来表示。

     
     //内存空间地址描述符标志
     typedef struct s_MSADFLGS
     {
         u32_t mf_olkty:2;    //挂入链表的类型
         u32_t mf_lstty:1;    //是否挂入链表
         u32_t mf_mocty:2;    //分配类型,被谁占用了,内核还是应用或者空闲
         u32_t mf_marty:3;    //属于哪个区
         u32_t mf_uindx:24;   //分配计数
     }__attribute__((packed)) msadflgs_t;
     //物理地址和标志  
     typedef struct s_PHYADRFLGS
     {
         u64_t paf_alloc:1;     //分配位
         u64_t paf_shared:1;    //共享位
         u64_t paf_swap:1;      //交换位
         u64_t paf_cache:1;     //缓存位
         u64_t paf_kmap:1;      //映射位
         u64_t paf_lock:1;      //锁定位
         u64_t paf_dirty:1;     //脏位
         u64_t paf_busy:1;      //忙位
         u64_t paf_rv2:4;       //保留位
         u64_t paf_padrs:52;    //页物理地址位
     }__attribute__((packed)) phyadrflgs_t;
     //内存空间地址描述符
     typedef struct s_MSADSC
     {
         list_h_t md_list;           //链表
         spinlock_t md_lock;         //保护自身的自旋锁
         msadflgs_t md_indxflgs;     //内存空间地址描述符标志
         phyadrflgs_t md_phyadrs;    //物理地址和标志
         void* md_odlink;            //相邻且相同大小msadsc的指针
     }__attribute__((packed)) msadsc_t;

     

6)我们的内存只有一个区吗?

  • 有很多的区域,一些区域放硬件,一些区域放内核,一些区域放个人的应用,就像一个城市有不同的区一样,各有各的特色和使命。注意这个内存区是逻辑上划分的,也就是不是实际存在的。

7)我们要如何表示一个内存区呢?

  • 和先前物理内存页面一样,我们需要定义一个数据结构,来表示一个内存区的开始地址和结束地址,里面有多少个物理页面,已经分配了多少个物理页面,剩下多少等等。

     
     #define MA_TYPE_HWAD 1
     #define MA_TYPE_KRNL 2
     #define MA_TYPE_PROC 3
     #define MA_HWAD_LSTART 0
     #define MA_HWAD_LSZ 0x2000000
     #define MA_HWAD_LEND (MA_HWAD_LSTART+MA_HWAD_LSZ-1)
     #define MA_KRNL_LSTART 0x2000000
     #define MA_KRNL_LSZ (0x40000000-0x2000000)
     #define MA_KRNL_LEND (MA_KRNL_LSTART+MA_KRNL_LSZ-1)
     #define MA_PROC_LSTART 0x40000000
     #define MA_PROC_LSZ (0xffffffff-0x40000000)
     #define MA_PROC_LEND (MA_PROC_LSTART+MA_PROC_LSZ)
     
     typedef struct s_MEMAREA
     {
         list_h_t ma_list;             //内存区自身的链表
         spinlock_t ma_lock;           //保护内存区的自旋锁
         uint_t ma_stus;               //内存区的状态
         uint_t ma_flgs;               //内存区的标志
         uint_t ma_type;               //内存区的类型
         sem_t ma_sem;                 //内存区的信号量
         wait_l_head_t ma_waitlst;     //内存区的等待队列
         uint_t ma_maxpages;           //内存区总的页面数
         uint_t ma_allocpages;         //内存区分配的页面数
         uint_t ma_freepages;          //内存区空闲的页面数
         uint_t ma_resvpages;          //内存区保留的页面数
         uint_t ma_horizline;          //内存区分配时的水位线
         adr_t ma_logicstart;          //内存区开始地址
         adr_t ma_logicend;            //内存区结束地址
         uint_t ma_logicsz;            //内存区大小
         //还有一些结构我们这里不关心。后面才会用到
     }memarea_t;

     

8)现在我们内存区和内存页都有了,那我们怎样把他们两联系起来呢?

  • 用一个新的数据结构当胶水把它两联系起来

     
     typedef struct s_BAFHLST
     {
         spinlock_t af_lock;    //保护自身结构的自旋锁
         u32_t af_stus;         //状态
         uint_t af_oder;        //页面数的位移量
         uint_t af_oderpnr;     //oder对应的页面数比如 oder为2那就是1<<2=4
         uint_t af_fobjnr;      //多少个空闲msadsc_t结构,即空闲页面
         uint_t af_mobjnr;      //此结构的msadsc_t结构总数,即此结构总页面
         uint_t af_alcindx;     //此结构的分配计数
         uint_t af_freindx;     //此结构的释放计数
         list_h_t af_frelst;    //挂载此结构的空闲msadsc_t结构
         list_h_t af_alclst;    //挂载此结构已经分配的msadsc_t结构
     }bafhlst_t;

posted on 2022-04-07 19:33  Love&Share  阅读(85)  评论(0编辑  收藏  举报

导航