




已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2410下寄存器地址虚实映射的实现我们知道在我们的驱动里面一般操作的寄存器的地址都是虚拟地址,然而一般在cpu的datasheet里描述的寄存器的地址都是物理地址,那linux内核是如何把我们驱动中指定操作的虚拟地址转换成正真可寻址并操作的物理地址的呢?这篇文档以s3c2410为例,将详细的描述这么一个实现流程。S3c2410使用的是arm920T的核,它支持MMU,正因为这样它才可以进行虚拟地址到物理地址的转换。而诸如使用arm7核的CPU一般都无法进行类似的转换,就在于它没有MMU,所以它上面能跑的操作系统也是去掉了MMU功能后的linux如uClinux,关于MMU的原理可参考相关文档。我们先来看文件Map.hincludeasm-armarch-s3c2410Map.h:#ifndef _ASSEMBLY_#define S3C2410_ADDR(x)(void _iomem _force *)0xF0000000 + (x)#else#define S3C2410_ADDR(x)(0xF0000000 + (x)#endif#define S3C2400_ADDR(x)S3C2410_ADDR(x)/* interrupt controller is the first thing we put in, to make* the assembly code for the irq detection easier*/#define S3C24XX_VA_IRQS3C2410_ADDR(0x00000000)#define S3C2400_PA_IRQ(0x14400000)#define S3C2410_PA_IRQ(0x4A000000)#define S3C24XX_SZ_IRQSZ_1M/* memory controller registers */#define S3C24XX_VA_MEMCTRL S3C2410_ADDR(0x00100000)#define S3C2400_PA_MEMCTRL (0x14000000)#define S3C2410_PA_MEMCTRL (0x48000000)#define S3C24XX_SZ_MEMCTRL SZ_1M我们可以看到IRQ的寄存器虚拟地址定义为0xF0000000,而物理地址为0x4A000000(这可从2410的datasheet上查到),memory控制器的寄存器虚拟地址定义为0xF0000000 + 0x00100000的地址处,物理地址为0x48000000,其他如lcd等寄存器都在这里定义了虚拟地址,当然这里仅仅是定义而已,还没有和物理地址达成映射的联系。我们接着看。我们来看2410的machine_desc结构:archarmmach-s3c2410Mach-smdk2410.c:MACHINE_START(SMDK2410, SMDK2410) /* TODO: request a new identifier and switch* to SMDK2410 */* Maintainer: Jonas Dietsche */.phys_io= S3C2410_PA_UART,.io_pg_offst= (u32)S3C24XX_VA_UART) 18) & 0xfffc,.boot_params= S3C2410_SDRAM_PA + 0x100,.map_io=smdk2410_map_io,.init_irq= s3c24xx_init_irq,.init_machine= smdk2410_init,.timer= &s3c24xx_timer,MACHINE_END这里定义了一个描述2410开发板的结构,其中的map_io, init_irq, init_machine都会在系统跑起来的时候被调用,我们这里要看的是smdk2410_map_io,这个函数完成后我们的虚拟地址和物理地址的映射关系就完成了。archarmmach-s3c2410Mach-smdk2410.c:static void _init smdk2410_map_io(void)s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc); /重点在这行s3c24xx_init_clocks(0);s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs);该函数调用s3c24xx_init_io来完成实质的东西。smdk2410_iodesc的定义如下:archarmmach-s3c2410Mach-smdk2410.c:static struct map_desc smdk2410_iodesc _initdata = /* nothing here yet */;这是一个保存虚拟地址和物理地址的映射关系表,内核通过这个参数的指导来完成映射关系。当然我们可以在这里添加我们需要映射的东东了。不过这里并没有条目,很简单因为在后面还会有这样的映射表。archarmplat-s3c24xxcpu.c:void _init s3c24xx_init_io(struct map_desc *mach_desc, int size)unsigned long idcode = 0x0;/* initialise the io descriptors we need for initialisation */iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc);/完成映射/获取当前系统的CPUif (cpu_architecture() = CPU_ARCH_ARMv5) idcode = s3c24xx_read_idcode_v5(); else idcode = s3c24xx_read_idcode_v4();cpu = s3c_lookup_cpu(idcode);if (cpu = NULL) printk(KERN_ERR Unknown CPU type 0x%08lxn, idcode);panic(Unknown S3C24XX CPU);printk(CPU %s (id 0x%08lx)n, cpu-name, idcode);if (cpu-map_io = NULL | cpu-init = NULL) printk(KERN_ERR CPU %s support not enabledn, cpu-name);panic(Unsupported S3C24XX CPU);(cpu-map_io)(mach_desc, size);/调用CPU相关的映射函数完成映射关系的核心就在这个函数里了,对iotable_init()的调用完成了s3c_iodesc里的映射条目的映射。而这个函数也是最最核心的东东了。我们先来看要完成映射的条目有那些archarmplat-s3c24xxcpu.c:static struct map_desc s3c_iodesc _initdata = IODESC_ENT(GPIO),/GPIO寄存器虚实地址映射IODESC_ENT(IRQ),/中断寄存器虚实地址映射IODESC_ENT(MEMCTRL), /IODESC_ENT(UART)/.;这个就是要进行虚实地址映射的映射表了,里面的每个条目都对应一个映射关系,用map_desc来描述,我们来看map_descincludeasm-armmachMap.h:struct map_desc unsigned long virtual;/虚拟地址unsigned long pfn;/对应的物理地址unsigned long length;/映射长度unsigned int type;/类型。;我们以IRQ的映射关系为例来看一下:先看IODESC_ENT的定义:#define IODESC_ENT(x) (unsigned long)S3C24XX_VA_#x, _phys_to_pfn(S3C24XX_PA_#x), S3C24XX_SZ_#x, MT_DEVICE 则IODESC_ENT(IRQ)就是:(unsigned long)S3C24XX_VA_IRQ,_phys_to_pfn(S3C24XX_PA_IRQ),S3C24XX_SZ_IRQ,MT_DEVICE而S3C24XX_VA_IRQ等都在includeasm-armarch-s3c2410Map.h下定义过了。因此这个条目解释就是虚拟地址为0xF0000000开始长度为1M的虚拟地址空间由MMU转换成物理地址为0x4A000000开始的1M地址空间,这正是IRQ寄存器物理地址所在位置。条目定义好了,剩下的就是要让系统MMU知道并在遇到这样一个虚拟地址时能正确映射到具体的物理地址。而这个工作就是由iotable_init完成的。ArcharmmmMmu.c:void _init iotable_init(struct map_desc *io_desc, int nr)int i;for (i = 0; i virtual != vectors_base() & md-virtual pfn), md-virtual);return;if (md-type = MT_DEVICE | md-type = MT_ROM) &md-virtual = PAGE_OFFSET & md-virtual pfn), md-virtual);type = &mem_typesmd-type;/获取memory类型/* Catch 36-bit addresses*/if (md-pfn = 0x100000) create_36bit_mapping(md, type);return;addr = md-virtual & PAGE_MASK;/得到虚拟地址phys = (unsigned long)_pfn_to_phys(md-pfn);/得到物理地址length = PAGE_ALIGN(md-length + (md-virtual & PAGE_MASK);/映射长度if (type-prot_l1 = 0 & (addr | phys | length) & SECTION_MASK) printk(KERN_WARNING BUG: map for 0x%08lx at 0x%08lx can not be mapped using pages, ignoring.n,_pfn_to_phys(md-pfn), addr);return;pgd = pgd_offset_k(addr);end = addr + length;do unsigned long next = pgd_addr_end(addr, end);alloc_init_section(pgd, addr, next, phys, type);phys += next - addr;addr = next; while (pgd+, addr != end);这个函数涉及到了相当多的MMU方面的知识,一般系统中会有一个页表,页表中的每个条目都是一个映射关系,包括对应的物理地址,及该块物理地址区域访问的各种属性等,而该页表的地址被保存在了MMU中的一个寄存器中。当我们在驱动中要访问某个寄存器时,一般都使用的是虚拟地址,这个虚拟地址被分成了两个区域,高地址的若干位其实是个inde
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年高压化成箔项目建议书
- 2025年甘肃省民航机场集团校园招聘45人模拟试卷附答案详解(完整版)
- Glutaraldehyde-生命科学试剂-MCE
- 2025年台州温岭市第一人民医院招聘医学卫生类高层次人才9人模拟试卷及答案详解(必刷)
- 2025年湿式静电除尘器合作协议书
- 2025河南九域龙源电力发展集团有限公司等单位高校毕业生招聘180人模拟试卷及答案详解(典优)
- 资产管理行业工艺流程与标准
- 2025国家自然资源部所属单位招聘118人(第三批)模拟试卷及答案详解(新)
- 婚内相处协议书7篇
- 财务预算编制模板全面管理指导
- (完整版)高压成套配电柜安装施工方案
- 隧道运营安全培训
- 2024城市综合管廊工程技术标准
- 2025年1月浙江卷化学试题(解析版)
- 煤炭信息化知识培训总结课件
- 农村妇联会议记录范文
- 油田井下作业案例课件
- 项目管理范围管理及计划分解模板
- 2025年中国工商银行校园招聘考试题库历年考试真题及答案
- 挺身式跳远技术
- 2025年香港销售合同范本
评论
0/150
提交评论