内存管理@初始化:修订间差异

来自个人维基
跳转到导航 跳转到搜索
Hovercool留言 | 贡献
无编辑摘要
 
Hovercool留言 | 贡献
无编辑摘要
第36行: 第36行:
...  
...  
</pre>
</pre>
<pre class="prettyprint">
#define GFP_ZONE_TABLE ( \
(ZONE_NORMAL << 0 * ZONES_SHIFT)       \
| (OPT_ZONE_DMA << ___GFP_DMA * ZONES_SHIFT)       \
| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * ZONES_SHIFT)       \
| (OPT_ZONE_DMA32 << ___GFP_DMA32 * ZONES_SHIFT)       \
| (ZONE_NORMAL << ___GFP_MOVABLE * ZONES_SHIFT)       \
| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * ZONES_SHIFT)       \
| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * ZONES_SHIFT)  \
| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * ZONES_SHIFT)  \
)
/*
* GFP_ZONE_BAD is a bitmap for all combinations of __GFP_DMA, __GFP_DMA32
* __GFP_HIGHMEM and __GFP_MOVABLE that are not permitted. One flag per
* entry starting with bit 0. Bit is set if the combination is not
* allowed.
*/
#define GFP_ZONE_BAD ( \
1 << (___GFP_DMA | ___GFP_HIGHMEM)       \
| 1 << (___GFP_DMA | ___GFP_DMA32)       \
| 1 << (___GFP_DMA32 | ___GFP_HIGHMEM)       \
| 1 << (___GFP_DMA | ___GFP_DMA32 | ___GFP_HIGHMEM)       \
| 1 << (___GFP_MOVABLE | ___GFP_HIGHMEM | ___GFP_DMA)       \
| 1 << (___GFP_MOVABLE | ___GFP_DMA32 | ___GFP_DMA)       \
| 1 << (___GFP_MOVABLE | ___GFP_DMA32 | ___GFP_HIGHMEM)       \
| 1 << (___GFP_MOVABLE | ___GFP_DMA32 | ___GFP_DMA | ___GFP_HIGHMEM)  \
)
static inline enum zone_type gfp_zone(gfp_t flags)
{
enum zone_type z;
int bit = (__force int) (flags & GFP_ZONEMASK);
z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
((1 << ZONES_SHIFT) - 1);
VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
return z;
}
</pre>
gfp_zone函数是作用是,输入 gfp类型,转换成对应的 zone类型输出。
其中,GFP_ZONE_TABLE是 gfp_flags - zones的对应表;GFP_ZONE_BAD同样是一个表,以 gfp_flags为位移,对应位的数值为 1表示不允许这样的组合,用来判定 gfp标志组合的合法性。

2015年12月15日 (二) 04:14的版本

特定于体系结构的设置

x86

start_kernel
└ setup_arch
    └ setup_memory_map
        └ x86_init.resources.memory_setup
           └ default_machine_specific_memory_setup //创建一个列表,包括系统占据的内存区和空闲内存区
           └ printk(KERN_INFO "BIOS-provided physical RAM map:\n");
           └ e820_print_map(who); //打印出结果,如图1
        └ paging_init
           └ pagetable_init
              └ permanent_kmaps_init
           └ __flush_tlb_all
           └ kmap_init
<图1>

$dmesg
... 
BIOS-provided physical RAM map: 
  BIOS-e820: 0000000000000000 -000000000009e800 (usable) 
  BIOS-e820: 000000000009e800 -00000000000a0000 (reserved) 
  BIOS-e820: 00000000000c0000 -00000000000cc000 (reserved) 
  BIOS-e820: 00000000000d8000 -0000000000100000 (reserved) 
  BIOS-e820: 0000000000100000 -0000000017cf0000 (usable) 
  BIOS-e820: 0000000017cf0000 -0000000017cff000 (ACPI data) 
  BIOS-e820: 0000000017cff000 -0000000017d00000 (ACPI NVS) 
  BIOS-e820: 0000000017d00000 -0000000017e80000 (usable) 
  BIOS-e820: 0000000017e80000 -0000000018000000 (reserved) 
  BIOS-e820: 00000000ff800000 -00000000ffc00000 (reserved) 
  BIOS-e820: 00000000fff00000 -0000000100000000 (reserved) 
... 


#define GFP_ZONE_TABLE ( \
	(ZONE_NORMAL << 0 * ZONES_SHIFT)				      \
	| (OPT_ZONE_DMA << ___GFP_DMA * ZONES_SHIFT)			      \
	| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * ZONES_SHIFT)		      \
	| (OPT_ZONE_DMA32 << ___GFP_DMA32 * ZONES_SHIFT)		      \
	| (ZONE_NORMAL << ___GFP_MOVABLE * ZONES_SHIFT)			      \
	| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * ZONES_SHIFT)	      \
	| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * ZONES_SHIFT)   \
	| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * ZONES_SHIFT)   \
)

/*
 * GFP_ZONE_BAD is a bitmap for all combinations of __GFP_DMA, __GFP_DMA32
 * __GFP_HIGHMEM and __GFP_MOVABLE that are not permitted. One flag per
 * entry starting with bit 0. Bit is set if the combination is not
 * allowed.
 */
#define GFP_ZONE_BAD ( \
	1 << (___GFP_DMA | ___GFP_HIGHMEM)				      \
	| 1 << (___GFP_DMA | ___GFP_DMA32)				      \
	| 1 << (___GFP_DMA32 | ___GFP_HIGHMEM)				      \
	| 1 << (___GFP_DMA | ___GFP_DMA32 | ___GFP_HIGHMEM)		      \
	| 1 << (___GFP_MOVABLE | ___GFP_HIGHMEM | ___GFP_DMA)		      \
	| 1 << (___GFP_MOVABLE | ___GFP_DMA32 | ___GFP_DMA)		      \
	| 1 << (___GFP_MOVABLE | ___GFP_DMA32 | ___GFP_HIGHMEM)		      \
	| 1 << (___GFP_MOVABLE | ___GFP_DMA32 | ___GFP_DMA | ___GFP_HIGHMEM)  \
)

static inline enum zone_type gfp_zone(gfp_t flags)
{
	enum zone_type z;
	int bit = (__force int) (flags & GFP_ZONEMASK);

	z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
					 ((1 << ZONES_SHIFT) - 1);
	VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
	return z;
}

gfp_zone函数是作用是,输入 gfp类型,转换成对应的 zone类型输出。
其中,GFP_ZONE_TABLE是 gfp_flags - zones的对应表;GFP_ZONE_BAD同样是一个表,以 gfp_flags为位移,对应位的数值为 1表示不允许这样的组合,用来判定 gfp标志组合的合法性。