内存管理小结(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\n",
            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\n",
            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)

 

posted @ 2018-08-26 21:05  bluebluebluesky  阅读(475)  评论(0编辑  收藏  举报