start_kernel
--> setup_arch ; arch/arm/kernel/setup.c
在arch/arm/kernel/setup.c中
start_kernel
--> setup_arch
1.1 结构体meminfo的初始化
结构体meminfo的初始化比较难找
start_kernel
--> setup_arch
start_kernel
--> setup_arch
--> parse_tags
start_kernel
--> setup_arch
--> parse_tags
--> parse_tag
1.1.1 上面的函数指针是什么呢?
start_kernel
--> setup_arch
--> parse_tags
--> parse_tag
--> parse_tag_mem32
在arch/arm/include/asm/setup.h中
有如下定义:
start_kernel
--> setup_arch
--> parse_tags
--> parse_tag
--> parse_tag_mem32
--> arm_add_memory
将内存起始与长度存在meminfo的bank中:
如果多次调用arm_add_memory,即板子上有多个内存bank,因为meminfo . nr_banks是一个全局变量,
这将会对每一个bank的起始与长度都保存到数组中,但不能超过8个
1.2 结构体meminfo的初始化
setup_arch
--> sanity_check_meminfo
在初始化好meminfo后就知道了内存中每个bank的起始地址和长度
1.3
将内存的block信息存在memblock中
setup_arch
--> arm_memblock_init
1.3.1 初始化memblock结构体
setup_arch
--> arm_memblock_init
--> iniit_memblock_init
定义在mm/memblock.c中
static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS + 1] __initdata_memblock;
1.3.2
初始化memblock结构体中的memory.region
setup_arch
--> arm_memblock_init
--> memblock_add
--> memblock_add_region
memblock_add(mi->bank[i].start, mi->bank[i].size);
1.3.3
初始化memblock结构体中的resever.region
setup_arch
--> arm_memblock_init
--> memblock_reserve
执行memblock_reserve的过程与 memblock_add的过程是一样的只是把memory.region.base与memory.region.size赋值了.
memblock . memory . regions [ 0 ] . base = 0x50008000 ;
memblock . memory . regions [ 0 ] . size = 0x8000000 ; //128M
memblock . memory . cnt = 1 ;
memblock . reserved . regions [ 0 ] . base = 0x50008000 ;
memblock . reserved . regions [ 0 ] . size = 0x734b10 ; //解压后内核在内存中的大小
memblock . reserved . cnt = 1 ;
1.3.4 还没有看明白
好像是将swap的信息整一下
setup_arch
--> arm_memblock_init
--> arm_mm_memblock_reserve
--> memblock_reserve
--> memblock_add_region
memblock
.
reserved
.
regions
[
0
]
.
base
=
0x50004000
;
//由0x50008000 --> 0x50004000
memblock . reserved . regions [ 0 ] . size = 0x734b10 ; //解压后内核在内存中的大小
memblock . reserved . cnt = 1 ;
1.3.5 将整个内存的大小存在memory_size中
setup_arch
--> arm_memblock_init
--> memblock_analyze
--> setup_arch ; arch/arm/kernel/setup.c
- asmlinkage void __init start_kernel(void)
- {
- setup_arch(&command_line);
- mm_init_owner(&init_mm, &init_task);
- mm_init_cpumask(&init_mm);
- page_alloc_init();
- parse_early_param();
- mm_init();
- idr_init_cache();
- }
在arch/arm/kernel/setup.c中
start_kernel
--> setup_arch
- void __init setup_arch(char **cmdline_p)
- {
- mdesc = setup_machine_fdt(__atags_pointer);
- if (!mdesc)
- mdesc = setup_machine_tags(machine_arch_type); //1. meminfo的初始化
- parse_early_param();
-
- sanity_check_meminfo(); //1.2 结构体meminfo的初始化
- arm_memblock_init(&meminfo, mdesc); //1.3 将内存的block信息存在memblock中
-
- paging_init(mdesc);
- request_standard_resources(mdesc);
-
- unflatten_device_tree();
-
- if (mdesc->init_early)
- mdesc->init_early();
- }
结构体meminfo的初始化比较难找
start_kernel
--> setup_arch
- static struct machine_desc * __init setup_machine_tags(unsigned int nr)
- {
- ..... //省略
- if (mdesc->fixup) //mdesc->fixxp ==NULL,下句不执行
- mdesc->fixup(mdesc, tags, &from, &meminfo);
-
- if (tags->hdr.tag == ATAG_CORE) {
- if (meminfo.nr_banks != 0)
- squash_mem_tags(tags);
- save_atags(tags);
- parse_tags(tags);
- }
- return mdesc;
- }
--> setup_arch
--> parse_tags
- static void __init parse_tags(const struct tag *t)
- {
- for (; t->hdr.size; t = tag_next(t))
- if (!parse_tag(t)) //在此处调用tag中的函数指针
- printk( "Ignoring unrecognised tag 0x%08x\n", t->hdr.tag);
- }
--> setup_arch
--> parse_tags
--> parse_tag
- static int __init parse_tag(const struct tag *tag)
- {
- extern struct tagtable __tagtable_begin, __tagtable_end;
- struct tagtable *t;
- for (t = &__tagtable_begin; t < &__tagtable_end; t++)
- if (tag->hdr.tag == t->tag) {
- t->parse(tag); //在此处调用tag中的函数指针
- break;
- }
- return t < &__tagtable_end;
- }
start_kernel
--> setup_arch
--> parse_tags
--> parse_tag
--> parse_tag_mem32
- 在arch/arm/kernel/setup.c中
- static int __init parse_tag_mem32(const struct tag *tag)
- {
- return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
- }
- __tagtable(ATAG_MEM, parse_tag_mem32);
- #define __tag __used __attribute__((__section__(".taglist.init")))
- #define __tagtable(tag, fn) \
- static struct tagtable __tagtable_##fn __tag = { tag, fn }
- 所以把__tagtable(ATAG_MEM, parse_tag_mem32);展开后:
- static struct tagtable __tagtable_parse_tag_mem32
- __used __attribute__((__section__(".taglist.init"))) = { ATAG_MEM , parse_tag_mem32};
--> setup_arch
--> parse_tags
--> parse_tag
--> parse_tag_mem32
--> arm_add_memory
将内存起始与长度存在meminfo的bank中:
如果多次调用arm_add_memory,即板子上有多个内存bank,因为meminfo . nr_banks是一个全局变量,
这将会对每一个bank的起始与长度都保存到数组中,但不能超过8个
- int __init arm_add_memory(phys_addr_t start, unsigned long size)
- {
- struct membank *bank = &meminfo.bank[meminfo.nr_banks];
- if (meminfo.nr_banks >= NR_BANKS) //#define NR_BANKS 8
return -EINVAL;
- size -= start & ~PAGE_MASK;
- bank->start = PAGE_ALIGN(start); //start = 0x50000000
- bank->size = size & PAGE_MASK; //size = 0x8000000=128M
- if (bank->size == 0)
- return -EINVAL;
- meminfo.nr_banks++; //现在nr_banks由0->1
- return 0;
- }
1.2 结构体meminfo的初始化
setup_arch
--> sanity_check_meminfo
在初始化好meminfo后就知道了内存中每个bank的起始地址和长度
- void __init sanity_check_meminfo(void)
- {
- // PHYS_OFFSET=0x50000000, PAGE_OFFSET=0xc0000000
// VMALLOC_START=0x800000, VMALLOC_END=0xf4000000
- // __va(bank->start)=0xc0000000,vmalloc_min=0xec000000
- for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
- struct membank *bank = &meminfo.bank[j];
- *bank = meminfo.bank[i];
-
- // CONFIG_HIGHMEM=y
- //物理内存映射后在高端,则highmem=1
- if (__va(bank->start) >= vmalloc_min || __va(bank->start) < (void *)PAGE_OFFSET)
- highmem = 1;
- bank->highmem = highmem; //此处highmem=0
- //如果物理内存映射后不在高端,但地址范围超过了高端地址,则highmem=1
- if (__va(bank->start) < vmalloc_min && bank->size > vmalloc_min - __va(bank->start))
- ;
- //开发板不属于以上两种情况,即highmem=0
- if (!bank->highmem && bank->start + bank->size > lowmem_limit)
- lowmem_limit = bank->start + bank->size;
-
- j++;
- }
- if (highmem) {
- }
- meminfo.nr_banks = j; //j=1
- memblock_set_current_limit(lowmem_limit); //lowmem_limit=0x58000000
- }
setup_arch
--> arm_memblock_init
- void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
- {
- //因为meminfo.nr_banks=1,所以这个sort没有起作用
- sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
- memblock_init(); //1.3.1 初始化memblock结构体
- for (i = 0; i < mi->nr_banks; i++) //nr_banks=1,所以只执行一次memblock_add
- memblock_add(mi->bank[i].start, mi->bank[i].size); //1.3.2初始化memblock的memory.region
-
- memblock_reserve(__pa(_stext), _end - _stext); //1.3.3初始化memblock的reserve.region
- arm_mm_memblock_reserve(); //1.3.4再次初始化memblock的reserve.region
- arm_dt_memblock_reserve(); //空函数,不用管
- if (mdesc->reserve) //没有定义mdesc->reserve
- mdesc->reserve();
- memblock_analyze(); //1.3.5 将整个内存的大小存在memory_size中
- memblock_dump_all();
- }
1.3.1 初始化memblock结构体
setup_arch
--> arm_memblock_init
--> iniit_memblock_init
定义在mm/memblock.c中
static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS + 1] __initdata_memblock;
- void __init memblock_init(void)
- {
- //函数只可执行一次
- static int init_done __initdata = 0;
- if (init_done)
- return;
- init_done = 1;
-
- memblock.memory.regions = memblock_memory_init_regions;
- memblock.memory.max = INIT_MEMBLOCK_REGIONS;
- memblock.reserved.regions = memblock_reserved_init_regions;
- memblock.reserved.max = INIT_MEMBLOCK_REGIONS;
-
- memblock.memory.regions[INIT_MEMBLOCK_REGIONS].base = (phys_addr_t)RED_INACTIVE;
- memblock.reserved.regions[INIT_MEMBLOCK_REGIONS].base = (phys_addr_t)RED_INACTIVE;
- memblock.memory.regions[0].base = 0;
- memblock.memory.regions[0].size = 0;
- memblock.memory.cnt = 1;
-
- memblock.reserved.regions[0].base = 0;
- memblock.reserved.regions[0].size = 0;
- memblock.reserved.cnt = 1;
-
- memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
- }
setup_arch
--> arm_memblock_init
--> memblock_add
--> memblock_add_region
memblock_add(mi->bank[i].start, mi->bank[i].size);
- long __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
- {
- return memblock_add_region(&memblock.memory, base, size);
- }
- static long __init_memblock memblock_add_region(struct memblock_type *type,
- phys_addr_t base, phys_addr_t size)
- {
- phys_addr_t end = base + size; //在函数memblock_init初始化中rgn->size=0
- for (i = 0; i < type->cnt; i++) { //所以这儿直接break了
- if (rgn->base > end || rgn->size == 0)
- break;
- }
- if ((type->cnt == 1) && (type->regions[0].size == 0)) { //进行两个赋值
- type->regions[0].base = base; //base=0x50000000
- type->regions[0].size = size; //size=0x8000000
- return 0;
- }
- }
setup_arch
--> arm_memblock_init
--> memblock_reserve
执行memblock_reserve的过程与 memblock_add的过程是一样的只是把memory.region.base与memory.region.size赋值了.
memblock . memory . regions [ 0 ] . base = 0x50008000 ;
memblock . memory . regions [ 0 ] . size = 0x8000000 ; //128M
memblock . memory . cnt = 1 ;
memblock . reserved . regions [ 0 ] . base = 0x50008000 ;
memblock . reserved . regions [ 0 ] . size = 0x734b10 ; //解压后内核在内存中的大小
memblock . reserved . cnt = 1 ;
1.3.4 还没有看明白
好像是将swap的信息整一下
setup_arch
--> arm_memblock_init
--> arm_mm_memblock_reserve
--> memblock_reserve
--> memblock_add_region
- void __init arm_mm_memblock_reserve(void)
- {
- //swap=0x50004000, size=0x4000
- memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
- }
- long __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
- {
- struct memblock_type *_rgn = &memblock.reserved;
- //base=0x50004000, size=0x4000
- return memblock_add_region(_rgn, base, size);
- }
-
- static long __init_memblock memblock_add_region(struct memblock_type *type,
- phys_addr_t base, phys_addr_t size)
- {
- phys_addr_t end = base + size;
- for (i = 0; i < type->cnt; i++) {
- struct memblock_region *rgn = &type->regions[i];
- phys_addr_t rend = rgn->base + rgn->size;
- rgn->base = base;
- rgn->size = rend - base;
- if (rend >= end)
- return 0;
- }
- }
memblock . reserved . regions [ 0 ] . size = 0x734b10 ; //解压后内核在内存中的大小
memblock . reserved . cnt = 1 ;
1.3.5 将整个内存的大小存在memory_size中
setup_arch
--> arm_memblock_init
--> memblock_analyze
- void __init memblock_analyze(void)
- {
- memblock.memory_size = 0;
- //memblock.memory_size=0x8000000
- for (i = 0; i < memblock.memory.cnt; i++)
- memblock.memory_size += memblock.memory.regions[i].size;
- memblock_can_resize = 1;
- }