Linux中设计强调的基本观点就是机制和策略分离。
机制是做某样事情的具体步骤,方法。而策略则是每个步骤所采取的不同方式。机制是相对固定的。
而每个步骤采用的策略是不固定的。机制是稳定的,而策略是灵活的。
设备的详细信息会通过netlink套接字发送出来:
netlink的使用范例
#include<linux/netlink.h>
static void die(char *s)
{
write(2,s,strlen(s));
exit(1);
}
int main(int argc,char *argv[])
{
struct sockaddr_nl nls;
struct pollfd pfd;
char buf[512];
/*open hotplug event */
menset(&nls,0,sizeof(struct sockaddr_nl));
nls.nl_family = AF_NET_LINK;
nls.nl_pid = getpid();
nls.nl_group = -1;
pfd.events = POLLIN;
pfd.fd = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT);
if(pfd.fd = -1)
die("Not root\n");
//Listen to netlink socket
if(bind(pfd.fd,(void *)&nls,sizeof(struct sockaddt_nl)))
die("Bind faild\n");
while(-1 != poll(&pfd,1,-1))
{
int i,len = recv(pfd.fd,buf,sizeof(buf),MSG_DONTWAIT);
if(len == -1)
die("recv\n");
//Print the data to stdout
i = 0;
while(i < len)
printf("%s\n",buf+1);
i +=strlen(buf + 1)+1;
}
die("poll\n");
//Dear gcc:shut up
return 0;
}
udev就是采用这种方式接收netlink消息,并根据他的内容和用户设置给udev的规则做匹配来进行工作的。
对于冷插拔的设备,Linux提供了sysfs下面的一个uevent节点。可以往该节点写一个add,导致内核重新发送netlink
,之后udev就可以收到冷插拔的netlink消息了。
devfs与udev的显著区别在于:采用devfs,当一个并不存在的/dev节点被打开的时候,devfs能自动加载对应的驱
动,udev则不这么做,udev的设计者认为Linux应该在设备被发现的时候加载驱动模块,而不是当他被访问的时候,系
统中所有的设备都应该产生热插拔事件并加载恰当的驱动。
sysfs文件系统与Linux
Linux 2.6 以后的内核引入了sysfs被看成是与proc,devfs和devpty同类别的文件系统。该文件系统是一个虚拟的
文件系统,他可以产生一个包括所有系统硬件的层级视图,与提供进程和状态信息的proc文件系统十分相似。
sysfs的一个目的就是展示设备驱动模型中各个组件的层次关系。其顶级目录包括block、bus、devices、
block目录包含所有的块设备,dvices目录包含系统所有的设备,并根据设备挂载的总线类型组织层次结构,bus目
录中包含所有的总线类型,class目录中包含系统中的设备的类型,/sys下
大多数情况下,内核中的设备驱动核心代码作为“幕后大佬”可以处理好这些关系,内核中的总线和其他内核子系统
会完成与设备模型的交互,不必关心设备模型,只需按照每个框架的要求,填鸭式的填充xxx_driver里面的各种回掉
数,xxx是总线的名字。
Linux中,分别使用bus_type,device_driver和device来描述总线,设备和驱动,定义于:include/linux/driver.h
头文件当中。
先到这里,爱你,YZ.
机制是做某样事情的具体步骤,方法。而策略则是每个步骤所采取的不同方式。机制是相对固定的。
而每个步骤采用的策略是不固定的。机制是稳定的,而策略是灵活的。
设备的详细信息会通过netlink套接字发送出来:
netlink的使用范例
#include<linux/netlink.h>
static void die(char *s)
{
write(2,s,strlen(s));
exit(1);
}
int main(int argc,char *argv[])
{
struct sockaddr_nl nls;
struct pollfd pfd;
char buf[512];
/*open hotplug event */
menset(&nls,0,sizeof(struct sockaddr_nl));
nls.nl_family = AF_NET_LINK;
nls.nl_pid = getpid();
nls.nl_group = -1;
pfd.events = POLLIN;
pfd.fd = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT);
if(pfd.fd = -1)
die("Not root\n");
//Listen to netlink socket
if(bind(pfd.fd,(void *)&nls,sizeof(struct sockaddt_nl)))
die("Bind faild\n");
while(-1 != poll(&pfd,1,-1))
{
int i,len = recv(pfd.fd,buf,sizeof(buf),MSG_DONTWAIT);
if(len == -1)
die("recv\n");
//Print the data to stdout
i = 0;
while(i < len)
printf("%s\n",buf+1);
i +=strlen(buf + 1)+1;
}
die("poll\n");
//Dear gcc:shut up
return 0;
}
udev就是采用这种方式接收netlink消息,并根据他的内容和用户设置给udev的规则做匹配来进行工作的。
对于冷插拔的设备,Linux提供了sysfs下面的一个uevent节点。可以往该节点写一个add,导致内核重新发送netlink
,之后udev就可以收到冷插拔的netlink消息了。
devfs与udev的显著区别在于:采用devfs,当一个并不存在的/dev节点被打开的时候,devfs能自动加载对应的驱
动,udev则不这么做,udev的设计者认为Linux应该在设备被发现的时候加载驱动模块,而不是当他被访问的时候,系
统中所有的设备都应该产生热插拔事件并加载恰当的驱动。
sysfs文件系统与Linux
Linux 2.6 以后的内核引入了sysfs被看成是与proc,devfs和devpty同类别的文件系统。该文件系统是一个虚拟的
文件系统,他可以产生一个包括所有系统硬件的层级视图,与提供进程和状态信息的proc文件系统十分相似。
sysfs的一个目的就是展示设备驱动模型中各个组件的层次关系。其顶级目录包括block、bus、devices、
block目录包含所有的块设备,dvices目录包含系统所有的设备,并根据设备挂载的总线类型组织层次结构,bus目
录中包含所有的总线类型,class目录中包含系统中的设备的类型,/sys下
大多数情况下,内核中的设备驱动核心代码作为“幕后大佬”可以处理好这些关系,内核中的总线和其他内核子系统
会完成与设备模型的交互,不必关心设备模型,只需按照每个框架的要求,填鸭式的填充xxx_driver里面的各种回掉
数,xxx是总线的名字。
Linux中,分别使用bus_type,device_driver和device来描述总线,设备和驱动,定义于:include/linux/driver.h
头文件当中。
先到这里,爱你,YZ.