参考
学习笔记
使用教材(配书源码以及使用方法)
《一个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字节的空间出去
分析
模拟color_map位图.png源码
$gcc -o main *.c
$main
j=66
color_map:0xffffffff00000007
address:0x0000000002000840
#include <stdio.h>
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;
}
网友评论