Chinaunix首页 | 论坛 | 博客
  • 博客访问: 84468
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-07 19:35
文章分类
文章存档

2015年(11)

2014年(18)

我的朋友

分类: LINUX

2014-11-20 15:51:51

(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调用下层实例

阅读(1224) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~