start_kernel
--> 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();
-
}
1.1 结构体meminfo的初始化
结构体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;
-
}
start_kernel
--> 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);
-
}
start_kernel
--> 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;
-
}
1.1.1 上面的函数指针是什么呢?
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);
在arch/arm/include/asm/setup.h中有如下定义:
-
#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};
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个
-
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
-
}
1.3 将内存的block信息存在memblock中
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;
-
}
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);
-
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;
-
}
-
}
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
-
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
].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
-
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;
-
}
阅读(1387) | 评论(0) | 转发(0) |