zoukankan      html  css  js  c++  java
  • 内存管理小结(1)--全局变量与宏

    1.全局变量赋值

    1.1high_memory

    void * high_memory; /*mm/memory.c*/
    
    unsigned long max_low_pfn; /*mm/bootmem.c*/
    unsigned long min_low_pfn;  /*mm/bootmem.c*/
    unsigned long max_pfn;  /*mm/bootmem.c*/

    以上全局变量在bootmem_init中赋值

    void __init bootmem_init(void)
        -->high_memory = __va((memend_pfn << PAGE_SHIFT) - 1) + 1;
        -->max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET;

    1.2mem_map

    struct page *mem_map; /*mm/memory.c*/

    赋值调用过程如下

    void __init bootmem_init(void)
        -->bootmem_free_node(node, mi);
            -->free_area_init_node(node, zone_size, start_pfn, zhole_size);
                -->static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat)
                    -->mem_map = NODE_DATA(0)->node_mem_map;

    1.3物理页框数统计

    unsigned long __meminitdata nr_kernel_pages;  /*mm/page_alloc.c*/
    unsigned long __meminitdata nr_all_pages;  /*mm/page_alloc.c*/

    赋值调用流程

    void __init bootmem_init(void)
        -->bootmem_free_node(node, mi);
            -->free_area_init_node(node, zone_size, start_pfn, zhole_size);
                -->free_area_init_core(pgdat, zones_size, zholes_size);
                    -->if (!is_highmem_idx(j))
                        nr_kernel_pages += realsize;
                    -->nr_all_pages += realsize

    1.4highest_memmap_pfn,最大页框号

    unsigned long highest_memmap_pfn __read_mostly; /*mm/page_alloc.c*/

    赋值调用流程

    void __init bootmem_init(void)
        -->bootmem_free_node(node, mi);
            -->free_area_init_node(node, zone_size, start_pfn, zhole_size);
                -->free_area_init_core(pgdat, zones_size, zholes_size);
                    -->memmap_init(size, nid, j, zone_start_pfn);
                        -->memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
                            -->if (highest_memmap_pfn < end_pfn - 1)
                                highest_memmap_pfn = end_pfn - 1;

    1.5totalram_pages,伙伴系统初始化完成后可用的ram总页数

    unsigned long totalram_pages __read_mostly;  /*mm/page_alloc.c*/
    
    void __init mem_init(void)
        -->totalram_pages += free_all_bootmem_node(pgdat);
        -->totalram_pages += totalhigh_pages;

     2.宏

    2.1VMALLOC_START

    定义在arch/arm/include/asm/pgtable.h

    #define VMALLOC_OFFSET        (8*1024*1024)
    #define VMALLOC_START        (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))

    2.2VMALLOC_END

    在arch/arm/plat-s3c/include/mach/vmalloc.h定义如下:

    #define VMALLOC_END      (0xE0000000)

    这里定义为0xE000_0000是考虑0xE000_0000-0xC000_0000=0x2000_00000=512M,刚好是S3C6410处理器支持的最大内存地址范围。

    在arch/arm/mach-realview/include/mach/vmalloc.h中定义如下

    #define VMALLOC_END        0xf8000000

    一般在支持高端内存的处理器上这个值设为0xF800_0000,距离4G空间的末尾128M的地方

    2.3.VMALLOC_MIN

    定义在arch/arm/mm/mmu.c中,

    #define VMALLOC_MIN    (void *)(VMALLOC_END - vmalloc_reserve)

    2.4.vmalloc_reserve

    定义在arch/arm/mm/mmu.c中,初始值为0x08000000,即128M。

    static unsigned long __initdata vmalloc_reserve = SZ_128M;

    这个值可以在命令行参数中修改

    /*
     * vmalloc=size forces the vmalloc area to be exactly 'size'
     * bytes. This can be used to increase (or decrease) the vmalloc
     * area - the default is 128m.
     */
    static void __init early_vmalloc(char **arg)
    {
        vmalloc_reserve = memparse(*arg, arg);
    
        if (vmalloc_reserve < SZ_16M) {
            vmalloc_reserve = SZ_16M;
            printk(KERN_WARNING
                "vmalloc area too small, limiting to %luMB
    ",
                vmalloc_reserve >> 20);
        }
    
        if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) {
            vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M);
            printk(KERN_WARNING
                "vmalloc area is too big, limiting to %luMB
    ",
                vmalloc_reserve >> 20);
        }
    }
    __early_param("vmalloc=", early_vmalloc);
    early_vmalloc

    vmalloc动态分配区间为max(VMALLOC_MIN,VMALLOC_START)——VMALLOC_END

    2.5PKMAP相关的宏,其中PMD_SIZE=2M,PTRS_PER_PTE=512.

    定义在arch/arm/include/asm/highmem.h中

    #define PKMAP_BASE        (PAGE_OFFSET - PMD_SIZE)
    #define LAST_PKMAP        PTRS_PER_PTE
    #define LAST_PKMAP_MASK        (LAST_PKMAP - 1)
    #define PKMAP_NR(virt)        (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
    #define PKMAP_ADDR(nr)        (PKMAP_BASE + ((nr) << PAGE_SHIFT))

    2.6fixmap相关的宏

    定义在arch/arm/include/asm/fixmap.h中,

    /*
     * Nothing too fancy for now.
     *
     * On ARM we already have well known fixed virtual addresses imposed by
     * the architecture such as the vector page which is located at 0xffff0000,
     * therefore a second level page table is already allocated covering
     * 0xfff00000 upwards.
     *
     * The cache flushing code in proc-xscale.S uses the virtual area between
     * 0xfffe0000 and 0xfffeffff.
     */
    
    #define FIXADDR_START        0xfff00000UL
    #define FIXADDR_TOP        0xfffe0000UL
    #define FIXADDR_SIZE        (FIXADDR_TOP - FIXADDR_START)
    
    #define FIX_KMAP_BEGIN        0
    #define FIX_KMAP_END        (FIXADDR_SIZE >> PAGE_SHIFT)
    
    #define __fix_to_virt(x)    (FIXADDR_START + ((x) << PAGE_SHIFT))
    #define __virt_to_fix(x)    (((x) - FIXADDR_START) >> PAGE_SHIFT)
  • 相关阅读:
    JS 异步编程
    JS XMLHttpRequest
    JS 日期
    JS DOM
    JS 异常处理
    JS BOM
    JS 正则表达式
    JS 面向对象
    (22)python PhantomJS
    HDU1698 线段树(区间更新区间查询)
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/9538909.html
Copyright © 2011-2022 走看看