联动
[OS64][021]源码阅读:程序4-8 申请分配连续64个可用物理页
https://www.jianshu.com/p/f1c159ddc917
说明
代码参考
- 源码
test_bits_map.c
参考自 联动程序4-8 memory.c
关于位图与内存
- 源码
test_bits_map.c
是模拟内存物理页管理位图,在物理页分配后于位图对应位置1
- 位图的每一位
bit
与内存条的1个2MB大小物理页
一一对应 - 一张位图对应一整个内存条,包括内存可用空间、内存空洞、内存的RAM区域等
- 内存的大小是
2GB
,从物理地址0x00
开始 -
第一张物理页是物理地址空间
0x00~0x1FFFFF
,即内存的第一个2MB内存空间,与 联动保持一致,这段空间包括:BootLoader 以及 kernel还有内存页管理结构(包括位图、页结构体数组、区域结构体数组)等等 - 空闲物理页从物理地址
0x200000
开始
关于源码中一些常数
-
1023
表示整个2G内存条一共可分成一千零二十三张2MB大小物理页 - 就是说位图需要至少
1023 bits
(即16个unsigned long 变量)来存 - 1个unsigned long 变量 = 8 字节 = 64 bits
关于源码中的一些变量
-
int j = 0x01;
对应于j = start = z->zone_start_address >> PAGE_2M_SHIFT;
z->zone_start_address
是本区域起始页对齐地址,即0x200000
unsigned long* p = bits_map + (j >> 6);
j >> 6
就是j / 64
,这里做除法,就是找出要检索的物理页对应表示着位图的第几个unsigned long 变量
p
就是指向那个unsigned long 变量的指针
-
unsigned long shift = j % 64;
这里做取余,就是找出要检索物理页对应表示着位图的那个unsigned long 变量的第几位 -
for (k = shift; k < 64 - shift; k++)
以及if (!(((*p >> k) | (*(p + 1) << (64 - k))) & (number == 64 ? 0xffffffffffffffffUL : ((1UL << number) - 1))))
其实是把
两个连续的 unsigned long变量
看做一个长长的区间,连起来其实就是128
位,假设K=20
,就是说要用到第一个unsigned long变量的20~63位,以及第二个 unsigned long变量的0~19位,一共64位,if
条件是说,只要这连续的64位都是0(表示空闲),那么就允许申请(即进入if
循环内部)
输出
[anno@localhost Desktop]$ gcc -o test test_bits_map.c
[anno@localhost Desktop]$ ./test
申请分配前的位图:
第1个unsinged long 变量 : 0x0000000000000001
第2个unsinged long 变量 : 000000000000000000
page0 PHY_ADDRESS:0x0000000000200000
left:000000000000000000 right:0x0000000000000001
page1 PHY_ADDRESS:0x0000000000400000
left:000000000000000000 right:0x0000000000000002
page2 PHY_ADDRESS:0x0000000000600000
left:000000000000000000 right:0x0000000000000003
page3 PHY_ADDRESS:0x0000000000800000
left:000000000000000000 right:0x0000000000000004
page4 PHY_ADDRESS:0x0000000000a00000
left:000000000000000000 right:0x0000000000000005
page5 PHY_ADDRESS:0x0000000000c00000
left:000000000000000000 right:0x0000000000000006
page6 PHY_ADDRESS:0x0000000000e00000
left:000000000000000000 right:0x0000000000000007
page7 PHY_ADDRESS:0x0000000001000000
left:000000000000000000 right:0x0000000000000008
page8 PHY_ADDRESS:0x0000000001200000
left:000000000000000000 right:0x0000000000000009
page9 PHY_ADDRESS:0x0000000001400000
left:000000000000000000 right:0x000000000000000a
page10 PHY_ADDRESS:0x0000000001600000
left:000000000000000000 right:0x000000000000000b
page11 PHY_ADDRESS:0x0000000001800000
left:000000000000000000 right:0x000000000000000c
page12 PHY_ADDRESS:0x0000000001a00000
left:000000000000000000 right:0x000000000000000d
page13 PHY_ADDRESS:0x0000000001c00000
left:000000000000000000 right:0x000000000000000e
page14 PHY_ADDRESS:0x0000000001e00000
left:000000000000000000 right:0x000000000000000f
page15 PHY_ADDRESS:0x0000000002000000
left:000000000000000000 right:0x0000000000000010
page16 PHY_ADDRESS:0x0000000002200000
left:000000000000000000 right:0x0000000000000011
page17 PHY_ADDRESS:0x0000000002400000
left:000000000000000000 right:0x0000000000000012
page18 PHY_ADDRESS:0x0000000002600000
left:000000000000000000 right:0x0000000000000013
page19 PHY_ADDRESS:0x0000000002800000
left:000000000000000000 right:0x0000000000000014
page20 PHY_ADDRESS:0x0000000002a00000
left:000000000000000000 right:0x0000000000000015
page21 PHY_ADDRESS:0x0000000002c00000
left:000000000000000000 right:0x0000000000000016
page22 PHY_ADDRESS:0x0000000002e00000
left:000000000000000000 right:0x0000000000000017
page23 PHY_ADDRESS:0x0000000003000000
left:000000000000000000 right:0x0000000000000018
page24 PHY_ADDRESS:0x0000000003200000
left:000000000000000000 right:0x0000000000000019
page25 PHY_ADDRESS:0x0000000003400000
left:000000000000000000 right:0x000000000000001a
page26 PHY_ADDRESS:0x0000000003600000
left:000000000000000000 right:0x000000000000001b
page27 PHY_ADDRESS:0x0000000003800000
left:000000000000000000 right:0x000000000000001c
page28 PHY_ADDRESS:0x0000000003a00000
left:000000000000000000 right:0x000000000000001d
page29 PHY_ADDRESS:0x0000000003c00000
left:000000000000000000 right:0x000000000000001e
page30 PHY_ADDRESS:0x0000000003e00000
left:000000000000000000 right:0x000000000000001f
page31 PHY_ADDRESS:0x0000000004000000
left:000000000000000000 right:0x0000000000000020
page32 PHY_ADDRESS:0x0000000004200000
left:000000000000000000 right:0x0000000000000021
page33 PHY_ADDRESS:0x0000000004400000
left:000000000000000000 right:0x0000000000000022
page34 PHY_ADDRESS:0x0000000004600000
left:000000000000000000 right:0x0000000000000023
page35 PHY_ADDRESS:0x0000000004800000
left:000000000000000000 right:0x0000000000000024
page36 PHY_ADDRESS:0x0000000004a00000
left:000000000000000000 right:0x0000000000000025
page37 PHY_ADDRESS:0x0000000004c00000
left:000000000000000000 right:0x0000000000000026
page38 PHY_ADDRESS:0x0000000004e00000
left:000000000000000000 right:0x0000000000000027
page39 PHY_ADDRESS:0x0000000005000000
left:000000000000000000 right:0x0000000000000028
page40 PHY_ADDRESS:0x0000000005200000
left:000000000000000000 right:0x0000000000000029
page41 PHY_ADDRESS:0x0000000005400000
left:000000000000000000 right:0x000000000000002a
page42 PHY_ADDRESS:0x0000000005600000
left:000000000000000000 right:0x000000000000002b
page43 PHY_ADDRESS:0x0000000005800000
left:000000000000000000 right:0x000000000000002c
page44 PHY_ADDRESS:0x0000000005a00000
left:000000000000000000 right:0x000000000000002d
page45 PHY_ADDRESS:0x0000000005c00000
left:000000000000000000 right:0x000000000000002e
page46 PHY_ADDRESS:0x0000000005e00000
left:000000000000000000 right:0x000000000000002f
page47 PHY_ADDRESS:0x0000000006000000
left:000000000000000000 right:0x0000000000000030
page48 PHY_ADDRESS:0x0000000006200000
left:000000000000000000 right:0x0000000000000031
page49 PHY_ADDRESS:0x0000000006400000
left:000000000000000000 right:0x0000000000000032
page50 PHY_ADDRESS:0x0000000006600000
left:000000000000000000 right:0x0000000000000033
page51 PHY_ADDRESS:0x0000000006800000
left:000000000000000000 right:0x0000000000000034
page52 PHY_ADDRESS:0x0000000006a00000
left:000000000000000000 right:0x0000000000000035
page53 PHY_ADDRESS:0x0000000006c00000
left:000000000000000000 right:0x0000000000000036
page54 PHY_ADDRESS:0x0000000006e00000
left:000000000000000000 right:0x0000000000000037
page55 PHY_ADDRESS:0x0000000007000000
left:000000000000000000 right:0x0000000000000038
page56 PHY_ADDRESS:0x0000000007200000
left:000000000000000000 right:0x0000000000000039
page57 PHY_ADDRESS:0x0000000007400000
left:000000000000000000 right:0x000000000000003a
page58 PHY_ADDRESS:0x0000000007600000
left:000000000000000000 right:0x000000000000003b
page59 PHY_ADDRESS:0x0000000007800000
left:000000000000000000 right:0x000000000000003c
page60 PHY_ADDRESS:0x0000000007a00000
left:000000000000000000 right:0x000000000000003d
page61 PHY_ADDRESS:0x0000000007c00000
left:000000000000000000 right:0x000000000000003e
page62 PHY_ADDRESS:0x0000000007e00000
left:000000000000000000 right:0x000000000000003f
page63 PHY_ADDRESS:0x0000000008000000
left:0x0000000000000001 right:000000000000000000
申请到的第一个物理页的起始物理地址:0x0000000000200000
分配到物理页后的位图:
第1个unsinged long 变量 : 0xffffffffffffffff
第2个unsinged long 变量 : 0x0000000000000001
完整源码 test_bits_map.c
#include <stdio.h>
#define PAGE_2M_SHIFT 21
// 1位对应 1个物理页 bit: 0 未使用 , 1 使用
unsigned long maps[16] = { 0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
unsigned long* bits_map = maps;
//
unsigned long pages[1023];
unsigned long* pages_struct = pages;
void init_page()
{
int i;
for (i = 0; i < 1023; i++) {
pages[i] =((unsigned long) (0x200000)) * i;
}
}
unsigned long* alloc_pages(int zone_select, int number, unsigned long page_flags)
{
int j = 0x01;
unsigned long* p = bits_map + (j >> 6);
unsigned long shift = j % 64;
unsigned long page = 0;
unsigned long k;
for (k = shift; k < 64 - shift; k++)
{
if (!(((*p >> k) | (*(p + 1) << (64 - k))) & (number == 64 ? 0xffffffffffffffffUL : ((1UL << number) - 1))))
{
unsigned long l;
page = j + k - 1;
for (l = 0; l < number; l++)
{
unsigned long* x = pages_struct + page + l;
printf("page%d\tPHY_ADDRESS:%#018lx\n", l, *x);
// 位图对应为置1 表示该物理页被使用
unsigned long page_PHY_address = *x;
unsigned long left = (page_PHY_address >> PAGE_2M_SHIFT) >> 6;
printf("\tleft:%#018lx", left);
unsigned long right = (page_PHY_address >> PAGE_2M_SHIFT) % 64;
printf("\tright:%#018lx\n", right);
*(bits_map + left) |= 1UL << right;
}
goto find_free_pages;
}
}
find_free_pages:
return (unsigned long*)(pages_struct + page);
}
int main()
{
printf("申请分配前的位图:\n");
printf("第1个unsinged long 变量 : %#018lx\n", *bits_map);
printf("第2个unsinged long 变量 : %#018lx\n", *(bits_map+1));
init_page();
unsigned long * page = alloc_pages(0, 64, 0);
printf("申请到的第一个物理页的起始物理地址:%#018lx\n", *page);
printf("分配到物理页后的位图:\n");
printf("第1个unsinged long 变量 : %#018lx\n", *bits_map);
printf("第2个unsinged long 变量 : %#018lx\n", *(bits_map + 1));
}
网友评论