squid日志的分割
作者 佚名技术
来源 Linux系统
浏览
发布时间 2012-07-04
址单元.
拥有帝国一切,皆有可能。欢迎访问phome.net (2)内存映射方式(Memory-mapped) RISC指令系统的CPU(如ARM、PowerPC等)通常只实现一个物理地址空间,外设I/O端口成为内存的一部分.此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令. 但是,这两者在硬件实现上的差异对于软件来说是完全透明的,驱动程序开发人员可以将内存映射方式的I/O端口和外设内存统一看作是“I/O内存”资源. 一般来说,在系统运行时,外设的I/O内存资源的物理地址是已知的,由硬件的设计决定.但是CPU通常并没有为这些已知的外设I/O内存资源的物理地址预定义虚拟地址范围,驱动程序并不能直接通过物理地址访问I/O内存资源,而将它们映射到核心虚地址空间内(通过页表),然后才能根据映射所得到的核心虚地址范围,通过访内指令访问这些I/O内存资源.Linux在io.h头文件中声明了函数ioremap(),用来将I/O内存资源的物理地址映射到核心虚地址空间(3GB-4GB)中,原型如下: void * ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); iounmap函数用于取消ioremap()所做的映射,原型如下: void iounmap(void * addr); 这两个函数都是实现在mm/ioremap.c文件中. 在将I/O内存资源的物理地址映射成核心虚地址后,理论上讲我们就可以象读写RAM那样直接读写I/O内存资源了.为了保证驱动程序的跨平台的可移植性,我们应该使用Linux中特定的函数来访问I/O内存资源,而不应该通过指向核心虚地址的指针来访问.如在x86平台上,读写I/O的函数如下所示: #define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) #define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) #define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) 拥有帝国一切,皆有可能。欢迎访问phome.net#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) #define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) #define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) #define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c)) ,我们要特别强调驱动程序中mmap函数的实现方法.用mmap映射一个设备,意味着使用户空间的一段地址关联到设备内存上,这只要程序在分配的地址范围内进行读取或者写入,实际上就是对设备的访问. 笔者在Linux源代码中进行包含“ioremap”文本的搜索,发现真正出现的ioremap的地方相当少.笔者追根索源地寻找I/O操作的物理地址转换到虚拟地址的真实所在,发现Linux有替代ioremap的语句,但是这个转换过程却是不可或缺的. 譬如我们再次摘取S3C2410这个ARM芯片RTC(实时钟)驱动中的一小段: static void get_rtc_time(int alm, struct rtc_time *rtc_tm) { spin_lock_irq(&rtc_lock); if (alm == 1) { rtc_tm->tm_year = (unsigned char)ALMYEAR & Msk_RTCYEAR; rtc_tm->tm_mon = (unsigned char)ALMMON & Msk_RTCMON; rtc_tm->tm_mday = (unsigned char)ALMDAY & Msk_RTCDAY; rtc_tm->tm_hour = (unsigned char)ALMHOUR & Msk_RTCHOUR; rtc_tm->tm_min = (unsigned char)ALMMIN & Msk_RTCMIN; rtc_tm->tm_sec = (unsigned char)ALMSEC & Msk_RTCSEC; } else { read_rtc_bcd_time: rtc_tm->tm_year = (unsigned char)BCDYEAR & Msk_RTCYEAR; rtc_tm->tm_mon = (unsigned char)BCDMON & Msk_RTCMON; rtc_tm->tm_mday = (unsigned char)BCDD |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |
你可能对下面的文章感兴趣
关于squid日志的分割的所有评论