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

(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值