free_page_tables图文并茂详细解读

具体解读对着图片看,图片的英文就是代码的变量
int free_page_tables (unsigned long from, unsigned long size)
{
        unsigned long *pg_table;
        unsigned long *dir, nr;

        if (from & 0x3fffff)// 要释放内存块的地址需以4M 为边界。
                panic ("free_page_tables called with wrong alignment");
        if (!from)// 出错,试图释放内核和缓冲所占空间。
                panic ("Trying to free up swapper memory space");
        // 计算所占页目录项数(4M 的进位整数倍),也即所占页表数。
        size = (size + 0x3fffff) >> 22;//size转换为4M的倍数,此时size为个页目录项的个数

 

// 下面一句计算起始目录项。对应的目录项号=from>>22,因每项占4 字节,并且由于页目录是从物理地址0 开始,因此实际的目录项指针=目录项号<<2,也即(from>>20)。与上0xffc 确保目录项指针范围有效。
        dir = (unsigned long *) ((from >> 20) & 0xffc);        /* _pg_dir = 0 */
        for (; size-- > 0; dir++){// size 现在是需要被释放内存的目录项数。
                if (!(1 & *dir))        // 如果该目录项无效(P 位=0),则继续。对着下图看
                        continue;        // 目录项的位0(P 位)表示对应页表是否存在。

 

pg_table = (unsigned long *) (0xfffff000 & *dir);        // 取目录项中页表地址。
                for (nr = 0; nr < 1024; nr++){        // 每个页表有1024 个页项。
                        if (1 & *pg_table)        // 若该页表项有效(P 位=1),则释放对应内存页。
                                free_page (0xfffff000 & *pg_table);
                        *pg_table = 0;        // 该页表项内容清零。
                        pg_table++;        // 指向页表中下一项。
                }
                free_page(0xfffff000 & *dir);// 释放该页表所占内存页面。但由于页表在物理地址1M以内,所以这句什么都不做。
                *dir = 0;                        // 对相应页表的目录项清零。
        }
        invalidate ();                // 刷新页变换高速缓冲。
        return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值