Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134115
  • 博文数量: 38
  • 博客积分: 1277
  • 博客等级: 中尉
  • 技术积分: 450
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-11 23:24
文章分类

全部博文(38)

文章存档

2012年(2)

2011年(7)

2010年(24)

2009年(5)

分类: LINUX

2010-10-03 03:31:04


#ifdef CONFIG_X86_32

# ifdef CONFIG_X86_PAE
# define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
# else# define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
# endif

#else /* CONFIG_X86_32 */

# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
#endif

// MAX_ARCH_PFN为系统架构下的最大PFN(page frame number)号,32位下时无PAE时,为2^32 / 4096

// 也就是 (1ULL<<(32-PAGE_SHIFT));当有PAE时,为 2^36/4096,也就是 (1ULL<<(36-PAGE_SHIFT))

/*
* Find the highest page frame number we have available */

// 查找系统中最大可用的页框数,最大不可超过MAX_ARCH_PFN,以及限制参数值
static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
{
    int i;
    unsigned long last_pfn = 0;
    unsigned long max_arch_pfn = MAX_ARCH_PFN; // 系统架构下最大PFN


    for (i = 0; i < e820.nr_map; i++) {
        struct e820entry *ei = &e820.map[i];
        unsigned long start_pfn;
        unsigned long end_pfn;
            
        if (ei->type != type)
            continue;
        start_pfn = ei->addr >> PAGE_SHIFT; // addr为物理地址,转成PFN, 计算起始PFN

        end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; // 计算结束PFN

        if (start_pfn >= limit_pfn) // 超过限定值

            continue;
        if (end_pfn > limit_pfn) { // 结束PFN超过限定值时,只取限定值,跳出

            last_pfn = limit_pfn;
            break;
        }
        if (end_pfn > last_pfn) // 取大值

            last_pfn = end_pfn;
    }
    if (last_pfn > max_arch_pfn) // 保证不超过系统架构下最大PFN

        last_pfn = max_arch_pfn;

    printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
            last_pfn, max_arch_pfn);
    return last_pfn;
}

// 获取内存结束的PFN
unsigned long __init e820_end_of_ram_pfn(void)
{
    return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
}

// 跟上面的类似,只不过限定为4G内
unsigned long __init e820_end_of_low_ram_pfn(void)
{
    return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
}


阅读(790) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~