zoukankan      html  css  js  c++  java
  • 从零分配内存

    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();

     关于页表PTE即L2页表的填充,调用如下

    #define cpu_set_pte_ext(ptep,pte,ext)    processor.set_pte_ext(ptep,pte,ext)
        /*arch/arm/mm/proc-v6.S*/
        -->cpu_v6_set_pte_ext
            -->armv6_set_pte_ext cpu_v6
                -->str    r1, [r0], #-2048    @ linux version



  • 相关阅读:
    LayoutInflater作用及使用--自定义EditText,自带清除内容按钮
    SSL backend error when using OpenSSL pycurl install error
    pypyodbc 的坑
    mongo aggregate 删除重复数据
    如何验证代理ip的正确性
    python的非官方的一个下载lib的地方
    rabbitmq web 管理系统的信息
    内存泄漏分析
    readme 语法
    logging dictconfig
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/8675962.html
Copyright © 2011-2022 走看看