zoukankan      html  css  js  c++  java
  • ucore实验二

    lab2对lab1的改进:

    1.在bootloader中,完成了对物理内存资源的探测工作(bootasm.S)

    OS需要了解整个计算机系统中的物理内存如何分布的,哪些可用,哪些不可用。其基本方法是通过BIOS中断调用来帮助完成的。其中BIOS中断调用必须在实模式下进行,所以在bootloader进入保护模式前完成这部分工作。具体的流程是:通过BIOS中断获取内存可调用参数为e820h的INT 15H BIOS中断,之后通过系统内存映射地址描述符(Address Range Descriptor)格式来表示系统物理内存布局,并且该地址描述符保存在物理地址0x8000

    保存地址范围描述符结构的缓冲区:

    struct e820map {
                      int nr_map;
                      struct {
                                        long long addr;
                                        long long size;
                                        long type;
                      } map[E820MAX];
    };

    下面是填充该结构体数据:
    probe_memory:
        movl $0, 0x8000      #对0x8000处的32位单元清零,即给位于0x8000处的struct e820map的成员变量nr_map清零
        xorl %ebx, %ebx      #ebx如果是第一次调用或内存区域扫描完毕,则为0
        movw $0x8004, %di   #表示设置调用INT 15h BIOS中断后,BIOS返回的映射地址map描述符的起始地址
    start_probe:
        movl $0xE820, %eax    #INT 15的中断调用参数;
        movl $20, %ecx         #设置地址范围描述符的大小为20字节,其大小等于struct e820map的成员变量map的大小
        movl $SMAP, %edx      #设置edx为534D4150h (即4个ASCII字符“SMAP”)
        int $0x15              #调用int 0x15中断,要求BIOS返回一个用地址范围描述符表示的内存段信息,递增di的值(20的倍数),让BIOS帮我们查找出一个个的内存布局entry,并放入到一个保存地址范围描述符结构的缓冲区的map中
        jnc cont               #如果eflags的CF位为0,则表示还有内存段需要探测
        movw $12345, 0x8000   #探测有问题,结束探测
        jmp finish_probe
    cont:
        addw $20, %di            #eflags的CF位为0,还有内存段需要检测,设置下一个BIOS返回的映射地址描述符的起始地址
        incl 0x8000              #递增struct e820map的成员变量nr_map
        cmpl $0, %ebx            #如果INT0x15返回的ebx为零,表示探测结束,否则继续探测
        jnz start_probe
    finish_probe:                

    2.bootloader不像lab1那样,直接调用kern_init函数,而是先调用位于lab2/kern/init/entry.S中的kern_entry函数。kern_entry函数的主要任务是为执行kern_init建立一个良好的C语言运行环境(设置堆栈),而且临时建立了一个段映射关系,为之后建立分页机制的过程做一个准备(细节在3.5小节有进一步阐述)。

    以页为单位管理物理内存:

    每个物理页可以用一个 Page数据结构来表示。Page结构也占空间,Page结构在设计时须尽可能小,以减少对内存的占用。具体结构的定义在kern/mm/memlayout.h中。

    struct Page {
        int ref;        // page frame's reference counter
        uint32_t flags; // array of flags that describe the status of the page frame
        unsigned int property;// the num of free block, used in first fit pm manager
        list_entry_t page_link;// free list link
    };

    ref:表示这页被页表引用次数,在某页表中有个页表项设置了该页到Page管理的页框的映射,则ref加1,若也表想取消映射,ref减1

    flags:表示页框状态(有两bit来表示这状态,PG_reserved:0表示该页框被内核占用或不能使用,PG_property:1表示可用空闲页框,该名字可以根据不同的分配算法而不同)

    设置的方法有set_bit(int nr,long*addr)将addr第nr置1,test_bit被测试位为0,返回0,为1,返回1。

    property:记录某连续空间空闲页的个数,该变量只有在连续内存空间地址的最小页(头一页)才会被使用,连续内存其余空闲页利用这个页的该变量也可知自己所处空闲块中空闲页个数。

    page_link:是便于把多个连续内存空闲块链接在一起的双向链接指针。连续内存空闲块利用该也的page_link来链接比他地址大和小的其他连续空闲块

    /* free_area_t - maintains a doubly linked list to record free (unused) pages */
    typedef struct {
                list_entry_t free_list;                                // the list header
                unsigned int nr_free;                                 // # of free pages in this free list
    } free_area_t;

    free_list也是记录空闲块链接的变量,nr_free记录内存中可用空闲页数量

    并且总共管理页数为:npage = maxPG(地址最大值) / PGSIZE,从而page结构占内存大小为 npage * sizeof(struct Page),从而从最终内存中0~pages(OS载入后end按页大小取整后地址) +  npage * sizeof(struct Page)  = freemem

    内存空间图:

  • 相关阅读:
    简单Android HttpURLConnectionGet方式
    异步加载图片
    平时收集的一些有关UED的团队和个人博客
    一道关于https进行登录验证的前端面试题
    IE下li的诡异边界问题
    关于Javascript框架的神回帖,值得围观
    jQuery中使用getJSON传递html文本
    CodeIgniter 去掉 URL 中的 index.php
    彻底解决跨浏览器下PHP下载文件名中的中文乱码问题
    php多维数组排序的方法
  • 原文地址:https://www.cnblogs.com/chaunceyctx/p/7219806.html
Copyright © 2011-2022 走看看