Memory驱动分析

原创 2013年12月03日 15:54:28

课堂实践3

简单Memory驱动程序

//memory.c 文件
/* Necessary includes for device drivers */

#include <linux/init.h>
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/cdev.h>  //linux2.6设备驱动的头文件,包含cdev_alloc、cdev_init、cdev_add和cdev_del函数的定义
#include <linux/device.h>  //class_create(),class_destroy(),class_device_create(),class_device_destroy()函数定义在device.h头文件中
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */

MODULE_LICENSE("Dual BSD/GPL");

/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);

/* Structure that declares the usual file */
/* access functions */
struct file_operations memory_fops = {
	.owner = THIS_MODULE,
	.read = memory_read,
	.write = memory_write,
	.open = memory_open,
	.release = memory_release
};

/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);

/* Global variables of the driver */
/* Major number */
//int memory_major = 360;

/* 设备号 */
dev_t dev_num;
static struct cdev *pcdev;
struct class *myclass=NULL;
/* Buffer to store data */
char *memory_buffer;

/* ------------------<memory init module>开始--------------------- */
//该段代码使用了kmalloc函数。这个函数工作在内核空间,用于为该驱动程序的缓冲区分配内存。
//它和我们熟悉的malloc函数很相似。最后,如果注册主设备号或者分配内存失败,模块将退出。
int memory_init(void) 
{
	int result = -1;
	/* Registering device */
	//result = register_chrdev(memory_major, "memory", &memory_fops);
	 //动态申请一个 字符设备内存。
	pcdev = cdev_alloc();
        //字符设备初始化
	cdev_init(pcdev, &memory_fops);
	//动态注册一个字符设备
	result = alloc_chrdev_region(&dev_num, 0, 1, "my_memory");  //次设备号从0开始,注册1个设备,设备名为my_memory。	
	printk("<0>major = %d, minor = %d\n", MAJOR(dev_num), MINOR(dev_num));
	pcdev->owner = THIS_MODULE;

        //向系统中 添加一个字符设备
	cdev_add(pcdev, dev_num, 1);

	//创建设备文件
	myclass=class_create(THIS_MODULE, "test");
	//利用udev创建设备文件创建设备文件,linux2.26及以后的版本,可能用device_create()
	//class_device_create(myclass,NULL,dev_num,NULL,"my_memory"); //error: implicit declaration of function 'class_device_create'
	device_create(myclass, NULL, dev_num, NULL,"my_memory");
	
	printk("<0>test_init ok,device create ok\n");
	
	/* Allocating memory for the buffer */
	memory_buffer = kmalloc(1, GFP_KERNEL);
	if (!memory_buffer) {
		result = -ENOMEM;
		goto fail;
	}
	memset(memory_buffer, 0, 1);
	printk("<0>Inserting memory module\n");
	return 0;
	fail:
		memory_exit();
		return result;
}
/* ------------------<memory init module>结束--------------------- */


/* ------------------<memory exit module>开始--------------------- */
//为了完全的卸载该驱动,缓冲区也需要通过该函数进行释放。
void memory_exit(void) 
{
	/* Freeing the major number */
	//unregister_chrdev(memory_major, "memory");
 	// 从系统中删除字符设备
        cdev_del(pcdev);
        //注销字符设备
        unregister_chrdev_region(dev_num, 1);
        
	//删除/dev目录下相应的设备文件,linux2.26及以后的版本,可能用device_destroy()
	//class_device_destroy(myclass,dev_num);	//error: implicit declaration of function 'class_device_destroy'
	//device_destroy(myclass);			//error: too few arguments to function 'device_destroy'
	device_destroy(myclass, dev_num);
	
	/* Freeing buffer memory */
	if (memory_buffer) {
		kfree(memory_buffer);
	}
	printk("<0>Removing memory module\n");
}
/* ------------------<memory exit module>结束--------------------- */

/* ------------------<memory open>开始--------------------- */
//当设备文件被打开后,通常就需要初始化驱动的各个变量,对设备进行复位。但在本例中,这些操作都没进行。
int memory_open(struct inode *inode, struct file *filp)
{
	/* Success */
	return 0;
}
/* ------------------<memory open>结束--------------------- */


/* ------------------<memory release>开始--------------------- */
//当设备文件关闭后,通常需要释放该设备使用的内存,释放各种操作该设备相关的变量。但是,为简单起见,例子里没有进行这些操作。
int memory_release(struct inode *inode, struct file *filp) 
{
	/* Success */
	return 0;
}
/* ------------------<memory release>结束--------------------- */


/* ------------------<memory read>开始--------------------- */
//本例中,memory_read函数通过copy_to_user函数从驱动的缓冲区(memory_buffer)向用户空间传送一个简单的字节。
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
	unsigned long ret;	
	/* Transfering data to user space */
	ret = copy_to_user(buf,memory_buffer,1);
	/* Changing reading position as best suits */
	if (*f_pos == 0) {
		*f_pos+=1;
		return 1;
	} 
	else {
		return 0;
	}
}
/* ------------------<memory read>结束--------------------- */


/* ------------------<memory write>开始--------------------- */
//本例中的memory_write函数,它有如下几个参数:
//一个file结构;
//buf,一个缓冲区,用户空间函数fwrite将向该该缓冲区写数据;
//count,统计将传送的字节数的计数器,和用户空间函数fwrite的计数器有相同的数值;
//最后是f_pos,指示从哪里开始写文件。。
ssize_t memory_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
	//char *tmp;
	unsigned long ret;
	//tmp=buf+count-1;
	ret = copy_from_user(memory_buffer,buf+count-1, 1);
	return 1;
}
/* ------------------<memory write>结束--------------------- */

编译的的时候,开发板可以正常加载,虚拟机里面red hat 5.5下面编译没问题,但是加载模块,虚拟机会卡死,暂时没解决,可能是 main函数 动态创建设备的问题,先不搞了, 留着。

记一次通过Memory Analyzer分析内存泄漏的解决过程

状况描述: 最近项目新打的版本,过不了多长时间,项目就会挂掉。状况就是处于一种假死的状态。索引查询都很慢,几乎进行不了任何操作,慢慢卡死。 然后我们再发版时,只能基于之前打好的war包,替换或者增加c...
  • liu765023051
  • liu765023051
  • 2017年07月14日 18:36
  • 3280

iOS小结(五) 结合 Instrument 分析并解决memory issues

memory通常遇到两种问题:  memory 持续上涨 memory leak          memory leak我遇到过一个问题是因为几个小的变量因为new的没有delete。    ...
  • u010696366
  • u010696366
  • 2015年09月09日 20:38
  • 2149

使用Memory Analyzer tool(MAT)分析内存泄漏(二)

前言 在使用Memory Analyzer tool(MAT)分析内存泄漏(一)中,我介绍了内存泄漏的前因后果。在本文中,将介绍MAT如何根据heap dump分析泄漏根源。由于测试范例可能过于简...
  • u012264122
  • u012264122
  • 2016年07月27日 15:47
  • 785

26. OP-TEE驱动篇----libteec和tee_supplicant调用驱动流程和重要结构体

驱动挂载完成之后,CA程序通过调用libteec中的接口调用到OP-TEE驱动来穿透到secure world中调用对应的TA程序。OP-TEE的驱动挂载后会在/dev目录下分别创建两个设备接待,分别...
  • shuaifengyun
  • shuaifengyun
  • 2017年06月09日 18:27
  • 721

MemoryAnalyzer-内存泄露分析工具

概述 对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。JVM 能够记...
  • shenhaiwen
  • shenhaiwen
  • 2017年01月22日 18:42
  • 8820

性能优化之内存泄露(Memory Leak)常用分析工具(另3种)

1 Lint分析工具(效果非常好)(1)概述 lint是随Android SDK自带的一个静态代码分析工具。它用来对Android工程的源文件进行检查,找出在正确性、安全、性能、可使用性、可访问性及...
  • chenliguan
  • chenliguan
  • 2016年11月14日 21:45
  • 914

使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)

做过应用诊断与优化的朋友都知道内存泄漏和带来的危害,对这种情况的分析和定位一般会比较困难,尤其在 .NET/Java 应用中,隐式的堆内存管理以及托管对象间纷繁复杂的引用关系,使分析和定位问题更加复杂...
  • formiss
  • formiss
  • 2013年01月16日 10:51
  • 2389

使用Eclipse Memory Analyzer进行内存泄漏分析三部曲

一、准备工作  分析较大的dump文件(根据我自己的经验2G以上的dump文件就需要使用以下介绍的方法,不然mat会出现oom)需要调整虚拟机参数  找个64位的系统在MemoryAnalyzer.i...
  • z69183787
  • z69183787
  • 2015年09月22日 14:16
  • 1347

Memory驱动——测试程序

课堂实践4: •参照“实践3”的测试程序,编写memory-26.c的测试程序test-memory-26.c ,不必使用多线程。测试包括写入数据和读取数据,正如《Linux设备驱动开发入门(中文...
  • hailmy
  • hailmy
  • 2013年12月03日 16:03
  • 499

利用内存分析工具(Memory Analyzer Tool,MAT)分析java项目内存泄露

一、开发环境: 操作系统:ubuntu 14.04 IDE:Eclipse Java EE IDE for Web Developers. Version: Luna Service Releas...
  • wanghuiqi2008
  • wanghuiqi2008
  • 2016年02月23日 20:46
  • 15446
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Memory驱动分析
举报原因:
原因补充:

(最多只允许输入30个字)