免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 877 | 回复: 0
打印 上一主题 下一主题

从物理地址到内核虚拟地址的映射 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-27 21:52 |只看该作者 |倒序浏览
—分析AT91SAM9261EK板子上9261芯片自带的LCD控制器的驱动程序

  本文分析了AT91SAM9261EK板子上9261芯片自带的LCD控制器的驱动程序中是如何实现从物理地址到内核虚拟地址的映射。
  当系统执行/drivers/video/atmel_lcdfb.c中的atmel_lcdfb_init()时,调用
platform_driver_probe(&atmel_lcdfb_driver, atmel_lcdfb_probe)函数,首先以atmel_lcdfb_driver中()的name "atmel_lcdfb"为依据来搜索系统注册的device中有没有这个platform_device,如果有这个设备,则向系统注册该设备的驱动。
static struct platform_driver atmel_lcdfb_driver = {
    .remove        =
__exit_p(atmel_lcdfb_remove),
    .driver        = {
        .name    =
"atmel_lcdfb",
        .owner    = THIS_MODULE,
    },
};
由于在/arch/arm/mach-at91/at91sam9261_devices.c中有下面的platform_device at91_lcdc_device,
static struct platform_device at91_lcdc_device = {
    .name        =
"atmel_lcdfb",
    .id        = 0,
    .dev        = {
              
.dma_mask        = &lcdc_dmamask,
              
.coherent_dma_mask    = 0xffffffff,
              
.platform_data        = &lcdc_data,
    },
    .resource    = lcdc_resources,
    .num_resources    =
ARRAY_SIZE(lcdc_resources),
};
它的name也为"atmel_lcdfb",并且在at91_add_device_lcdc()函数中已经向系统注册了该设备,所以当执行
atmel_lcdfb_probe()函数中的map = platform_get_resource(pdev, IORESOURCE_MEM, 1)时,即可得到下面定义的lcdc_resources参数,其中AT91SAM9261_LCDC_BASE即为 LCD User Interface 的起始地址0x600000,也即物理地址;AT91SAM9261_LCDC_BASE + SZ_4K
- 1为结束地址。
static struct resource lcdc_resources[] = {
    [0] = {
        .start    =
AT91SAM9261_LCDC_BASE,
        .end    =
AT91SAM9261_LCDC_BASE + SZ_4K - 1,
        .flags    =
IORESOURCE_MEM,
    },
    [1] = {
        .start    = AT91SAM9261_ID_LCDC,
        .end    =
AT91SAM9261_ID_LCDC,
        .flags    =
IORESOURCE_IRQ,
    },
#if defined(CONFIG_FB_INTSRAM)
    [2] = {
        .start    =
AT91SAM9261_SRAM_BASE,
        .end    =
AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1,
        .flags    =
IORESOURCE_MEM,
    },
#endif
};
然后通过ioremap()函数实现从物理地址到内核虚拟地址的映射,也即sinfo->mmio
= ioremap(info->fix.mmio_start, info->fix.mmio_len);其中的
info->fix.mmio_start = regs->start(即AT91SAM9261_LCDC_BASE);
    info->fix.mmio_len = regs->end(即AT91SAM9261_LCDC_BASE + SZ_4K - 1)
- regs->start + 1;
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/26525/showart_391422.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP