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;
...
}


<pre name="code" class="cpp">同樣是該路徑的該函數:
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",
};








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章