驱动学习1
KERNELRELEASE = $(shell cat include/config/kernel.release 2>
:= memdev.o。这样就实现了内核的编译。
具体的应用程序代码我都是按着别人的代码修改调试的。
下面是我的源码:
第一个代码是头文件:
#ifndef _MEMDEV_H_H_
#define _MEMDEV_H_H_
#ifndef MEMDEV_MAJOR
#define MEMDEV_MAJOR 555
#endif
#ifndef MEMDEV_NR_DEVS
#define MEMDEV_NR_DEVS 2
#endif
#ifndef MEMDEV_SIZE
#define MEMDEV_SIZE 2048
#endif
struct mem_dev
{
char *data;
unsigned long size;
};
#endif
第二个是C文件:
#include
#include
#include
//#include
#include
#include
#include
/*该头文件主要实现内存的控制,包括kmalloc等函数*/
#include
#include
#include
#include
/*错误的不同,需要具体的类型*/
#include
/*自己定义的头文件*/
#include"memdev.h"
static mem_major = MEMDEV_MAJOR;
module_param(mem_major,int,S_IRUGO);
module_param(mem_major,int,S_IRUGO);
struct mem_dev *mem_devp;
struct cdev cdev;
/*函数的声明*/
static int memdev_init(void);
static void memdev_exit(void);
int mem_open(struct inode *inode,struct file *filp);
int mem_release(struct inode *inode, struct file *flip);
static ssize_t mem_read(struct file *flip,char __user *buf, size_t size,loff_t *ppos);
static ssize_t mem_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos);
static loff_t mem_llseek(struct file *filp,loff_t offset, int whence);
/*添加该模块的基本文件操作支持*/
static const struct file_operations mem_fops =
{
.owner = THIS_MODULE,
.llseek = mem_llseek,
.read = mem_read,
.write = mem_write,
.open = mem_open,
.release = mem_release,
};
/*初始化函数*/
static int memdev_init(void)
{
int result;
int i;
/*创建一个设备号*/
dev_t devno = MKDEV(mem_major,0);
/*注册一个设备号*/
/*如果定义了主设备号采用静态申请的方式*/
if(mem_major)
result = register_chrdev_region(devno,2,"mem_dev");
else/*动态申请设备号*/
{
result = alloc_chrdev_region(&devno,0,2,"mem_dev");
mem_major = MAJOR(result);
}
/*错误处理*/
if(result < 0)
return result;
/*创建一个设备*/
/*初始化cdev,并将相关的文件操作添加进来*/
cdev_init(&cdev,&mem_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &mem_fops;
/*注册字符设备*/
cdev_add(&cdev,MKDEV(mem_major,0),MEMDEV_NR_DEVS);
/*分配两个内存空间,此处是在物理内存上实现分配,实质是创建两个设备*/
mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev),GFP_KERNEL);
if(!mem_devp)/*出错的相应操作*/
{
result = -ENOMEM;
/*错误处理,采用典型的goto语句*/
goto fail_malloc;
}
/*清除空间*/
memset(mem_devp,0,sizeof(struct mem_dev));
for(i = 0; i < MEMDEV_NR_DEVS; ++i)
{
mem_devp[i].size = MEMDEV_SIZE;
mem_devp[i].data = kmalloc(MEMDEV_SIZE,GFP_KERNEL);
/*问题,没有进行错误的控制*/
memset(mem_devp[i].data,0,MEMDEV_SIZE);
}
return 0;
fail_malloc:
unregister_chrdev_region(devno,1);
return result;
}
/*模块清除函数*/
static void memdev_exit(void)
{
cdev_del(&cdev);/*注销字符设备*/
/*释放两个物理内存*/
kfree(mem_devp[0].data);
kfree(mem_devp[1].data);
kfree(mem_devp);/*释放设备结构体内存*/
unregister_chrdev_region(MKDEV(mem_major,0),2);
}
/*定义相关的操作函数*/
/*mem_open*/
int mem_open(struct inode *inode,struct file *filp)
{
struct mem_dev *dev;
/*判断设备文件的次设备号*/
int num = MINOR(inode->i_rdev);
if(num >= MEMDEV_NR_DEVS)
return -ENODEV;
dev = &mem_devp[num];
/*将数据指向两个内存空间*/
filp->private_data = dev;
return 0;
}
/*release函数的
驱动学 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)