本文也即是《Linux Device Drivers》一书第三章Char Drivers的读书笔记之一。
我们在/dev中可以查看设备节点,每个设备有一个主号码(major)
以及一个副号码(minor),通常一个major号码对应某一种设备,虽然linux允许多种设备共享一个major号码。minor号码用于
kernel具体进行设备的对应,kernel并不了解对应在minor后面设备具体的应用。
在一个kenrel
module的程序中,我们需要将我们的程序和某个或某组设备节点对应起来。在这个scull的例子中,使用的是char型的设备节点,他是内存中的某一
个部分(这样无需特别的设备)。这些设备可能已经有固定的主号码,也可能没有而采用系统自动分配的方式。通过下面的例子来学习。
头文件scull.h如下:如果major不为0,则为指定的major号码,如果为0,则采用系统自行动态分配的方式。我们的模块包括4个设备,minor号码从0-3。
#ifndef _WEI_SCULL_H
#define _WEI_SCULL_H
#define SCULL_MAJOR 0
#define SCULL_MINOR_MIN 0
#define SCULL_DEV_NUM 4
#endif
源文件scull.c如下,我们学习三个函数:
int register_chrdev_region(dev_t first,unsigned int count,char *name);
int alloc_chrdev_region(dev_t * dev, unsigned int firstminor, unisgned int count ,char *name);
void unregister_chrdev_region(dev_t first, unsigned int count);
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include "scull.h"
MODULE_LICENSE("Dual BSD/GPL");
dev_t dev;
int is_get_dev = -1;
static int scull_major = SCULL_MAJOR;
static int __init scull_init(void)
{
printk("Scull module init enter\n");
if(scull_major){ /* 根据major和minor号码获得dev */
dev = MKDEV(scull_major,SCULL_MINOR_MIN
);
is_get_dev = register_chrdev_region
(dev, SCULL_DEV_NUM,"scull");//注册
}else{ /* 系统动态分配 */
is_get_dev = alloc_chrdev_region
(&dev,SCULL_MINOR_MIN, SCULL_DEV_NUM,"scull");
scull_major = MAJOR(dev
);
//获取主号码,MINOR()可获取minor号码
}
if(is_get_dev < 0){
printk(KERN_WARNING "scull: can't get device major number %d\n",scull_major);
}
return is_get_dev;
}
/*在模块结束的时候,应该释放注册的资源*/
static void __exit scull_exit(void)
{
if(is_get_dev < 0){
return ;
}else{
unregister_chrdev_region(dev,SCULL_DEV_NUM
);
printk("Scull module exit\n");
}
}
module_init(scull_init);
module_exit(scull_exit);
如果这些设备节点已经存在于系统中,可以在/dev中查看,也可以在/proc/devices中查看major号码和设备名称的对应。我们手动去
mknod我们的设备节点,这种情况,major号码为我们手动配置的主号码,在scull.h的宏定义中去定义,或者我们也可以在加载模块的时候作为参
数带入。如果我们由系统进行动态分配,那么需等待系统分配后,知道主号码,才能创建设备节点。我们可以利用脚本来完成这个工作,下面是加载模块,并自动创
建节点的脚本scull_load
[wei@wei ~]$ cat scull_load
#!/bin/sh
module="scull"
device="scull"
mode="644"
#加载节点,如果加载不成功(可能已经load过),则退出
/sbin/insmod ./$module.ko $* || exit 1
#如果/dev中含有以前创建的节点,删除它们,当然我们也可以判断major号是否和分配的一直,来决定保留或者删除
rm -f /dev/${device}[0-3]
#这是获取major号的过程,awk的使用,可以参考文档:http://www.ibm.com/developerworks/cn/linux/shell/awk/awk-1/
将/proc/devices作为输入,按行输入,如果第二个参数匹配$module,这打印第一个参数,也即赋值给major
major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)
echo major=${major}
#mknod四个设备节点
mknod /dev/${device}0 c $major 0
mknod /dev/${device}1 c $major 1
mknod /dev/${device}2 c $major 2
mknod /dev/${device}3 c $major 3
#一般而言,kernel模块的操作权限都是root,但是有时候我们希望某些用户也可以有读取的权限需要修改设备节点的权限。下面允许组wei的操作,如果组wei不存在,则为组moblin。
group="wei"
grep -q '^wei:' /etc/group|| group="moblin"
chgrp $group /dev/${device}[0-3]
chmod $mode /dev/${device}[0-3]
下面是卸载是的脚本scull_unload,我们需要删除创建的设备节点。
[wei@wei ~]$ cat scull_unload
#!/bin/sh
module="scull"
device="scull"
#如果没有加载该模块结束,否则卸载模块,并删除相关的节点。
/sbin/lsmod | grep $module || exit 1
/sbin/rmmod $module
rm -f /dev/${device}[0-3]
分享到:
相关推荐
简单Kernel Module
1.1. What Is A Kernel Module? 1.2. How Do Modules Get Into The Kernel? 2. Hello World 2.1. Hello, World (part 1): The Simplest Module 2.2. Compiling Kernel Modules 2.3. Hello World (part 2): The ...
Linux Kernel Module及Tcpip程序设计配套光盘
這本電子書是撰寫 Kernel Module 必備的參考書籍. 本文檔提供中文以及英文的文檔供對照.
The Linux Kernel Module Programming Guide CHS Linux内核驱动模块编程指南 (内核版本2.2, 2.4) Peter Jay Salzman Ori Pomerantz 版权 © 2001 Peter Jay Salzman 2003-04-04 ver 2.4.0 -------------------...
Kernel panic - not syncing: Attempted to kill init 解决办法 开源成就技术;技术成就梦想
linux kernel module简单模拟ps指令,简单说明: http://blog.csdn.net/qq123386926
The Linux Kernel Module Programming Guide.pdf 是早期linux参与者对linux编程的殷切指导
動態 Linux kernel 測試工具:SystemTap
如果你在VNware官网下载了VMware-Workstation-Full-15.5.1-15018445.x86_64.bundle ...方法是vmaware-install -l 获取到版本信息后,只取vmware后面的代码(字母) 比如我的是vmware-workstation 15.5.1
kernel panic - not syncing : fatal exception 之后就一直停在那里. 查了一些网站资料,大部分都是双CPU才发生的,有些是关闭:Hyper-Threading (HT)好了,有些关闭USB好了。 但是我试过了关闭HT,或者关闭USB都...
The Linux Kernel Module Programming Guide 2.6 中英文版本 内核编程入门挺好
The_Linux_Kernel_Module_Programming_Guide_2.6中文版 《Linux 内核驱动模块编程指南》最初是由Ori Pomerantz为2.2版本的内核编写的 ,后来,Ori将文档维护的任务交给了Peter Jay Salzman,Peter完成了2.4内核版本...
很好的一个内核模块,欢迎大家下载这些创新创效程序从vdcvcx
公司Ubuntu12.04服务器突然开机起来后就卡住不动,打印kernel offset信息 目前已尝试以下方法,均失败 1:开机启动选择Ubuntu选项时,选择recovery mode启动,仍然卡住,显示kernel offset信息 2:在开机选项...
LINUX KERNEL MODULE PROGRAMMING GUIDE 2009
The Linux Kernel Module Programming Guide 2.6中文版