Android系统中添加内存分区(Zone)

1.  添加zone_type枚举类型

//路径: include/linux/Mmzone.h

enum zone_type {
#ifdef CONFIG_ZONE_DMA
	/*
	 * ZONE_DMA is used when there are devices that are not able
	 * to do DMA to all of addressable memory (ZONE_NORMAL). Then we
	 * carve out the portion of memory that is needed for these devices.
	 * The range is arch specific.
	 *
	 * Some examples
	 *
	 * Architecture		Limit
	 * ---------------------------
	 * parisc, ia64, sparc	<4G
	 * s390			<2G
	 * arm			Various
	 * alpha		Unlimited or 0-16MB.
	 *
	 * i386, x86_64 and multiple other arches
	 * 			<16M.
	 */
	ZONE_DMA,
#endif
#ifdef CONFIG_ZONE_DMA32
	/*
	 * x86_64 needs two ZONE_DMAs because it supports devices that are
	 * only able to do DMA to the lower 16M but also 32 bit devices that
	 * can only do DMA areas below 4G.
	 */
	ZONE_DMA32,
#endif
	/*
	 * Normal addressable memory is in ZONE_NORMAL. DMA operations can be
	 * performed on pages in ZONE_NORMAL if the DMA devices support
	 * transfers to all addressable memory.
	 */
	ZONE_NORMAL,
        ZONE_MEMSWAP,
#ifdef CONFIG_HIGHMEM
	/*
	 * A memory area that is only addressable by the kernel through
	 * mapping portions into its own address space. This is for example
	 * used by i386 to allow the kernel to address the memory beyond
	 * 900MB. The kernel will set up special mappings (page
	 * table entries on i386) for each page that the kernel needs to
	 * access.
	 */
	ZONE_HIGHMEM,
#endif
	ZONE_MOVABLE,
	__MAX_NR_ZONES
};

其中
ZONE_MEMSWAP,
即为添加zone对应的枚举类型


2. 修改内存初始化代码

//路径 arch/arm/mm/Init.c
static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
	unsigned long max_high)
添加代码

unsigned long mem_swap_size = 1UL << 15;
    unsigned long normal_start = min, normal_end = max_low - mem_swap_size;


zone_size[0] = normal_end - normal_start;
zone_size[ZONE_MEMSWAP] = mem_swap_size;

#ifdef CONFIG_HIGHMEM
	zone_size[ZONE_HIGHMEM] = max_high - max_low;
#endif

zhole_size[ZONE_MEMSWAP] = 0UL;

	for_each_memblock(memory, reg) {
		unsigned long start = memblock_region_memory_base_pfn(reg);
		unsigned long end = memblock_region_memory_end_pfn(reg);

		if (start < normal_end) {
			unsigned long low_end = min(end, normal_end);
			zhole_size[0] -= low_end - start;
		}

#ifdef CONFIG_HIGHMEM
		if (end > max_low) {
			unsigned long high_start = max(start, max_low);
			zhole_size[ZONE_HIGHMEM] -= end - high_start;
		}
#endif

3. 修改内存分配代码

//路径:mm/page_alloc.c

get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,
		struct zonelist *zonelist, int high_zoneidx, int alloc_flags,
		struct zone *preferred_zone, int migratetype)


在上面函数的下述for循环开头添加如下代码:

for_each_zone_zonelist_nodemask(zone, z, zonelist,
						high_zoneidx, nodemask) {
...

        if (zone_idx(zone) == ZONE_MEMSWAP)
            continue;
...
}


同样是该路径的该函数:
static char * const zone_names[MAX_NR_ZONES] = {
#ifdef CONFIG_ZONE_DMA
	 "DMA",
#endif
#ifdef CONFIG_ZONE_DMA32
	 "DMA32",
#endif
	 "Normal",
     "MemSwap",
#ifdef CONFIG_HIGHMEM
	 "HighMem",
#endif
	 "Movable",
};
 
  






你可能感兴趣的:(Linux)