sysfs platform总线

发布者:会哭的蓝精灵最新更新时间:2019-11-19 来源: 51hei关键字:sysfs  platform总线  linux2  6内核  文件系统 手机看文章 扫描二维码
随时随地手机看文章

sysfs 文件系统linux2.6内核引入sysfs文件系统,sysfs可以看成与proc,devfs和devpty同类别的文件系统,该文件系统是虚拟的文件系统,可以更方便对系统设备进行管理。它可以产生一个包含所有系统硬件层次视图,与提供进程和状态信息的proc文件系统十分类似。sysfs把连接在系统上的设备和总线组织成为一个分级的文件,它们可以由用户空间存取,向用户空间导出内核的数据结构以及它们的属性。sysfs的一个目的就是展示设备驱动模型中各组件的层次关系,其顶级目录包括block,bus,drivers,class,power和firmware等.

它把实际连接到系统上的设备和总线组织成一个分级的文件,用户空间的程序同样可以利用这些信息以实现和内核的交互,该文件系统是当前系统上实际设备树的一个直观反应,它是通过kobject子系统来建立这个信息的,当一个kobject被创建的时候,对应的文件和目录也就被创建了,位于 /sys下的相关目录下,既然每个设备在sysfs中都有唯一对应的目录,那么也就可以被用户空间读写了。你可能根本没有去关心过sysfs文件系统的挂载过程,它是这样被挂载的。mount -t sysfs sysfs /sys

sysfs是一个特殊文件系统,并没有一个实际存放文件的介质。sysfs的信息来源是kobject层次结构,读一个sysfs文件,就是动态的从kobject结构提取信息,生成文件。重启后里面的信息当然就没了


sysfs文件系统与kobject结构紧密关联,每个在内核中注册的kobject对象都对应于sysfs文件系统中的一个目录。Kobject 是Linux 2.6引入的新的设备管理机制,在内核中由struct kobject表示。通过这个数据结构使所有设备在底层都具有统一的接口,kobject提供基本的对象管理,是构成Linux2.6设备模型的核心结构,Kobject是组成设备模型的基本结构。类似于C++中的基类,它嵌入于更大的对象的对象中,用来描述设备模型的组件。如bus,devices, drivers 等。都是通过kobject连接起来了,形成了一个树状结构。这个树状结构就与/sys向对应。


sysfs就是利用VFS的接口去读写kobject的层次结构,建立起来的文件系统。 kobject的层次结构的注册与注销XX_register()形成的。文件系统是个很模糊广泛的概念, linux把所有的资源都看成是文件,让用户通过一个统一的文件系统操作界面,也就是同一组系统调用,对属于不同文件系统的文件进行操作。这样,就可以对用户程序隐藏各种不同文件系统的实现细节,为用户程序提供了一个统一的,抽象的,虚拟的文件系统界面,这就是所谓"VFS(Virtual Filesystem Switch)"。这个抽象出来的接口就是一组函数操作。


我们要实现一种文件系统就是要实现VFS所定义的一系列接口,file_operations, dentry_operations, inode_operations等,供上层调用。file_operations是描述对每个具体文件的操作方法(如:读,写),dentry_operations结构体指明了VFS所有目录的操作方法, 而inode_operations提供所有结点的操作方法。

举个例子,我们写C程序,open(“hello.c”, O_RDONLY),它通过系统调用的流程是这样的

open() -> 系统调用-> sys_open() -> filp_open()-> dentry_open() -> file_operations->open()         

不同的文件系统,调用不同的file_operations->open(),在sysfs下就是sysfs_open_file()。


我们使用不同的文件系统,就是将它们各自的文件信息都抽象到dentry和inode中去。这样对于高层来说,我们就可以不关心底层的实现,我们使用的都是一系列标准的函数调用。这就是VFS的精髓,实际上就是面向对象。


注意sysfs是典型的特殊文件。它存储的信息都是由系统动态的生成的,它动态的包含了整个机器的硬件资源情况。从sysfs读写就相当于向 kobject层次结构提取数据。


Linux内核驱动的的platform机制

虚拟总线platform简介


 从Linux 2.6起引入了一套新的驱动管理和注册机制:platform_device和platform_driver。Linux中大部分的设备驱动,都可以使用这套机制,设备用platform_device表示,驱动用platform_driver进行注册。


 Linux platform. driver机制和传统的device driver 机制(通过driver_register函数进行注册)相比,一个十分明显的优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform. device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性(这些标准接口是安全的)。platform机制的本身使用并不复杂,由两部分组成:platform_device和platfrom_driver。通过platform机制开发底层设备驱动的大致流程如图所示。

platform_device简介


linux发明的platform虚拟总线,相应的设备叫做

platform_device,相应的驱动叫做

platfrom_driver。


    platform_device结构体描述设备的名称、资源信息等。该结构被定include/linux/platform_device.h中,     定义的结构体原型如下:


        struct platform_device {


               const char * name;    //定义平台设备的名称


               int id;


               struct device dev;


               u32 num_resources;


               struct resource * resource; //定义平台设备的资源。


        };


    最重要的一个成员struct resource * resource。struct resource被定义在include/linux/ioport.h中,定义原型如下:


       struct resource {


               resource_size_t start;  //定义资源的起始地址


               resource_size_t end;  //定义资源的结束地址


               const char *name;    //定义资源的名称


               unsigned long flags; //定义资源的类型,比如MEM,IO,IRQ,DMA类型


               struct resource *parent, *sibling, *child;  //资源链表指针


        };


    以RTC驱动为例(为什么用RTC,RTC是一个标准的plartform device,机制是相同的,但是相对比较简单)

    在arch/arm/mach-sep4020/devices.c中加入rtc的plartform_device结构体和resources结构体:

        static struct resource sep4020_rtc_resource[] = {

              [0] = { .start = RTC_BASE_V,

                      .end   = RTC_BASE_V+ 0x2f,

                      .flags = IORESOURCE_MEM,

                    }

              [1] = {

                      .start = INTSRC_RTC,

                      .end   = INTSRC_RTC,

                      .flags = IORESOURCE_IRQ,

                    }

        }; 

        struct platform_device sep4020_device_rtc = {

              .name            = "sep4020_rtc",

              .id              = -1,

              .num_resources   = ARRAY_SIZE(sep4020_rtc_resource),

             .resource        = sep4020_rtc_resource,

        };   

    然后再通过4020.c文件中的__initdata设备数组将这个plartform_device结构体注册进去了: 

        static struct platform_device *devices[] __initdata = {

               &serial_device,

             &sep4020_device_rtc,

               &epson_ohci_device,

               &sep4020_device_usbgadget

        };  

    platform_add_devices(devices, ARRAY_SIZE(devices)); 通过调用platform_add_devices()向系统中添加该设备了,该函数内部调用platform_device_register( )进行设备注册。要注意的是,这里的platform_device设备的注册过程必须在相应设备驱动加载之前被调用,即执行platform_driver_register()之前,原因是驱动注册时需要匹配内核中所有已注册的设备名。(后面会详细介绍device和driver之间是如何通过注册的名字进行连接的)

                                                           platform_driver简介


   platform_driver结构体的原型定义,在include/linux/platform_device.h中,代码如下:


         struct platform_driver {

             int (*probe)(struct platform_device *);

             int (*remove)(struct platform_device *);

             void (*shutdown)(struct platform_device *);

             int (*suspend)(struct platform_device *, pm_message_t state);

             int (*suspend_late)(struct platform_device *, pm_message_t state);

             int (*resume_early)(struct platform_device *);

             int (*resume)(struct platform_device *);

             struct device_driver driver;

         };

   内核提供的platform_driver结构体的注册函数为platform_driver_register(),

   其原型定义在driver/base/platform.c文件中,具体实现代码如下:

         int platform_driver_register(struct platform_driver *drv)

         {

             drv->driver.bus = &platform_bus_type;

             if (drv->probe)  

                 drv->driver.probe = platform_drv_probe;

             if (drv->remove)

                 drv->driver.remove = platform_drv_remove;

             if (drv->shutdown)

                 drv->driver.shutdown = platform_drv_shutdown;

             if (drv->suspend)

                 drv->driver.suspend = platform_drv_suspend;

             if (drv->resume)

                 drv->driver.resume = platform_drv_resume;

             return driver_register(&drv->driver);

         }

    总结,通常情况下只要和内核本身运行依赖性不大的外围设备,相对独立的,拥有各自独自的资源(地址总线和IRQs),都可以用platform_driver实现。如:LCD,网卡、USB、UART等,都可以用platfrom_driver写,而timer,irq等小系统之内的设备则最好不用platfrom_driver机制。


关键字:sysfs  platform总线  linux2  6内核  文件系统 引用地址:sysfs platform总线

上一篇:为你破解ARM中断寄存器
下一篇:platform驱动模型编程总结(基于mini2440平台的LED驱动)

推荐阅读最新更新时间:2024-11-16 21:07

stm32——Fatfs文件系统读写文件
因项目需求需要移植fatfs文件系统,参考了正点原子的战舰例程。 使用mcu为stm32f103zet6,spi的sd卡模块,8Gsd卡。例程为mini板(mcu:stm32f103rct6)的 ALIENTEK MINISTM32 实验29 FATFS文件系统实验,zet6的例程由于是sdio模式所以没有选用。 初始化 这里只初始化sd卡.e2prom部分删除了 mem_init(); //初始化内存池 //SD卡检测及初始化 while(SD_Initialize()) //检测不到SD卡 { delay_ms(500); } e
[单片机]
stm32——Fatfs<font color='red'>文件系统</font>读写文件
Flash损耗均衡的嵌入式文件系统设计
  本文基于AVR单片机扩展 Flash存储器 和以太网控制器设计了一款嵌入式文件系统,实现数据存储和存储器使用的损耗均衡,为延长Flash存储器的使用寿命提供研究方法。   1 硬件平台设计   本嵌入式文件系统选用Atmel公司的AVR单片机ATmega 128和Flash存储器AT45D13081。该Flash芯片具有8 Mb存储空间,共分为4096数据页,每页可存储264字节。通过串行外围设备接口SPI实现ATmega 128和AT45DB081之间的数据通信。文件系统的硬件结构如图1所示。其中,RTL8019AS是一种全双工即插即用的以太网控制器。      2 嵌入式文件系统总体设计   文件系统
[单片机]
Flash损耗均衡的嵌入式<font color='red'>文件系统</font>设计
S3C6410嵌入式应用平台构建(六)——linux-3.14.4移植到OK6410-(Yaffs2文件系统移植)
我个人觉得nandflash上用yaffs2文件系统是很好的方案,但是最新的Linux并不支持yaffs2文件系统,需要你自己给内核打补丁,不过话说在前面,由于内核间差异及兼容问题,在编译时肯定会出现各种编译问题,需要你一一的去解决。 一、准备工作 1. 下载源码 使用git工具下载:$ git clone git://www.aleph1.co.uk/yaffs2 2. 给内核打补丁 下载完成后,在该执行目录下会有yaffs2文件夹,进入该文件夹。 $ ./patch-ker.sh c m ../../kernel/test/linux-3.14.4 Updating ../../kernel/te
[单片机]
S3C6410嵌入式应用平台构建(六)——linux-3.14.4移植到OK6410-(Yaffs2<font color='red'>文件系统</font>移植)
基于AT91SAM9X35EK的嵌入式Linux+UBI根文件系统移植成功
经过近一个月的学习与实践,终于在AT91SAM9X35EK开发板上跑起了Linux系统,用的是UBI文件系统,开发环境与不断的编译、查找资料、烧写验证,下载相关的软件,占了很多的时间,不过不断的克服困难,就能不断的前进。路很长,但需要耐心不断走下去。 开发环境为: CentOS6.5 Linux虚拟机。 硬件为:AT91SAM9X35EK NandFlash启动(Bootstrap+Uboot+Linux Kernel+UBI根文件系统全烧写在NandFlash中)。 使用较新的AT91Bootstrap与Uboot。 使用较新的稳定的Linux version 2.6.39(ATmel官方提供AT91SAM9X35E
[单片机]
基于AT91SAM9X35EK的嵌入式Linux+UBI根<font color='red'>文件系统</font>移植成功
u-boot移植(十三)---代码修改---支持文件系统及补丁制作
一、烧写文件系统 1.1 jffs2烧写   1.下载文件系统:tftp 30000000 fs_mini_mdev.jffs2      2.擦除文件的块:nand erase.part rootfs      3.烧入文件系统:nand write.jffs2 30000000 0x00260000 5b89a8      4.设置启动参数:set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2      5.重新启动      这个需要先烧写内核。 1.2 yaffs烧写   1.下载文件系统:tftp 30000000 fs_mini_m
[单片机]
u-boot移植(十三)---代码修改---支持<font color='red'>文件系统</font>及补丁制作
ARM Linux根文件系统Root Filesystem的制作
http://xianzilu.spaces.live.com/blog/fakehandlerpage.aspx?wa=wsignin1.0 http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!290.entry 关于根文件系统的制作,网络上有很多文章,大多数都只讲到建几个目录,然后用Busybox做个Shell,有很多关键的东西没有说。经过很长时间的摸爬滚打,我终于能够白手起家建立一个根文件系统了。其实我也不懂得原理,只是告诉大家我的作法,其中也不免有错误,欢迎大家指正。 首先介绍根文件系统的组成:目录、Shell、库、脚本,一个个来。 目录 根
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved