襄阳公司网站建设,财务软件单机版,太原seo自媒体,网站与客户端的区别吗globalmem看 linux 设备驱动开发详解时#xff0c;字符设备驱动一章#xff0c;写的测试代码和应用程序#xff0c;加上自己的操作#xff0c;对初学者我觉得非常有帮助。写这篇文章的原因是因为我看了我之前发表的文章#xff0c;还没有写过字符设备相关的#xff0c;至… globalmem看 linux 设备驱动开发详解时字符设备驱动一章写的测试代码和应用程序加上自己的操作对初学者我觉得非常有帮助。写这篇文章的原因是因为我看了我之前发表的文章还没有写过字符设备相关的至于里面提到的结构体的作用有很多详细的文章说明我就不做更深的叙述。代码在github上点击下面阅读原文可以直达https://github.com/weiqifa0/globalmem/blob/main/README.md把这部分放在github上也有好处后续可以增加删除一些东西以后自己需要使用的时候也方便许多。我们讨论字符设备驱动就有必要知道他的结构体和头文件像一些后来的封装什么的大部分还是脱离不了操作这个结构体里面的东西。/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_CDEV_H
#define _LINUX_CDEV_H#include linux/kobject.h
#include linux/kdev_t.h
#include linux/list.h
#include linux/device.hstruct file_operations;
struct inode;
struct module;struct cdev {struct kobject kobj; /*内嵌kobject结构体方便以后应用也会在sys下生成相关设备文件*/struct module *owner;/*所属于的模块正常就是本模块THIS_MODULE*/const struct file_operations *ops;/*文件的操作结构体设备也是一个文件*/struct list_head list;/*字符设备的链表头*/dev_t dev;/*设备号*/unsigned int count;
} __randomize_layout;
/*初始化cdev并建立和file_operation的联系*/
void cdev_init(struct cdev *, const struct file_operations *);
/*申请cdev内存*/
struct cdev *cdev_alloc(void);void cdev_put(struct cdev *p);int cdev_add(struct cdev *, dev_t, unsigned);void cdev_set_parent(struct cdev *p, struct kobject *kobj);
int cdev_device_add(struct cdev *cdev, struct device *dev);
void cdev_device_del(struct cdev *cdev, struct device *dev);void cdev_del(struct cdev *);void cd_forget(struct inode *);#endif加载内核模块insmod globalmem.ko 错误需要的修改。insmod: cant insert globalmem.ko: Device or resource busy出错的原因模块使用的是静态分配设备号的方式而这个设备号已经被系统中的其他设备所占用。查看未被占用的设备号需要到pro/devices下面去查看。查看设备号的方法# cat /proc/devices编译内核版本#uname -a
Linux bsp-ubuntu1804 4.15.0-117-generic #118-Ubuntu SMP Fri Sep 4 20:02:41 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux加载模块之后使用lsmod查看模块weiqifabsp-ubuntu1804:~/c/globalmem$ sudo insmod globalmem.koweiqifabsp-ubuntu1804:~/c/globalmem$ lsmod |grep global
globalmem 16384 0
weiqifabsp-ubuntu1804:~/c/globalmem$weiqifabsp-ubuntu1804:~/c/globalmem$ cat /proc/devices |grep global
230 globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$
创建设备文件节点使用mknod创建设备节点的时候后面跟上的参数需要跟我们在/proc/devices下面看到的对应也就是我们在驱动里面申请的主设备号。weiqifabsp-ubuntu1804:~/c/globalmem$ sudo mknod /dev/globalmem c 230 0
weiqifabsp-ubuntu1804:~/c/globalmem$ ls /dev/globalmem -al
crw-r--r-- 1 root root 230, 0 Dec 22 16:19 /dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$
使用命令读写设备文件Linux 下的 echo 和cat 命令是十分有用这两个命令可以让在不写代码的情况下就可以完成调试读写设备。weiqifabsp-ubuntu1804:~/c/globalmem$ sudo chmod 777 /dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$ sudo echo linux /dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$ cat /dev/globalmem
linux
cat: /dev/globalmem: No such device or address
weiqifabsp-ubuntu1804:~/c/globalmem$ cat /dev/globalmem
linux
cat: /dev/globalmem: No such device or address
weiqifabsp-ubuntu1804:~/c/globalmem$ sudo echo linuxgdb /dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$ cat /dev/globalmem
linuxgdb
cat: /dev/globalmem: No such device or address
weiqifabsp-ubuntu1804:~/c/globalmem$
通过代码来读写设备文件代码在下面阅读原文的链接里面。weiqifabsp-ubuntu1804:~/c/globalmem$ gcc app-main.c ./a.out
str:LINUX,GDB
weiqifabsp-ubuntu1804:~/c/globalmem$
使用传入参数设置主设备号内核模块参数我觉得是一个比较冷门的知识点冷门的原因是因为我们在做项目的时候很少使用这个参数但是实际上这个参数非常有用。我们可以把内核模块当做main函数main函数是可以接收传参的内核模块也可以在加载的时候接收传入的参数。如下是把主设备号传给内核模块但是需要注意这个主设备号不能被占用了。
weiqifabsp-ubuntu1804:~/c/globalmem$ sudo insmod globalmem.ko globalmem_major231
weiqifabsp-ubuntu1804:~/c/globalmem$ cat /proc/devices |grep globalmem
231 globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$增加自动创建设备节点的驱动文件每次手动创建设备文件节点总是很麻烦而且在实际编写设备驱动的时候不会出现自己手动创建设备节点这种低端的操作。当然了聪明的内核提供了接口让我们在注册驱动的时候也把设备文件节点注册上去。具体代码可以查看globalmem2.c里面的代码。weiqifabsp-ubuntu1804:~/c/globalmem$ chmod 777 globalmem.ko
weiqifabsp-ubuntu1804:~/c/globalmem$ sudo insmod globalmem.ko
[sudo] password for weiqifa:
weiqifabsp-ubuntu1804:~/c/globalmem$ ls /dev/globalmem
/dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$ ls /dev/globalmem -al
crw------- 1 root root 238, 0 Dec 22 17:18 /dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$/*修改权限后才可以正常进行独写操作*/
weiqifabsp-ubuntu1804:~/c/globalmem$ sudo chmod 777 /dev/globalmem
weiqifabsp-ubuntu1804:~/c/globalmem$ gcc app-main.c ./a.out
write data ok!
str:LINUX,GDB
weiqifabsp-ubuntu1804:~/c/globalmem$使用lseek操作文件位置具体对应的文件是app-main2.cweiqifabsp-ubuntu1804:~/c/globalmem$ gcc app-main2.c ./a.out
file ret:0
write data ok! fd:3
str:123456789ABCDEF10111213141516171819201617181920
lseek:1
str:23456789ABCDEF10111213141516171819201617181920
weiqifabsp-ubuntu1804:~/c/globalmem$推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈