[C语言]模拟color_map位图分配

参考

学习笔记

使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171

  • 配书代码包 :第9章 \ 程序 \ 程序9-1 文件 memory.c 函数 kmalloc

说明

  • 假设从地址vaddress = 0x2000000开始分配空间,每次分配size=0x20字节,使用一组连续的unsigned long变量组成一张color_map来标记分配情况,color_map 每一位 表示 每size字节 的分配,位上置1表示已分配,位上置0表示可分配;
  • 代码技巧
if(*(color_map + (j >> 6)) == 0xffffffffffffffffUL)
可以快速跳过 连续 64个位都是1的那一整个unsigned long变量
即这里连续 64个size字节 的 可分配项 已经用掉了

j 表示遍历每一位,故而在for循环里的递增量是j++ 
if( (*(color_map + (j >> 6)) & (1UL << (j % 64))) == 0 )
找到某一个不全是1的unsigned long变量
在这一段里面,找第一个为0的位

技巧是,假设 j >> 6 就是 j / 6 
定位在第几个段也就是第几个unsigned long变量里

而 j % 64 是在此段内的偏移量

源码中取的例子,第一个为 0 的位在 0 0 1 1,
故而 j = 64 时,遇到第一个 1,j++
j = 65 时,遇到第二个 1,j++
j = 66 时,终于遇到那个 0 
就在这个位置1 表示分配size字节的空间出去

分析

[C语言]模拟color_map位图分配_第1张图片
模拟color_map位图.png

源码

https://www.tutorialspoint.com/compile_c_online.php

$gcc -o main *.c
$main
j=66
color_map:0xffffffff00000007
address:0x0000000002000840
#include 

int main()
{
    int size = 0x20;
    /*
    before   8 4 2 1  j  8 4 2 1 after
        0    0 0 0 0 64  0 0 0 1    1
        1    0 0 0 1 65  0 0 1 1    3
        3    0 0 1 1 66  0 1 1 1    7
        7    0 1 1 1 67  1 1 1 1    f
    */
    unsigned long maps[] = {0xffffffffffffffff,0xffffffff00000003};
    unsigned long * color_map = maps;
    unsigned long * Vaddress = (unsigned long *)0x2000000;
    
    int j;
    for(j = 0;j < 256;j++)
    {
        if(*(color_map + (j >> 6)) == 0xffffffffffffffffUL)
        {
            j += 63;
            continue;
        }
            
        if( (*(color_map + (j >> 6)) & (1UL << (j % 64))) == 0 )
        {
            *(color_map + (j >> 6)) |= 1UL << (j % 64);
            printf("j=%d\n", j);
            printf("color_map:%#018lx\n",*(color_map + (j >> 6)));
            printf("address:%#018lx\n", (char *)Vaddress + size * j);
            return 1;
        }
    }

    return 0;
}

你可能感兴趣的:([C语言]模拟color_map位图分配)