从零分配内存

Posted 天地有大美而不言

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零分配内存相关的知识,希望对你有一定的参考价值。

1.解压缩内核阶段,对整个4G的虚拟内存做1:1映射,只一级映射,一个页表项对应1MB,
共4096个页表项,一级页表占用16KB内存空间。

/*arch/arm/boot/compressed/head.S中*/
start
    -->__setup_mmu

2. 解压后,打开MMU之前.映射当前执行的指令所在地址pa的1MB的地址。
映射KERNEL_START~KERNEL_END间的地址到pa起的物理地址

L1pagetable_addr           PA                     VA
0x5000_5400                0x5000_0000            0x5000_0000
....                       ...                    ...
0x5000_7000                0x5000_0000            0xC000_0000     KERNEL_START
0x5000_7004                0x5010_0000            0xC010_0000     ...
0x5000_7008                0x5020_0000            0xC020_0000     ...
0x5000_700c                0x5030_0000            0xC030_0000     ...
0x5000_7010                0x5040_0000            0xC040_0000     KERNEL_END

 

/*arch/arm/kernel/head.S*/
stext
    -->__create_page_tables

3. 内存信息如何传入到内存管理系统
由u-boot通过struct tag结构传入内核,约定好存放地址,譬如0x5000_0100
解析参数中的ATAG_MEM类型的参数
__tagtable(ATAG_MEM, parse_tag_mem32);

static int __init parse_tag_mem32(const struct tag *tag)
    -->arm_add_memory(tag->u.mem.start, tag->u.mem.size);
        -->struct membank *bank = &meminfo.bank[meminfo.nr_banks];
            -->bank->start = PAGE_ALIGN(start);
            -->bank->size  = size & PAGE_MASK;
            -->bank->node  = PHYS_TO_NID(start);
            -->meminfo.nr_banks++;

内核中arch/arm/mm/init.c中定义全局变量struct meminfo meminfo,用于保存内存信息,如起始物理地址,内存大小即所属的Node(用于NUMA)等

struct membank {
    unsigned long start;
    unsigned long size;
    int           node;
};
struct meminfo {
    int nr_banks;
    struct membank bank[NR_BANKS];
};

以OK6410为例,初始化之后
meminfo.nr_banks=1;
meminfo.bank[0].start = 0x5000_0000;
meminfo.bank[0].size = 0x1000_0000;//256M
meminfo.bank[0].node = 0;

4.boot_allocator的建立arch/arm/mm/mmu.c

void __init paging_init(struct machine_desc *mdesc)
    /*准备页表,除meminfo。bank[0]定义的内存区域外全部映射都清零*/
    -->void prepare_page_table(void)
    -->bootmem_init();

 



以上是关于从零分配内存的主要内容,如果未能解决你的问题,请参考以下文章

《Linux Device Drivers》第八章 分配内存——note

如何避免第三方库(无源代码)从物理内存中分配内存?

在结构中分配内存时出现不可预测的行为

在 c 中的 unsigned short int 中分配零

Java 中的堆和栈

使用交叉验证分数获得零分