关于asp_sql网站开发的书籍,西地那非片的正确服用方法,页面访问界面紧急升级通知,东莞做网站it sUbuntu18.04添加内核模块#xff08;字符设备#xff09;
虚拟机Ubuntu18.04#xff08;内核版本linux-5.4.0-135-generic#xff09;
参考
嵌入式Linux驱动开发#xff08;一#xff09;——字符设备驱动框架入门
1 编译内核模块
创建字符设备代码文件char_dev.c字符设备
虚拟机Ubuntu18.04内核版本linux-5.4.0-135-generic
参考
嵌入式Linux驱动开发一——字符设备驱动框架入门
1 编译内核模块
创建字符设备代码文件char_dev.c
#include linux/init.h //定义了module_init
#include linux/module.h //最基本的头文件其中定义了MODULE_LICENSE这一类宏
#include linux/fs.h // file_operations结构体定义在该头文件中
#include linux/device.h //class、class_device结构体的定义位置static const char* devive_name first_driver; // 定义设备名
static struct class *first_class; //定义class结构体
static struct device *first_dev; //定义device结构体//定义了open函数
static int first_drv_open (struct inode *inode, struct file *file)
{printk(open\n);return 0;
}//定义了write函数
static ssize_t first_drv_write (struct file *file, const char __user *buf, size_t size, loff_t * ppos)
{printk(write\n);return 0;
}//在file_operations中注册open和write函数
static struct file_operations first_drv_fo
{.owner THIS_MODULE,//将对应的函数关联在file_operations的结构体中.open first_drv_open, .write first_drv_write,
};static int dev_id 0; //初始化的设备号0
//init驱动的入口函数
static int __init first_drv_init(void)
{ //注册设备实际是将file_operations结构体放到内核的制定数组中以便管理//在register_chrdev中制定dev_id作为主设备号若dev_id为0则自动分配一个主设备号dev_id register_chrdev(dev_id, devive_name , first_drv_fo);first_class class_create(THIS_MODULE, first_drv); //初始化class结构体指定设备文件名first_dev device_create(first_class, NULL, MKDEV(dev_id, 0), NULL, first_drv);// 根据class来初始化device会创建出对应的设备文件 /dev/first_drvprintk(init\n);return 0;
}//驱动的出口函数
static void __exit first_drv_exit(void)
{printk(exit\n);unregister_chrdev(dev_id, devive_name); //卸载设备实际是将file_operations结构体从内核维护的相关数组中以主设备号作为索引删除device_unregister(first_dev); // 后创建的先卸载class_destroy(first_class);
}//内核将通过这个宏来直到这个驱动的入口和出口函数
module_init(first_drv_init);
module_exit(first_drv_exit);MODULE_AUTHOR(Ethan Lee 4128127qq.com);
MODULE_LICENSE(GPL); //指定协议同目录下创建Makefile文件
obj-m char_dev.o
KERN_DIR/usr/src/linux-headers-5.4.0-135-genericall:make -C ${KERN_DIR} M${shell pwd} modulesclean:rm -f *.ko *.o *.mod.o *.mod.c *.sysvers编译
make2 加载内核模块
sudo insmod char_dev.ko查看是否添加成功
cat /proc/devices结果如下
Character devices:...189 usb_device204 ttyMAX226 drm240 first_driver #这里是我们添加的模块241 aux242 hidraw
...Block devices:7 loop8 sd9 md11 sr65 sd66 sd
...创建一个测试程序char_dev_test.c
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include stdio.hint main(int argc, char **argv)
{int fd; //声明设备描述符int val 1; //随便定义变量传入到fd open(/dev/first_drv, O_RDWR); //根据设备描述符打开设备if(fd 0) //打开失败printf(cant open\n); write(fd, val, 4); //根据文件描述符调用writereturn 0;
}编译并运行测试程序
gcc char_dev_test.c -o char_dev_testsudo ./char_dev_test查看结果
$ dmesg | tail -10
[ 1746.094412] CPU3 has been hot-added
[ 1746.094945] CPU4 has been hot-added
[ 1746.097525] CPU5 has been hot-added
[ 1746.098038] CPU6 has been hot-added
[ 1746.098708] CPU7 has been hot-added
[ 2861.264107] char_dev: loading out-of-tree module taints kernel.
[ 2861.264142] char_dev: module verification failed: signature and/or required key missing - tainting kernel
[ 2861.264398] init
[ 3070.234439] open
[ 3070.234441] write3.卸载内核模块
sudo rmmod char_dev查看结果
$ dmesg | tail -1
[ 4282.264114] exit