最近初学Linux驱动程序的编写,其中用到gpio,使用readl函数和writel函数访问了GPMCON和GPMDAT寄存器。这两个寄存器在头文件gpio-bank-m.h中被定义为S3C64XX_GPMCON和S3C64XX_GPMDAT,但是它们到底代表哪个地址呢?我很好奇,于是一步步地进行跟踪。以下是跟踪过程:
-
/*
-
gpio-bank-m.h
-
*/
-
-
#define S3C64XX_GPMCON (S3C64XX_GPM_BASE+0x00)
-
#define S3C64XX_GPMDAT (S3C64XX_GPM_BASE+0x04)
-
/*
-
regs-gpio.h
-
*/
-
-
#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820)
-
#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO+(reg))
-
/*
-
map.h
-
*/
-
-
#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000)
-
/*
-
map-base.h
-
*/
-
-
#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000+(x))
-
#ifndef __ASSEMBLY__
-
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE+(x))
-
#else
-
#define S3C_ADDR(x) (S3C_ADDR_BASE+(x))
-
#endif
-
-
#define S3C_ADDR_BASE 0xF4000000
到此为止,终于找到了定义的源头。
根据这些宏定义进行推算,最后得出S3C64XX_GPMCON代表的地址为0xF4500820,S3C64XX_GPMDAT代表的地址为0xF4500824。而在S3C6410的官方手册中,GPMCON的地址为0x7F008820,GPMDAT的地址为0x7F008824,可见,readl和writel访问的地址为虚拟地址,而不是物理地址。那么驱动究竟是如何最终访问到GPMCON和GPMDAT这两个寄存器的呢?这就是接下来研究的重点。
阅读(1624) | 评论(0) | 转发(0) |