[C语言]模拟内存物理页,申请连续64个物理页,对应位图置1

联动

[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));
}

转载于:https://www.jianshu.com/p/313b2d5a366a

猜你喜欢

转载自blog.csdn.net/weixin_33919950/article/details/91063529