numa
非numa结构
在mm/page_alloc.c中
#ifndef CONFIG_DISCONTIGMEM
static bootmem_data_t contig_bootmem_data;
struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data };
在include/linux/mmzone.h中:
#ifndef CONFIG_DISCONTIGMEM extern struct pglist_data contig_page_data;
#define NODE_DATA(nid) (&contig_page_data)
说明:静态变量bootmem_data contig_bootmem_data首先初始化为0,contig_page_data就是保存节点内容的。
在mm/page_alloc.c中
struct pglist_data *pgdat_list;
首先初始化在mm/bootmem.c中:
51 static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
52 unsigned long mapstart, unsigned long start, unsigned long end)
53 {
54 bootmem_data_t *bdata = pgdat->bdata;
55 unsigned long mapsize = ((end - start)+7)/8;
56
57 pgdat->pgdat_next = pgdat_list;
58 pgdat_list = pgdat;
59
60 mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
61 bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
62 bdata->node_boot_start = (start << PAGE_SHIFT);
63 bdata->node_low_pfn = end;
64
65 /*
66 * Initially all pages are reserved - setup_arch() has to
67 * register free RAM areas explicitly.
68 */
69 memset(bdata->node_bootmem_map, 0xff, mapsize);
70
71 return mapsize;
72 }
pgdat->pgdat_next=pgdat_list=NULL;
pgdat_list=pgdat;
在arch/i386/kernel/setup.c中
start_pfn = PFN_UP(init_pg_tables_end);
find_max_pfn();
bootmap_size = init_bootmem(start_pfn, max_low_pfn);
PFN的定义
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
start_pfn = PFN_UP(init_pg_tables_end) //0x0
PFN是page frame number的缩写,所谓page frame,就是针对物理内存而言的,把物理内存分成一个个的page size的区域,并且给每一个page 编号,这个号码就是PFN。假设物理内存从0地址开始,那么PFN等于0的那个页帧就是0地址(物理地址)开始的那个page。假设物理内存从x地址开始,那么第一个页帧号码就是(x>>PAGE_SHIFT)。
PFN_UP和PFN_DOWN中的参数x是物理地址,x不是物理地址。
PFN_UP(x),如果物理地址第12位全为0,则是当前页帧;如果低12位不为0,则是下一个页帧。
PFN_DOWN(x)就是当前页帧
PFN_PHYS(x),x就是页帧,转换后就是物理地址。
说明:
1< <N <======> 2^N
2^12-1 <======> 0xFFF
sanitize_e820_map
446 /*
447 Visually we're performing the following (1,2,3,4 = memory types)...
448
449 Sample memory map (w/overlaps):
450 ____22__________________
451 ______________________4_
452 ____1111________________
453 _44_____________________
454 11111111________________
455 ____________________33__
456 ___________44___________
457 __________33333_________
458 ______________22________
459 ___________________2222_
455 ____________________33__
456 ___________44___________
457 __________33333_________
458 ______________22________
459 ___________________2222_
460 _________111111111______
461 _____________________11_
462 _________________4______
463
464 Sanitized equivalent (no overlap):
465 1_______________________
466 _44_____________________
467 ___1____________________
468 ____22__________________
469 ______11________________
470 _________1______________
471 __________3_____________
472 ___________44___________
473 _____________33_________
474 _______________2________
475 ________________1_______
476 _________________4______
477 ___________________2____
478 ____________________33__
479 ______________________4_
480 */
说明:
1第一幅图怎么到第二幅图,每一列中选出一个数字,如果同一列中有不同的数字,选择最大的数字;第一列中只有1,然后把1放在第一行第一列,第二列和第三列最大的是4,然后把44放在第2行中的2,3列,紧挨着的两个数字放一行,然后依次顺下去。