Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15499069
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2007-08-08 15:39:41

浅析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);
}

阅读(3051) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~