Linux学习笔记——linux内核字符设备驱动 - Go语言中文社区

Linux学习笔记——linux内核字符设备驱动


尝试在树莓派安装的raspbian系统上进行linux字符设备驱动

1.更新安装kernel header源码

sudo apt-get update
sudo apt-get install raspberrypi-kernel-headers

可以使用uname -r查看当前版本

2.编写模块源码mydev1.c

#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/moduleparam.h>
#include<linux/cdev.h>
#include<linux/fs.h>
#include<linux/wait.h>
#include<linux/poll.h>
#include<linux/sched.h>
#include<linux/slab.h>

#define BUFFER_MAX (10)
#define OK 	   (0)
#define ERROR	   (-1)

struct cdev *gDev;
struct file_operations *gFile;
dev_t devNum;

unsigned int subDevNum=1;
int reg_major=232;
int reg_minor=0;
char *buffer;
int flag=0;
int testOpen(struct inode *p,struct file *f)
{
	printk(KERN_EMERG"testOpen OKrn");
	return 0;
}

int testWrite(struct file *f,const char __user *u,size_t s,loff_t *l)
{
	printk(KERN_EMERG"testWrite OKrn");
	return 0;
}

int testRead(struct file *f,char __user *u,size_t s,loff_t *l)
{
	printk(KERN_EMERG"testRead OKrn");
	return 0;
}

int charDrvInit(void)
{
	devNum=MKDEV(reg_major,reg_minor);

	if(OK == register_chrdev_region(devNum,subDevNum,"testchar1"))
        {
	  printk(KERN_EMERG"register_chrdev_region OKrn");
	}
	else
	{
	  printk(KERN_EMERG"register_chrdev_region errorrn");
	  return ERROR;
	}
	printk(KERN_EMERG"devNum is %drn",devNum);
	gDev = kzalloc(sizeof(struct cdev),GFP_KERNEL);
	gFile = kzalloc(sizeof(struct file_operations),GFP_KERNEL);

	gFile->open=testOpen;    //当测试程序调用open函数时会进入testOpen
	gFile->read=testRead;	//当测试程序调用read函数时会进入testRead
	gFile->write=testWrite;	//当测试程序调用write函数时会进入testWrite
	gFile->owner=THIS_MODULE;
	cdev_init(gDev,gFile);
	cdev_add(gDev,devNum,3);
	return 0;
}

void __exit charDrvExit(void)
{
  cdev_del(gDev);
  unregister_chrdev_region(devNum,subDevNum);
  return;
}

module_init(charDrvInit);//insmod **.ko
module_exit(charDrvExit);//rmmod **.ko
MODULE_LICENSE("GPL");

创建编写Makefile文件
sudo vim Makefile

obj-m :=mydev1.o
HEAD :=$(shell uname -r)
KERNEL := /usr/src/linux-headers-$(HEAD)/
all:
	make -C $(KERNEL) M=$(shell pwd) modules
clean:
	make -C $(KERNEL) M=$(shell pwd) clean
install:
	ismod mydev1.ko
unistall:
	rmmod mydev1

esc :wq 保存后退出vim

编译内核模块

make

成功后可看到如下文件
在这里插入图片描述
清空一下dmesg消息

sudo dmesg -C

加载模块

sudo insmod mydev1.ko   

可以看到
在这里插入图片描述
查看内核缓存信息

dmesg

可以看到
在这里插入图片描述

3.编写测试程序源码testchar1.c

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>

#define DATA_NUM (10)
int main(int argc,char *argv[])
{
	int fd,i;
	int WD,RD;
	fd_set fdset;
	char buf[DATA_NUM]="111";
	memset(buf,0,DATA_NUM);  //清空数组buf
	fd=open("/dev/testchar1",O_RDWR);
	   printf("%drn",fd);
	if(-1==fd)
	{
	  perror("open file errorrn");
	}
	else
	{
	  printf("open successern");
	}

	WD=write(fd,buf,DATA_NUM);
	RD=read(fd,buf,DATA_NUM);
	printf("%d %drn",WD,RD);
	printf("%srn",buf);
	return 0;

}

编译代码

   sudo gcc -o testchar1 testchar1.c

程序中fd=open("/dev/testchar1",O_RDWR); 所以还需建立/dev/testchar1 目录项及索引节点

# c表示为字符设备(b表示块设备) 232为主设备号 0为次设备号  
sudo mknod /dev/testchar1 c 232 0

执行测试程序

sudo ./testchar1

在这里插入图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/luotuoxiansheng/article/details/82858841
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢