浅析armlinux-setup_arch()->request_standard_resources()函数6
文章来源:http://gliethttp.cublog.cn
建议首先参考《浅析armlinux2_4_19启动程序[head-armv.s文件]》[http://gliethttp.cublog.cn]
request_standard_resources()函数主要是完成对从内核启动到此时,cpu使用到的所有外围总线设备实体的注册登记工作. 由函数request_resource()来完成登记注册工作,request_resource()将cpu总线上所有设备实体进行单向由小到大的线性登记注册链接, 可以参看《我看linux对挂接在4G总线空间上的设备实体的管理方式-resource结构体》和 《linux下request_mem_region的粗略理解》两篇文章[http://gliethttp.cublog.cn].
static void __init request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) {struct resource *res; int i; kernel_code.start = __virt_to_phys(init_mm.start_code); kernel_code.end = __virt_to_phys(init_mm.end_code - 1); kernel_data.start = __virt_to_phys(init_mm.end_code); kernel_data.end = __virt_to_phys(init_mm.brk - 1);
for (i = 0; i < mi->nr_banks; i++) { unsigned long virt_start, virt_end; if (mi->bank[i].size == 0) continue; //总线上的所有memory, virt_start = __phys_to_virt(mi->bank[i].start); virt_end = virt_start + mi->bank[i].size - 1;
res = alloc_bootmem_low(sizeof(*res));//申请res存储空间 res->name = "System RAM";//该设备实体的名称 res->start = __virt_to_phys(virt_start); res->end = __virt_to_phys(virt_end);//该设备实体地址段 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res);//将该设备实体登记注册到总线空间链表 if (kernel_code.start >= res->start && kernel_code.end <= res->end) //如果kernel_code在这个memory内,那么将kernel_code这个比较有特性的设备实体登记注册到 //res[该memory实体]设备实体下,来详细描述res内部地址空间中一些比较有特色的设备实体的分布情况 //进而使linux能够给用户提供一个更加详细,充实的cpu外围总线设备的级联图解情况. //res就像一个倒挂的树,res是树根,kernel_code是倒挂在res这个树根下的一根枝儿. // [...................................res...................................]//树根 // | | // | [..kernel_data..]//又生出来一根枝儿[gliethttp] // [..kernel_code..]//生出来一根枝儿[gliethttp] request_resource(res, &kernel_code);//将kernel_code设备实体登记注册到res空间 if (kernel_data.start >= res->start && kernel_data.end <= res->end) request_resource(res, &kernel_data);//将kernel_code设备实体登记注册到res空间 } //ok,到这里所有总线上的外部内存都已经登记注册了,这些空间已经被告知linux---占用了. if (mdesc->video_start) { video_ram.start = mdesc->video_start; video_ram.end = mdesc->video_end; //将video,液晶之类的设备实体占用的总线地址空间段,进行登记注册. request_resource(&iomem_resource, &video_ram); } //登记注册以下,io口,这些io口在linux系统运行起来之后,只能由如下的设备使用,不能他用. if (mdesc->reserve_lp0) request_resource(&ioport_resource, &lp0); if (mdesc->reserve_lp1) request_resource(&ioport_resource, &lp1); if (mdesc->reserve_lp2) request_resource(&ioport_resource, &lp2); }
|