• Linux源码(0.11)学习04---申请和释放内存页 get_free_page free_page


    内存分配和管理

    Linux 0.11内核默认最多支持16M物理内存,物理内存各部分的功能区域示意图如下所示。

     对内存的管理是以页(4KB)为单位进行的,对于内核代码和数据外的内存(1M以上内存区域),使用mem_map[]数组来记录内存页面的状态,0表示空闲,100表示被占用。

    系统首先计算出管理的页面数:PAGING_PAGES = (16M - 1M) / 4KB = 3840 主内存对应的页面数:(16M - 4.5M) / 4KB = 2944 ,前896项对应1M以上的高速缓存区和虚拟磁盘所占用的的物理页面,且被置为占用状态。  

    get_free_page
    // 获取首个空闲页面,并标记为已使用,如果没有空闲页面,则返回0
    unsigned long get_free_page(void)
    {
    register unsigned long __res asm("ax");
    
    __asm__("std ; repne ; scasb
    	"  // 循环比较mem_map数组是否等于0,最大循环次数cx
        "jne 1f
    	"                   // 没有等于0的字节,则跳转结束
        "movb $1,1(%%edi)
    	"         // 1=>[1+edi],对应页面设置为1
        "sall $12,%%ecx
    	"           // 页面数*4kb = 相对页面起始地址
        "addl %2,%%ecx
    	"            // 加上 %2 LOW_MEM 起始地址,等于物理地址
        "movl %%ecx,%%edx
    	"         // 实际物理地址->edx地址
        "movl $1024,%%ecx
    	"         // ecx=1024
        "leal 4092(%%edx),%%edi
    	"   // 4092 + edx->edi(页面的末端)
        "rep ; stosl
    	"              // edi所指内存清零
        "movl %%edx,%%eax
    "           // 页面起始地址->eax(返回值)
        "1:"
        :"=a" (__res)                  // %0 返回
        :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES), // 输入%1 ax=0 %2 LOW_MEM管理内存起始位置 %3 cx=PAGING_PAGES页面数
        "D" (mem_map+PAGING_PAGES-1)               // %4 di=mem_map尾端地址
        );
    return __res;
    }
    free_page
    // 释放addr处的一页内存
    void free_page(unsigned long addr)
    {
        // 校验地址合法性
        if (addr < LOW_MEM) return;
        if (addr >= HIGH_MEMORY)
            panic("trying to free nonexistent page");
        
        // 获取对应页面
        addr -= LOW_MEM;
        addr >>= 12;
        if (mem_map[addr]--) return;
    
        // 置0标记为空闲
        mem_map[addr]=0;
        panic("trying to free free page");
    }
  • 相关阅读:
    TPYBoard—MicroPython开发板免费试用!你最想抱走哪款?
    MicroPython最全资料集锦丨TPYBoard全系列教程之文档+例程源码
    MicroPython-GPRS教程之TPYBoardv702GPRS功能测试
    MicroPython-GPS教程之TPYBoardv702控制5110显示当前经纬度
    MicroPython之TPYBoard v102开发板控制OLED显示中文
    TPYBoard开发板ADC数模转换一: 初识ADC使用
    Set集合
    Collection接口和List集合
    在方法中抛出异常,使用throw关键字抛出异常
    捕捉异常和异常的使用原则
  • 原文地址:https://www.cnblogs.com/vczf/p/12650337.html
Copyright © 2020-2023  润新知