(1)linux文件系统目录结构介绍
进入Linux根目录/之后,运行:ls -l 即可查看。
/bin:包含基本命令文件,如ls,cp等,这个文件中的文件都是可执行的。
/boot:Linux系统的内核及引导系统程序所需要的文件,如vmlinuz,initrd.img都位于这个目录中。
/dev:设备文件存储目录,应用程序通过对这些文件的读写和控制就可以访问实际的设备。如:ls -l /dev。
/etc:系统配置文件的所在地,一些服务器的配置文件也在这里,如帐号名跟密码。
/home:普通用户的家目录。
/lib:库文件的存放目录。
/lost+found:在EXT2和EXT3文件系统中,系统崩溃时的一些文件碎片存放在这里。
/mnt:一般是用来存放挂载储存设备的挂载目录的,比如cdrom的目录。有时我们可以把让系统开机自动挂载文件系统,把挂载点放在这里 也是可以的。
/opt:有些软件包会安装在这里,比如open office或者用户自己编译的软件包也可以安装在这个目录中。
/proc:操作系统运行时,进程及内核信息(如CPU,内存)存放在这里。它是个伪文件系统目录,仅存在于内存中。
/root:超级用户的根目录。
/sbin:超级用户的命令文件存放的目录。
/tmp:用来存放系统运行时产生的临时文件。
/usr:系统存放程序的目录,内核发行版提供的软件包大多数被安装在这里。
/var:这个目录的内容经常变动,如/var/log用来存放系统日志。
/sys:Linux 2.6内核支持的sysfs文件系统被映射在此目录。Linux 设备驱动模型中的总线、驱动和设备都可以在sysfs文件系统找到对应的节点。当内核检测到系统中出现了新设备后,内核会在sysfs文件系统中为该新设备生成一项新的记录。
(2)linux下有专门的文件系统用来对设备进行管理,devfs和sysfs就是其中两种。
1,devfs:devfs是在2.4内核就出现了,它是用来解决linux中设备管理混乱的问题,linux内核开发人员开发了devfs。
2,sysfs:是Linux 内核中设计较新的一种虚拟的基于内存的文件系统,并没有一个实际存放文件的介质,断电后就玩完了。它的作用与proc 有些类似,但除了与proc 相同的具有查看和设定内核参数功能之外,还有为Linux 统一设备模型作为管理之用。
sysfs 文件系统总是被挂载在/sys 挂载点上,sysfs的信息来源是kobject层次结构,读一个sysfs文件,就是动态的从kobject结构提取信息,生成文件。虽然在较早期的2.6内核系统上并没有规定sysfs的标准挂载位置,可以把sysfs 挂载在任何位置,但较近的2.6内核修正了这一规则,要求sysfs 总是挂载在/sys目录上。sysfs 与proc 相比有很多优点:sysfs 的设计原则是一个属性文件只做一件事情,sysfs 属性文件一般只有一个值,直接读取或写入。新设计的内核机制应该尽量使用sysfs机制,而将proc 保留给纯净的“进程文件系统”。
UBUNTU中比如:执行ls -F /sys,得block/ bus/ class/ dev/ devices/ firmware/ fs/ kernel/ module/ power/
下面对/sys 文件系统下的目录结构做说明:
/sys/devices:这是内核对系统中所有设备的分层次表达模型,也是 /sys 文件系统管理设备的最重要的目录结构;
/sys/dev:这个目录下维护一个按字符设备和块设备的主次号码(major:minor)链接到真实的设备(/sys/devices下)的符号链接文件,它是在内核2.6.26 首次引入;
/sys/bus:这是内核设备按总线类型分层放置的目录结构,devices中的所有设备都是连接于某种总线之下,在这里的每一种具体总线之下可以找到每一个具体设备的符号链接,它也是构成 Linux 统一设备模型的一部分;
/sys/class:这是按照设备功能分类的设备模型,如系统所有输入设备都会出现在 /sys/class/input 之下,而不论它们是以何种总线连接到系统。它也是构成Linux 统一设备模型的一部分;比如LED灯设备:cat /sys/class/leds/lcd-backlight/,终端回显:
-rw-r--r-- root root 4096 1970-01-01 00:00 uevent
lrwxrwxrwx root root 1970-01-01 00:03 subsystem -> ../../leds
lrwxrwxrwx root root 1970-01-01 00:03 device -> ../../../devices/platform/smdk-backlight
drwxr-xr-x root root 1970-01-01 00:00 power
-rw-r--r-- system system 4096 1970-01-01 00:00 brightness
其中device有指向smdk-backlight的符号链接,当你进入该目录再退回上层目录时,你会发现处于/sys/devices目录下,更说明了设备模型虽然采用不同方式却指向同一设备的概念。
/sys/block:这里是系统中当前所有的块设备所在,按照功能来说放置在/sys/class 之下会更合适,但只是由于历史遗留因素而一直存在于/sys/block, 但从2.6.22 开始就已标记为过时,只有在打开了CONFIG_SYSFS_DEPRECATED 配置下编译才会有这个目录的存在,并且在2.6.26 内核中已正式移到 /sys/class/block, 旧的接口/sys/block 为了向后兼容保留存在,但其中的内容已经变为指向它们在/sys/devices/ 中真实设备的符号链接文件;
/sys/firmware:这里是系统加载固件机制的对用户空间的接口,关于固件有专用于固件加载的一套API;
/sys/fs:这里按照设计是用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点,但目前只有fuse,gfs2 等少数文件系统支持sysfs接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在sysctl (/proc/sys/fs) 接口中;
/sys/kernel:这里是内核所有可调整参数的位置,目前只有uevent_helper, kexec_loaded, mm,和新式的slab 分配器等几项较新的设计在使用它,其它内核可调整参数仍然位于sysctl (/proc/sys/kernel) 接口中;
/sys/module:这里有系统中所有模块的信息,不论这些模块是以内联(inlined)方式编译到内核映像文件(vmlinuz)中还是编译为外部模块(ko文件),都可能会出现在 /sys/module 中;
/sys/power:这里是系统中电源选项,这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机、重启等。
(3)总结一下,驱动跟内核接口分类对应如下:
类型 所包含的内容 对应内核数据结构 对应/sys项
设备(Devices) 设备是此模型中最基本的类型 struct device /sys/devices/*/*/.../
设备驱动(Device Drivers) 多个相同设备只需要一份驱动程序 struct device_driver /sys/bus/pci/drivers/*/
总线类型(Bus Types) 在总线级别对总线上的所有设备管理 struct bus_type /sys/bus/*/
设备类别(Device Classes) 按照功能进行分类的设备层次树 /sys/class/input/ 下
sysfs 给应用程序提供了统一访问设备的接口,但可以看到, sysfs 仅仅是提供了一个可以统一访问设备的框架,但究竟是否支持 sysfs 还需要各设备驱动程序的编程支持;在 2.6 内核诞生 5年以来的发展中,很多子系统、设备驱动程序逐渐转向了 sysfs 作为与用户空间友好的接口,但仍然也存在大量的代码还在使用旧的 proc 或虚拟字符设备的 ioctl 方式。
(4) Driver Attributes and Device Attributes
A,Driver Attributes结构:
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *driver, char *buf);
ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
};
Device drivers can export attributes via their sysfs directories,Drivers can declare attributes using a DRIVER_ATTR macro that works identically to the DEVICE_ATTR macro.
Example: DRIVER_ATTR(debug,0644,show_debug,store_debug);
This is equivalent to declaring:struct driver_attribute driver_attr_debug;This can then be used to add and remove the attribute from the driver's directory using:
int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);
B,Device Attributes结构:
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,const char *buf, size_t count);
};
Attributes of devices can be exported via drivers using a simple procfs-like interface.Please see Documentation/filesystems/sysfs.txt for more information
on how sysfs works.Attributes are declared using a macro called DEVICE_ATTR:#define DEVICE_ATTR(name,mode,show,store)
Example:DEVICE_ATTR(power,0644,show_power,store_power);
This declares a structure of type struct device_attribute named 'dev_attr_power'. This can then be added and removed to the device's directory using:
int device_create_file(struct device *device, struct device_attribute * entry);
void device_remove_file(struct device * dev, struct device_attribute * attr);
(5)sysfs实例
用DRIVER_ATTR创建的设备属性如下:
static DRIVER_ATTR(chipinfo, S_IRUGO, show_chipinfo_value, NULL);
static DRIVER_ATTR(sensordata, S_IRUGO, show_sensordata_value, NULL);
static DRIVER_ATTR(cali, S_IWUSR | S_IRUGO, show_cali_value, store_cali_value);
static DRIVER_ATTR(selftest, S_IWUSR | S_IRUGO, show_selftest_value, store_selftest_value);
static DRIVER_ATTR(firlen, S_IWUSR | S_IRUGO, show_firlen_value, store_firlen_value);
static DRIVER_ATTR(trace, S_IWUSR | S_IRUGO, show_trace_value, store_trace_value);
static DRIVER_ATTR(status, S_IRUGO, show_status_value, NULL);
/*----------------------------------------------------------------------------*/
static struct driver_attribute *mma8452q_attr_list[] = {
&driver_attr_chipinfo, /*chip information*/
&driver_attr_sensordata, /*dump sensor data*/
&driver_attr_cali, /*show calibration data*/
&driver_attr_selftest, /*self test demo*/
&driver_attr_firlen, /*filter length: 0: disable, others: enable*/
&driver_attr_trace, /*trace log*/
&driver_attr_status,
};
用driver_create_file(driver, mma8452q_attr_list[idx])创建完之后,在/sys/bus/platform/drivers/gsensor路径下就可以查看到创建的那些属性项目,如下:
uevent
unbind
bind
gsensor
chipinfo
sensordata
cali
selftest
firlen
trace
status
(6)上层通过sysfs调用下层实例
参考原文:http://www.xxlinux.com/linux/article/development/kernel/20090112/14828.html
参考原文: http://blog.csdn.net/zq5848/article/details/6857453