udev和mdev学习总结.docx
- 文档编号:25178650
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:11
- 大小:20.99KB
udev和mdev学习总结.docx
《udev和mdev学习总结.docx》由会员分享,可在线阅读,更多相关《udev和mdev学习总结.docx(11页珍藏版)》请在冰豆网上搜索。
udev和mdev学习总结
udev和mdev学习总结
篇一:
linux环境编程
福建农林大学金山学院
课程名称:
姓名:
系:
专业:
年级:
学号:
指导教师:
职称:
实验报告
Linux环境编程
信息与机电工程计算机科学与技术
XX级
讲师
XX年5月26日
实验项目列表
福建农林大学金山学院实验报告
系:
信息与机电工程系专业:
计算机科学与技术年级:
XX姓名:
学号:
实验室号__607_____计算机号实验时间:
指导教师签字:
成绩:
实验一:
gcc编译器(验证性、2学时)
一、实验目的:
1)熟悉Shell操作环境。
2)掌握在Linux下的C语言代码编译运行的方法。
3)初步了解C语言库函数与Linux系统调用。
二、实验内容
1、编写能输出“Helloworld!
”问候语的C程序,并在终端中编译、执行。
要求记录所使用的命令及结果。
#include#includeintmain(){
printf("HelloWorld\n");exit(0);}
2、编写程序p.c,其功能是从键盘输入两个实数,输出这两个实数的平方和,生成可执行文件为pow。
#include"stdio.h"main(){
floatx,y;
scanf("%f%f",&x,&y);printf("%6.3f",x*x+y*y);}
3、教材第9页静态库实验,记录操作步骤与结果。
分析所出现的问题及如何解决的?
4、编写一个C程序并设置其在后台执行,其功能是在一段时间后(可自行设置),在屏幕上显示信息:
Timeforplay!
,写出相应的程序、命令及结果。
#includemain(){
sleep(6);
printf("TimeforPlay!
\n");
}
5、编制一段程序,使用系统调用fork()创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。
让每一个进程在屏幕上显示一个字符:
父进程显示字符a,子进程分别显示字符b和字符c。
试观察、记录并分析屏幕上,进程调度的情况。
#include#include#include#includemain()
{
if(fork()==0)//子进程1{
printf("b\n");exit(0);}else
{
if(fork()==0)//子进程2{
printf("c\n");exit(0);
}
printf("a\n");//父进程exit(0);}
}
三、实验结果与讨论(根据实验结果回答下列问题)
1、你所使用的实验环境是什么?
请写出Linux的平台、内核版本号。
VMwareWorkstation
2、在Linux中,标准设备文件有哪些?
这些设备文件在哪个目录?
Devfsudevmdev
3、对于上述各编程题目中所用到了的各个头文件,请找到它们的位置。
/user/include四、总结
篇二:
设备文件系统剖析与使用
设备文件系统剖析与使用设备文件系统剖析与使用
嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。
一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。
如有错误之处,谢请指正。
?
共享资源,欢迎转载:
一、什么是Linux设备文件系统
首先我们不看定义,定义总是太抽象很难理解,我们先看现象。
当我们往开发板上移植了一个新的文件系统之后(假如各种设备驱动也移植好了),启动开发板,我们用串口工具进入开发板,查看系统/dev目录,往往里面没有或者就只有null、console等几个系统必须的设备文件在这儿外,没有任何设备文件了。
那我们移植好的各种设备驱动的设备文件怎么没有啊?
如果要使用这些设备,那不是要一个一个的去手动的创建这些设备的设备文件节点,这给我们使用设备带来了极为的不便(在之前篇幅中讲的各种设备驱动的移植都是这样)。
设备文件系统就是给我们解决这一问题的关键,他能够在系统设备初始化时动态的在/dev目录下创建好各种设备的设备文件节点(也就是说,系统启动后/dev目录下就有了各种设备的设备文件,直接就可使用了)。
除此之外,他还可以在设备卸载后自动的删除/dev下对应的设备文件节点(这对于一些热插拔设备很有用,插上的时候自动创建,拔掉的时候又自动删除)。
还有一个好处就是,在我们编写设备驱动的时候,不必再去为设备指定主设备号,在设备注册时用0来动态的获取可用的主设备号,然后在驱动中来实现创建和销毁设备文件(一般在驱动模块加载和卸载函数中来实现)。
二、设备文件系统的种类
设备文件系统有:
devfs、udev、mdev等。
mdev是udev的简化版本,是busybox中所带的程序,最适合用在嵌入式系统,而udev一般都用在PC上的Linux中,相对mdev来说要复杂些;devfs是2.4内核引入的,而在2.6内核中却被udev所替代,他们有着共同的优点,只是devfs中存在着一些未修复的bug,作者也停止了对他的维护,最显著的一个区别是:
采用devfs时,当一个并不存在的设备节点被打开时,他却还能自动加载对应的驱动,而udev则不能,udev认为当打开并不存在的设备节点时不应该加载对应的驱动模块,因为加载了也没用,浪费系统资源。
三、udev或者mdev设备文件系统的使用
1.首先让大家明白一个问题就是,不管是udev还是mdev,他们就是一个应用程序,就跟其他应用程序一样(比如:
Boa服务),配置了就可以使用了。
为了方便起见,我们就使用busybox自带的一个mdev,这样在配置编译busybox时,只要将mdev的支持选项选上,编译后就包含了mdev设备文件系统的应用(当然你也可以不使用busybox自带的,去下载udev的源码进行编译移植)
#cdbusybox-
#makemenuconfig
LinuxSystemUtilities--->
[*]mdev
[*]Support/etc/mdev.conf
[*]Supportsubdirs/symlinks
[*]Supportregularexpressionssubstitutionswhenrenamingdevice
[*]Supportcommandexecutionatdeviceaddition/removal
2.udev或者mdev需要内核sysfs和tmpfs虚拟文件系统的支持,sysfs为udev提供设备入口和uevent通道,tmpfs为udev设备文件提供存放空间。
所以在/etc/fstab配置文件中添加如下内容(红色部分):
#devicemount-pointtypeoptionsdumpfsckorder
#----------------------------------------------------------------
procfs/procprocdefaults00
sysfs/syssysfsdefaults00
tmpfs/dev/shmtmpfsdefaults00
usbfs/proc/bus/usbusbfsdefaults00
ramfs/devramfsdefaults00
none/dev/ptsdevptsmode=062200
3.在系统初始化配置文件/etc/init.d/rcS中挂载mdev要用到的sysfs文件系统和tmpfs文件系统,然后启动/sbin目录下的mdev应用对系统的设备进行搜索(红色部分)。
#Mountvirtualfilesystem
/bin/mount-tprocprocfs/proc
/bin/mount-n-tsysfssysfs/sys
/bin/mount-n-tusbfsusbfs/proc/bus/usb
/bin/mount-tramfsramfs/dev
#Makedir
/bin/mkdir-p/dev/pts
/bin/mkdir-p/dev/shm
/bin/mkdir-p/var/log
/bin/mount-n-tdevptsnone/dev/pts-omode=0622
/bin/mount-n-ttmpfstmpfs/dev/shm
#Makedevicenode
echo/sbin/mdev>/proc/sys/kernel/hotplug
/sbin/mdev-s
4.在设备驱动程序中加上对类设备接口的支持,即在驱动程序加载和卸载函数中实现设备文件的创建与销毁,例如在之前篇幅的按键驱动中添加(红色部分):
#include//设备类用到的头文件
staticintdevice_major=DEVICE_MAJOR;//用于保存系统动态生成的主设备号
staticstructclass*button_class;//定义一个类
staticint__initbutton_init(void)
{
//注册字符设备,这里定义DEVICE_MAJOR=0,让系统去分配,注册成功后将返回动态分配的主设备号device_major=register_chrdev(DEVICE_MAJOR,DEVICE_NAME,&buttons_fops);
if(device_major {
printk(DEVICE_NAME"registerfaild!
\n");
returndevice_major;
}
//注册一个设备类,使mdev可以在/dev/目录下建立设备节点
button_class=class_create(THIS_MODULE,DEVICE_NAME);
if(IS_ERR(button_class))
{
printk(DEVICE_NAME"createclassfaild!
\n");
return-1;
}
//创建一个设备节点,取名为DEVICE_NAME(即my2440_buttons)
//注意2.6内核较早版本的函数名是class_device_create,现该为device_create
device_create(button_class,NULL,MKDEV(device_major,0),NULL,DEVICE_NAME);
return0;
}
staticvoid__exitbutton_exit(void)
{
//注销字符设备
uegister_chrdev(device_major,DEVICE_NAME);
//删除设备节点,注意2.6内核较早版本的函数名是class_device_destroy,现该为device_destroy
device_destroy(button_class,MKDEV(device_major,0));
//注销类
class_destroy(button_class);
}
4.至于mdev的配置文件/etc/mdev.conf,这个可有可无,只是设定设备文件的一些规则。
我这里就不管他了,让他为空好了。
5.完成以上步骤后,重新编译文件系统,下载到开发板上,启动开发板后进入开发板的/dev目录查看,就会有很多系统设备节点在这里产生了,我们就可以直接使用这些设备节点了。
篇三:
设备模型(上)底层模型
Linux设备驱动工程师之路
——设备模型(上)底层模型
一、重要知识点
1.Sysfs文件系统
Sysfs文件系统是一种类似于proc文件系统的特殊文件系统,它存在于内存当中,当系统启动时由内核挂载于内存当中。
用于将系统中的设备组织成层次结构,并向用户模式程序提供详细的数据结构信息。
2.Linux设备底层模型
1)为什么要使用设备模型
随着系统的拓扑结构越来越复杂,以及要支持诸如电源管理等新特性的要求,于是在
2.6的内核中出现了设备模型。
设备模型其实就是一套数据结构建立起来的模型。
内核使用该模型支持了多种不同的任务,包括:
a.电源管理和系统关机
设备模型使操作系统能够以正确的顺序遍历系统硬件。
b.与用户空间通信
Sysfs文件系统向用户空间提供系统信息以及改变操作参数的结构。
c.热插拔事件
d.设备类型
系统中许多部分对设备如何连接不感兴趣,但是他们需要知道哪些类型设备时可用的。
设备模型提供了将设备分类的机制。
e.对象的生命周期
上述的许多功能,包括热插拔支持和sysfs,使得内核中管理对象的工作更为复杂。
设备模型需要创造一套机制管理对象的生命周期。
2)Kobject
如果说设备模型是一套房子的话,Kobject就是构造房子的砖块。
每个注册的Kobject的都对应于Sysfs文件系统中的一个目录。
Kobject是组成设备模型的基本结构。
类似于C++的基类,它潜入于更大的对象中——所谓的容器,用来描述设备模型的组件。
如bus,device,drivers都是典型的容器。
这些容器就是通过kobject连接起来,形成一个树状结构。
这个树状结构就与/sys文件系统对应。
不过kobject只能建立单层结构,也就是只能建立一级目录,要建立多级目录,还要使用后面要介绍的Kset。
Kobject结构定义为:
structkobject{
constchar*name;//指向设备名称的指针
structlist_headentry;//structlist_headentry;挂接到所在kset中去的单元structkobject*parent;//指向父对象的指针
structkset*kset;//所属kset的指针
structkobj_type*ktype;//指向其对象类型描述符的指针
structsysfs_dirent*sd;//sysfs文件系统中与该对象对应的文件节点路径指针structkrefkref;//对象引用计数
unsignedintstate_initialized:
1;
unsignedintstate_in_sysfs:
1;
unsignedintstate_add_uevent_sent:
1;
unsignedintstate_remove_uevent_sent:
1;
unsignedintuevent_suppress:
1;
};
structkobj_type{
void(*release)(structkobject*kobj);
structsysfs_ops*sysfs_ops;
structattribute**default_attrs;
};
相关操作函数:
voidkobjet_init(structkobject*kobj)
初始化Kobject
intkobject_add(structkobject*kobj)
将Kobject对象注册到linux系统,如果失败则返回一个错误码.
intkobject_init_and_add(structkobject*kobj,kobj_type*ktype,structkobject*parent,const*fmt…)
初始化并注册kobject,kobject传入要初始化的Kobject对象,ktype将在后面介绍到,parent指向上级的kobject对象,如果指定为NULL,将在/sys的顶层创建一个目录。
*fmt为kobject对象的名字。
kobject的ktype对象是一个指向kobject_type结构的指针,该结构记录了kobject对象的一些属性。
每个kobject都需要对应一个相应的kobj_type结构。
structkobj_type{
void(*release)(structkobject*kobj);
structsysfs_ops*sysfs_ops;
structattribute**default_attrs;
};
release方法用于释放kobject占用的资源,当kobject引用计数为0时被调用。
kobje_type的attribute成员:
structattribute{
char*name;//属性文件名
structmodule*owner;
mode_tmode;
}
structattribute(属性):
对应于kobject的目录下一个文件,name就是文件名。
kobje_type的structsysfs_ops成员:
structsysfs_ops
{
ssize_t(*show)(structkobejct*,
structattribute*,char*name);
ssize_t(*store)(structkobejct*,structattribute*,char*name);
}
show:
当用户读属性文件时,该函数被调用,该函数将属性值存入buffer中返回给用户态;
store:
当用户写属性文件时,该函数被调用,用于存储用户存入的属性值。
Kobject测试模块:
#include
#include
#include
#include
#include
#include
#include
MODULE_AUTHOR("DavidXie");
MODULE_LICENSE("DualBSD/GPL");
voidobj_test_release(structkobject*kobject);
ssize_tkobj_test_show(structkobject*kobject,structattribute*attr,char*buf);
ssize_tkobj_test_store(structkobject*kobject,structattribute*attr,constchar*buf,size_tcount);
structattributetest_attr={
.name="kobj_config",
.mode=S_IRWXUGO,
};
staticstructattribute*def_attrs[]={
&test_attr,
NULL,
};
structsysfs_opsobj_test_sysops=
{
.show=kobj_test_show,
.store=kobj_test_store,
};
structkobj_typektype=
{
.release=obj_test_release,
.sysfs_ops=&obj_test_sysops,
.default_attrs=def_attrs,
};
voidobj_test_release(structkobject*kobject)
{
printk("eric_test:
release.\n");
}
ssize_tkobj_test_show(structkobject*kobject,structattribute*attr,char*buf)
{
printk("haveshow.\n");
printk("attrname:
%s.\n",attr->name);
sprintf(buf,"%s\n",attr->name);
returnstrlen(attr->name)+2;
}
ssize_tkobj_test_store(structkobject*kobject,structattribute*attr,constchar*buf,size_tcount){
printk("havestore\n");
printk("write:
%s\n",buf);
returncount;
}
structkobjectkobj;
staticintkobj_test_init()
{
printk("kbojecttestinit.\n");
kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");
return0;
}
staticintkobj_test_exit()
{
printk("kobjecttestexit.\n");
kobject_del(&kobj);
return0;
}
module_init(kobj_test_init);
module_exit(kobj_test_exit);
测试结果:
在/sys目录下创建了kobject_test目录
在kobject_test目录下有kobj_config文件
读kobject_config文件则调用了show函数。
并在用户空间显示了show返回的kobject对象名字。
写kobject_config文件调用了store函数。
3)Kset
kset的主要功能是包容;我们可以认为它是kobject的顶层容器。
实际上,在每个kset对象的内部,包含了自己的kobject,并且可以用多种处理kobject的方法处理kset。
如果说kobject是基类的话,那么kset就是派生类。
kobject通过kset组织成层次化的结构,kset是相同类型的组合。
通俗的讲,kobject建立一级的子目录,kset可以为kobject建立多级的层次性的父目录。
structkset{
structlist_headlist;//用于连接该kset中所有kobject的链表头
spinlock_tlist_lock;
s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- udev mdev 学习 总结