内存管理小结(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);
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)