linux驱动编程--内存与I/O访问

来源:互联网 发布:js文件怎么写 编辑:程序博客网 时间:2024/04/29 08:39

(still a problem)

一.

        1.1 MMU

                MMU(Memory Manage Unit)是一种辅助内存管理的硬件机制。由一组硬件设备共同协从硬件上为CPU提供访问安全检查,地址映射等功能。

                地址映射(物理地址和虚拟地址的映射)

                linux利用MMU建立了一个三级页表。

二.linux的内存管理

       内存空间指0~4GB的逻辑地址范围,实际物理来源可能包括: 物理内存, IO内存,IO端口等部分。其中0~3GB为用户空间,其每个进程有独立的逻辑映射关系。3~4GB为内核空间,其逻辑映射关系始终不变。其中内核空间又详细的分为:物理内存映射区--//--vmalloc映射区-- //--高端内存映射区--...--保留区;其中物理内存映射区包含896MB的范围,映射关系是简单的线性映射,超出896MB的范围非线性映射到高端内存映射区。一般用kmalloc__get_free_page申请的内存就是在这个区域。

       2.1 用户空间内存的动态申请

                malloc();                free();

        2.2 内核空间内存的动态申请

                kmalloc();       //较适合小内存申请                  kfree();                __get_free_pages();   //页申请                  release_pages();                vmalloc();       //大内存申请,至少超过一页                  vfree();

三.IO端口和IO内存

                 IO端口和IO内存的最大区别在于地址的编码方式,IO内存与普通内存是统一编址,IO端口是单独编制。

        3.1 访问IO端口

                              对IO端口的访问可以直接访问,也可以将其映射到内存空间中间接访问。

                             3.1.1 直接访问

request_region( unsigned long first, unsigned long n, const char *name);//申请IO端口inb();//直接访问outb();release_region( unsigned long start, unsigned long n);


                             3.1.2  间接访问

request_region( unsigned long first, unsigned long n, const char *name);//申请IO端口ioport_map(port,nr);//地址映射到内存区ioread8(X);ioread8_rep(p,dst,count);ioport_unmap(addr);release_region( unsigned long start, unsigned long n);

        3.2 访问IO内存

                             3.2.1 动态映射

//在需要时再将物理地址动态映射到内核空间中request_mem_region(start,n,name);//申请IO内存ioremap(cookie,size);/*io操作*/iounmap(cookie);release_mem_region(start,n);

            

                             3.2.2 静态映射

                                                    由系统自动将物理地址动态映射进内存。在板级文件中有一个记录内存映射信息的数组,通常如下

static struct map_desc io_desc[] = {{.virtual = IO_ADDRESS(x),.pfn = __phys_to_pfn(paddr),.length = SZ_4K,.type = MT_DEVICE,},{},{},};

                                                   然后系统会调用iotable_init(map,num)将该段地址映射进内存。

        3.3 设备地址到用户空间的映射                     

//将设备地址空间映射到用户空间mmap(struct file * file,struct vm_area_struct * vma);munmap(void *,int);

        3.4 (*)slab               

kmem_cache_create(const char * name,size_t size,size_t align,unsigned long flags,void(* ctor)(void *));kmem_cache_alloc(struct kmem_cache * cachep,gfp_t flags);kmem_cache_free(struct kmem_cache * cachep,void * objp);kmem_cache_destroy(struct kmem_cache * cachep);

        3.5 (*)内存池

mempool_create(int min_nr,mempool_alloc_t * alloc_fn,mempool_free_t * free_fn,void * pool_data);mempool_alloc(mempool_t * pool,gfp_t gfp_mask);mempool_free(void * element,mempool_t * pool);mempool_destroy(mempool_t * pool);

 四.DMA

                DMA是一种设备与内存进行高速数据交换的方式,并不需要驱动。常见的问题是有可能导致内存与cache的内存信息不一致,而使程序运行出错。

 

0 0
原创粉丝点击