- Navigation (`・ω・´)
- house主页
- 作品
- 暮光小猿图片管理器2
- av_timerSC 科学创造
- 记录
- videocam没事瞎折腾系列
- devices隔壁老王210
- devicesLinux嵌入式
- 关于
- archive更新日志
- restore历史版本
哔哩哔哩 - ( ゜- ゜)つロ 乾杯~
实验环境
- 硬件: PC
- 内核版本: 5.3.0
- 操作系统: Parrot 4.8
相关资料
什么是杂项设备
杂项设备是在嵌入式系统中用得比较多的一种设备驱动。
其实是因为这些字符设备不符合预先确定的字符设备范畴,
所以这些设备采用主编号10,
一起归于misc device。
misc设备其实也是特殊的字符设备。
(摘自百度知道LINUX misc设备是什么)
设备读写实现
特殊的字符设备,字符设备就需要实现它的读写方法。
读写部分和第三篇基本一样。
// 64字节缓冲区
static char readbuf[64];
// 设备的读取
static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
{
// 计算长度
size_t len = strlen(readbuf);
// 如果不是空的
if (len > 0)
{
// 复制数据到用户空间
if (copy_to_user(buf, readbuf, len))
{
return -EFAULT;
}
// 清空缓冲区
memset(readbuf, 0, 64);
// 返回读取到的长度
return len;
}
// 没有读到任何数据
return 0;
}
// 设备的写入
static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
{
// 确认长度不会超过最大
if (count > 63)
count = 63;
// 从用户空间复制到内核空间
if (copy_from_user(readbuf, buf, count))
{
return -EFAULT;
}
// 返回写入的长度
return count;
}
定义一个杂项设备
设备就是一个结构体,里边写上它的属性。
// 定义写入读取方法
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.read = &dev_read,
.write = &dev_write,
};
// 定义一个设备
static struct miscdevice dev = {
// 动态分配子设备号
.minor = MISC_DYNAMIC_MINOR,
// 设备名字 会显示到/sys/class/misc/misctest 和/dev/misctest
.name = "misctest",
// 读写方法
.fops = &dev_fops,
};
程序入口
因为这次的测试环境的内核版本是5.3.0,
不知道是从哪个版本开始,内核/用户空间数据复制的名字有变化,
这里加一个定义。
然后就是在入口注册这个杂项设备,
出口注销这个杂项设备。
最终的程序在Git仓库,这就不再放了。
// 不知道哪个内核版本 把这两个改名了
#define copy_to_user raw_copy_to_user
#define copy_from_user raw_copy_from_user
// 模块入口 注册设备
static __init int Module_Init(void)
{
return misc_register(&dev);
}
// 模块出口 取消注册设备
static __exit void Module_Exit(void)
{
misc_deregister(&dev);
}
module_init(Module_Init);
module_exit(Module_Exit);
MODULE_LICENSE("GPL");
程序测试
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $make
make -C /usr/src/linux-headers-5.3.0-1parrot1-amd64 M=/home/kuresaru/armlinux/misctest modules
make[1]: Entering directory '/usr/src/linux-headers-5.3.0-1parrot1-amd64'
CC [M] /home/kuresaru/armlinux/misctest/main.o
LD [M] /home/kuresaru/armlinux/misctest/misctest.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/kuresaru/armlinux/misctest/misctest.mod.o
LD [M] /home/kuresaru/armlinux/misctest/misctest.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.3.0-1parrot1-amd64'
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $sudo make load
[sudo] kuresaru 的密码:
insmod misctest.ko
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $ls -l /sys/class/misc/misctest
lrwxrwxrwx 1 root root 0 11月 22 08:15 /sys/class/misc/misctest -> ../../devices/virtual/misc/misctest
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $ls -l /dev/misctest
crw------- 1 root root 10, 54 11月 22 08:14 /dev/misctest
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $sudo chmod 666 /dev/misctest
[sudo] kuresaru 的密码:
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $cat /dev/misctest
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $echo "Hello World~" > /dev/misctest
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $cat /dev/misctest
Hello World~
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $cat /dev/misctest
┌─[kuresaru@parrot]─[~/armlinux/misctest]
└──╼ $sudo make unload
rmmod misctest