linux0.12 ---memory.c

 free_page()释放物理地址addr处的一页内存

 

本帖最后由 Gen216ius 于 2011-8-14 21:26 编辑

具体解读对着图片看,图片的英文就是代码的变量,注意这里的from是线性地址
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为个页目录项的个数
linux0.12 ---memory.c_第1张图片
        // 下面一句计算起始目录项。对应的目录项号=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 位)表示对应页表是否存在。
linux0.12 ---memory.c_第2张图片
                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;
}

你可能感兴趣的:(memory)