Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2131292
  • 博文数量: 288
  • 博客积分: 10594
  • 博客等级: 上将
  • 技术积分: 3469
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-27 19:27
文章分类

全部博文(288)

文章存档

2012年(4)

2011年(30)

2010年(40)

2009年(32)

2008年(71)

2007年(79)

2006年(32)

分类: LINUX

2007-12-21 02:56:26

从物理地址到内核虚拟地址的映射

分析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;

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