7.驱动小知识点

1.linux内核内存的使用
1.1 整体结构图

内存结构图

1.2 相关函数
  • vmalloc 物理上不连续 会睡眠, 效率低,一般不得已在分配大块内存时才使用
  • kmalloc(<128k) 基于kmem_cache 物理连续 常用GFP_KERNEL, 中断时要用GFP_ATOMIC(不可睡眠) 适合分配小于128K的
  • get_free_pages(n) < 4M
  • kmem_cache_alloc 基于slab 适合分配和释放数据结构。 (slab是反复分配同一大小的,会保留原来的数据,不再重初始化)
2.自动创建设备节点

管理设备文件方法演变 mkdnod – > devfs(动态 内核) --> udev(真实 用户)

2.1 devfs优缺点

是由Linux2.4 引入的,它使得设备驱动能管理自己,如创建删除/dev,修改权限等。

  • 优点
    1. 无需手动mknod ,它可devfs_mk_cdev 等自动生成
    2. 不需要指定主次设备号,传0的主设备号,它会动态获取。
  • 缺点
    1. 不确定的设备映射
    2. /dev下文件太多,且不是表示当前系统实际的设备
2.2 udev介绍

是由linux2.6 引入的用于替代devfs。

  • 优点
    1. 稳定的设备映射
    2. /dev下只包含系统真实存在的设备
    3. 无需手动mknod,用device_create会自动创建
2.3 udev使用
		#include <linux/kernel.h>      
        struct class *my_class;	
        
        static int  led_init(void)
       {  
        		.....      
						/* 创建自己的类 */
						my_class = class_create(THIS_MODULE, "own_class");
						if (IS_ERR(my_class)) {
							printk("Err: failed in creating class.\n");
							return ;
						}
					
						/* 在sysfs中注册您自己的设备,这将导致udevd创建相应的设备节点 */
						device_create(my_class,NULL, devno, NULL,"own_dev");      
		}
3.map映射机制
3.1 静态映射 map_dec

静态映射硬件物理地址到内核虚拟地址空间,内核启动时会自动完成该映射

3.2 动态映射 ioremap
/* 动态映射 物理地址 到内核地址
 *		phys_addr  起始物理地址
 *		size       映射范围大小
 * 返回值     映射后的虚拟地址	
 */
void *ioremap(phys_addr_t addr, unsigned long size)
3.3 mmap文件映射到内存
3.3.1 什么是mmap

mmap是把文件内容映射到进程的虚拟内存空间, 通过对这段内存的读取和修改,来实现对文件的读取和修改,而不需要再调用read,write等操作。

void* mmap (  void * addr ,   //指定映射的起始地址, 通常设为NULL, 由系统指定 
	          size_t len ,    //映射到内存的文件长度
	          int prot ,      //映射区的保护方式, PROT_EXEC: 映射区可被执行 PROT_READ: 可读  PROT_WRITE: 可写
	          int flags ,     //MAP_SHARED:写入映射区的数据会复制回文件, 且允许其他映射该文件的进程共享。
	                          //MAP_PRIVATE:对映射区的写入操作会产生一个映射区的复制(copy-on-write), 对此区域所做的修改不会写回原文件。
	          int fd ,        //由open返回的文件描述符, 代表要映射的文件
	          off_t offset    //以文件开始处的偏移量, 必须是分页大小的整数倍, 通常为0, 表示从文件头开始映射
	               ) 
3.3.2 mmap优点
  1. 用mmap替代文件操作(read,write)访问设备,效率高. 它是用户空间访问内核空间的一种高效率方式。
       mmap – 映射文件到虚拟内存
       read,write – copy_to_user 拷贝
       对比read write,mmap无需每次都copy_to_user拷贝一次. 它仅需一次映射,以后都直接操作内存buf,效率高。
  2. 用共享内存方式,方便进程间通讯,且效率高。
       采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。
       对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝
       (1.由用户空间的buf中将数据拷贝到内核中。2.内核将数据拷贝到内存中。3.内存到内核。4.内核到用户空间的buf.)
       而共享内存则只拷贝两次数据:一次从输入文件到共享内存区,另一次从共享内存区到输出文件
3.3.3 mmap使用
		#include <stdio.h>
		#include<sys/types.h>
		#include<sys/stat.h>
		#include<fcntl.h>
		#include<unistd.h>
		#include<sys/mman.h>
		
		int main()
		{
		 int fd;
		 char *start;
		 //char buf[100];
		 char *buf;
		 
		 /*打开文件*/
		 fd = open("/dev/memdev0",O_RDWR);     
		 buf = (char *)malloc(100);
		 memset(buf, 0, 100);
		 start=mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
		 
		 /* 读出数据 */
		 strcpy(buf,start);
		 sleep (1);
		 printf("buf 1 = %s\n",buf); 
		 
		
		 /* 写入数据 */
		 strcpy(start,"Buf Is Not Null!");
		 memset(buf, 0, 100);
		 strcpy(buf,start);
		 sleep (1);
		 printf("buf 2 = %s\n",buf);
	
		 munmap(start,100); /*解除映射*/
		 free(buf);
		 close(fd); 
		 return 0; 
		}	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值