学习总结
当前位置:首页 > 工作总结 > 学习总结 > 列表页

udev和mdev学习总结

小草范文网  发布于:2017-04-16  分类: 学习总结 手机版

篇一:linux环境编程

福建农林大学金山学院

课程名称:姓 名:系: 专 业:年 级:学 号:指导教师:职 称:实验报告

Linux环境编程

信息与机电工程 计算机科学与技术

2009级

讲师

2012年 5 月 26 日

实验项目列表

福建农林大学金山学院实验报告

系: 信息与机电工程系 专业:计算机科学与技术年级:2009姓名: 学号: 实验室号_ _607_____ 计算机号实验时间:指导教师签字:成绩:

实验一: gcc编译器(验证性、2学时)

一、实验目的:

1)熟悉Shell操作环境。

2)掌握在Linux下的C语言代码编译运行的方法。 3)初步了解C语言库函数与Linux系统调用。

二、实验内容

1、编写能输出“Hello world!”问候语的C程序,并在终端中编译、执行。要求记录所使用的命令及结果。 #include <stdio.h> #include<stdlib.h> int main() {

printf("Hello World\n"); exit(0); }

2、编写程序p.c,其功能是从键盘输入两个实数,输出这两个实数的平方和,生成可执行文件为pow。 #include"stdio.h" main() {

float x,y;

scanf("%f %f",&x,&y); printf("%6.3f",x*x+y*y); }

3、教材第9页静态库实验,记录操作步骤与结果。分析所出现的问题及如何解决的? 4、编写一个C程序并设置其在后台执行,其功能是在一段时间后(可自行设置),在屏幕上显示信息:Time for play!,写出相应的程序、命令及结果。 #include <stdio.h> main() {

sleep(6);

printf("Time for Play!\n");

}

5、编制一段程序,使用系统调用fork( )创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。让每一个进程在屏幕上显示一个字符:父进程显示字符a,子进程分别显示字符 b和字符c。试观察、记录并分析屏幕上,进程调度的情况。 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> main()

{

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的平台、内核版本号。

VMware Workstation

2、 在Linux中,标准设备文件有哪些?这些设备文件在哪个目录? Devfsudevmdev

3、 对于上述各编程题目中所用到了的各个头文件,请找到它们的位置。 /user/include 四、总结

篇二:设备文件系统剖析与使用

设备文件系统剖析与使用 设备文件系统剖析与使用

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。

? 共享资源,欢迎转载:http://hbhuanggang.cublog.cn

一、什么是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的源码进行编译移植)

#cd busybox-1.13.0/

#make menuconfig

Linux System Utilities --->

[*] mdev

[*] Support /etc/mdev.conf

[*] Support subdirs/symlinks

[*] Support regular expressions substitutions when renaming device

[*] Support command execution at device addition/removal

2. udev或者mdev需要内核sysfs和tmpfs虚拟文件系统的支持,sysfs为udev提供设备入口和uevent通道,tmpfs为udev设备文件提供存放空间。所以在/etc/fstab配置文件中添加如下内容(红色部分):

# device mount-point type options dump fsck order

#----------------------------------------------------------------

procfs /proc proc defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs /dev/shm tmpfs defaults 0 0

usbfs /proc/bus/usb usbfs defaults 0 0

ramfs /dev ramfs defaults 0 0

none /dev/pts devpts mode=0622 0 0

3. 在系统初始化配置文件/etc/init.d/rcS中挂载mdev要用到的sysfs文件系统和tmpfs文件系统,然后启动/sbin目录下的mdev应用对系统的设备进行搜索(红色部分)。

# Mount virtual filesystem

/bin/mount -t proc procfs /proc

/bin/mount -n -t sysfs sysfs /sys

/bin/mount -n -t usbfs usbfs /proc/bus/usb

/bin/mount -t ramfs ramfs /dev

# Make dir

/bin/mkdir -p /dev/pts

/bin/mkdir -p /dev/shm

/bin/mkdir -p /var/log

/bin/mount -n -t devpts none /dev/pts -o mode=0622

/bin/mount -n -t tmpfs tmpfs /dev/shm

# Make device node

echo /sbin/mdev > /proc/sys/kernel/hotplug

/sbin/mdev -s

4. 在设备驱动程序中加上对类设备接口的支持,即在驱动程序加载和卸载函数中实现设备文件的创建与销毁,例如在之前篇幅的按键驱动中添加(红色部分):

#include <linux/device.h> //设备类用到的头文件

static int device_major = DEVICE_MAJOR; //用于保存系统动态生成的主设备号

static struct class *button_class; //定义一个类

static int __init button_init(void)

{

//注册字符设备,这里定义DEVICE_MAJOR=0,让系统去分配,注册成功后将返回动态分配的主设备号 device_major = register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &buttons_fops);

if(device_major < 0)

{

printk(DEVICE_NAME " register faild!\n");

return device_major;

}

//注册一个设备类,使mdev可以在/dev/目录下建立设备节点

button_class = class_create(THIS_MODULE, DEVICE_NAME);

if(IS_ERR(button_class))

{

printk(DEVICE_NAME " create class faild!\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);

return 0;

}

static void __exit button_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结构定义为:

struct kobject {

const char *name; //指向设备名称的指针

struct list_head entry; // struct list_head entry; 挂接到所在kset中去的单元 struct kobject *parent; // 指向父对象的指针

struct kset *kset; //所属kset的指针

struct kobj_type *ktype; //指向其对象类型描述符的指针

struct sysfs_dirent *sd; // sysfs文件系统中与该对象对应的文件节点路径指针 struct kref kref; // 对象引用计数

unsigned int state_initialized:1;

unsigned int state_in_sysfs:1;

unsigned int state_add_uevent_sent:1;

unsigned int state_remove_uevent_sent:1;

unsigned int uevent_suppress:1;

};

struct kobj_type {

void (*release)(struct kobject *kobj);

struct sysfs_ops *sysfs_ops;

struct attribute **default_attrs;

};

相关操作函数:

void kobjet_init(struct kobject*kobj)

初始化Kobject

int kobject_add(struct kobject*kobj)

将Kobject对象注册到linux系统,如果失败则返回一个错误码.

int kobject_init_and_add(structkobject *kobj, kobj_type *ktype, struct kobject *parent, const *fmt…)

初始化并注册kobject,kobject传入要初始化的Kobject对象,ktype将在后面介绍到,parent指向上级的kobject对象,如果指定为NULL,将在/sys的顶层创建一个目录。*fmt为kobject对象的名字。

kobject的ktype对象是一个指向kobject_type结构的指针,该结构记录了kobject对象的一些属性。每个kobject都需要对应一个相应的kobj_type结构。

struct kobj_type{

void (*release)(struct kobject *kobj);

structsysfs_ops *sysfs_ops;

struct attribute **default_attrs;

};

release方法用于释放kobject占用的资源,当kobject引用计数为0时被调用。

kobje_type的attribute成员:

struct attribute{

char*name;//属性文件名

structmodule *owner;

mode_tmode;

}

struct attribute(属性):对应于kobject的目录下一个文件, name就是文件名。

kobje_type的struct sysfs_ops成员:

struct sysfs_ops

{

ssize_t (*show)(structkobejct *,

udev和mdev学习总结

struct attribute *, char *name);

ssize_t (*store)(structkobejct *, struct attribute *, char *name);

}

show:当用户读属性文件时,该函数被调用,该函数将属性值存入buffer中返回给用户态;

store:当用户写属性文件时,该函数被调用,用于存储用户存入的属性值。

Kobject测试模块:

#include <linux/device.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/string.h>

#include <linux/sysfs.h>

#include <linux/stat.h>

MODULE_AUTHOR("David Xie");

MODULE_LICENSE("Dual BSD/GPL");

void obj_test_release(struct kobject *kobject);

ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf);

ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count);

struct attribute test_attr = {

.name = "kobj_config",

.mode = S_IRWXUGO,

};

static struct attribute *def_attrs[] = {

&test_attr,

NULL,

};

struct sysfs_ops obj_test_sysops =

{

.show = kobj_test_show,

.store = kobj_test_store,

};

struct kobj_type ktype =

{

.release = obj_test_release,

.sysfs_ops=&obj_test_sysops,

.default_attrs=def_attrs,

};

void obj_test_release(struct kobject *kobject)

{

printk("eric_test: release .\n");

}

ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf)

{

printk("have show.\n");

printk("attrname:%s.\n", attr->name);

sprintf(buf,"%s\n",attr->name);

return strlen(attr->name)+2;

}

ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count) {

printk("havestore\n");

printk("write: %s\n",buf);

return count;

}

struct kobject kobj;

static int kobj_test_init()

{

printk("kboject test init.\n");

kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");

return 0;

}

static int kobj_test_exit()

{

printk("kobject test exit.\n");

kobject_del(&kobj);

return 0;

}

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建立多级的层次性的父目录。

struct kset {

struct list_head list; //用于连接该kset中所有kobject的链表头

spinlock_t list_lock;

struct kobject kobj; //嵌入的kobject

struct kset_uevent_ops *uevent_ops; //指向热插拔操作表的指针

};

struct kset {

struct subsystem * subsys; //所在的subsystem的指针

struct kobj type * ktype; //指向该kset对象类型描述符的指针

struct list head list;

struct kobject kobj;

struct kset_uevent_ops * uevent_ops;

};

包含在kset中的所有kobject被组织成一个双向循环链表,list域正是该链表的头。Ktype域指向一个kobj_type 结构,被该kset中的所有kobject共享,表示这些对象的类型。Kset数据结构还内嵌了一个kobject对象(由kobj域表示),所有属于这个kset 的kobject对象的parent域均指向这个内嵌的对象。此外,kset还依赖于kobj维护引用计数:kset的引用计数实际上就是内嵌的kobject对象的引用计数。

本文已影响