sysfs文件系统
来源:互联网 发布:怎么看淘宝的图片大小 编辑:程序博客网 时间:2024/06/05 13:07
sysfs文件系统
sysfs是一个特殊的文件系统,类似于proc。sysfs不仅像proc一样允许用户空间访问内核的数据,而且它以更结构化的方式向用户提供内核数据信息。sysfs是一种内存文件系统,它与kobject关系非常密切。系统中的每一个kobject对应sysfs中的一个目录。而每一个sysfs中的目录代表一个kobject对象,每个文件代表kobject的属性。
sysfs文件系统非常清晰地展示了设备驱动程序模型中各组件的层次关系。其顶级目录包括block、device、bus、drivers、class、power、firmware等。sysfs文件系统最基本的接口包括:
sysfs文件系统一般是自动加载到/sys下的,也可以通过下面的命令手工加载:
- int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) ;
- int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode);
- void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
- mount -t sysfs sysfs /sys
/sys的目录结构如表1-1所示。
表1-1 sysfs文件系统的目录
名 称
功 能
Block
块设备
Bus
系统总线
Class
设备组
Devices
系统设备
Firmware
固件
Kernel
内核
Module
内核模块
Power
供电系统
设备模型层次
在kobject等内核对象机制的基础上,Linux的设备模型包括设备结构device、设备驱动结构device_driver、总线结构bus、设备类结构class等几个核心组件。
设备结构device主要用来描述DMA配置以及与体系相关的硬件特性,定义如下:
- struct device {
- struct device*parent; //父设备
- struct device_private*p;
- struct kobject kobj;
- const char*init_name; /*初始名称*/
- struct device_type *type;
- struct semaphore sem; /* 同步信号量*/
- struct bus_type *bus;
- struct device_driver *driver; /*关联的设备驱动结构 */
- void *platform_data; /* 平台相关的数据 */
- struct dev_pm_info power;
- #ifdef CONFIG_NUMA
- int numa_node;/* NUMA结点*/
- #endif
- u64 *dma_mask; /*DMA掩码 */
- u64 coherent_dma_mask;/ * 连续DMA内存分配掩码*/
- struct device_dma_parameters *dma_parms;
- struct list_head dma_pools; /*DMA池*/
- struct dma_coherent_mem *dma_mem;
- /*体系结构相关的附加信息*/
- struct dev_archdata archdata;
- dev_t devt;
- spinlock_t devres_lock;
- struct list_head devres_head;
- struct klist_node knode_class;
- struct class *class;
- const struct attribute_group **groups;
- void (*release)(struct device *dev);
- };
device的注册与注销函数如下:
device_driver对象用来描述设备的管理接口,对应的数据结构定义如下:
- int device_register(struct device * dev);
- void device_unregister(struct device * dev);
- int device_add(struct device * dev);
- void device_del(struct device * dev);
device_driver的注册与注销函数原型如下:
- struct device_driver {
- const char*name; //设备驱动程序的名称
- struct bus_type*bus; //该驱动程序所管理的设备挂接的总线
- struct module *owner;
- const char*mod_name; /*模块名*/
- bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
- int (*probe) (struct device *dev); //指向设备探测函数
- int (*remove) (struct device *dev); //用于删除设备的函数
- void (*shutdown) (struct device *dev); //停止设备的函数
- int (*suspend) (struct device *dev, pm_message_t state); //挂起设备的函数
- int (*resume) (struct device *dev); //恢复设备的函数
- const struct attribute_group **groups;
- const struct dev_pm_ops *pm;
- struct driver_private *p;
- };
- int driver_register(struct device_driver * drv);
- void driver_unregister(struct device_driver * drv);
platform的概念
平台概念的引入目的是为了能够更好地描述设备的资源信息。平台设备是系统中自治的实体,包括基于端口的设备、外围总线和集成入片上系统平台的大多数控制器,它们通常直接通过CPU的总线寻址。每个平台设备被赋予一个名称,并分配一定数量的资源。平台设备本质上是device_driver模型的扩展。
平台设备使用platform_device结构描述,该结构定义如下:
- struct platform_device {
- const char* name; // 平台设备名称
- int id;
- struct device dev; //对应的设备结构
- u32 num_resources; //资源的数量
- struct resource * resource; //资源信息
- struct platform_device_id*id_entry;
- struct pdev_archdata archdata; /*体系结构相关的附加信息*/
- };
- int platform_device_register(struct platform_device *);//注册一个平台设备
- void platform_device_unregister(struct platform_device *);//注销一个平台设备
- 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 (*resume)(struct platform_device *);
- struct device_driver driver; //对应的设备驱动结构
- struct platform_device_id *id_table;
- };
- int platform_driver_register(struct platform_driver *drv);
- void platform_driver_unregister(struct platform_driver *drv);
platform_driver_register和platform_driver_unregister本质上就是调用driver_register和driver_unregister。
resource结构是对平台资源的描述,定义如下:
- struct resource {
- resource_size_t start; //起始地址
- resource_size_t end; //终止地址
- const char *name; //名称
- unsigned long flags;//资源类别
- struct resource *parent, *sibling, *child;
- };
- #define IORESOURCE_IO 0x00000100 //IO资源
- #define IORESOURCE_MEM 0x00000200 //内存资源
- #define IORESOURCE_IRQ 0x00000400 //中断资源
- #define IORESOURCE_DMA 0x00000800 //DMA资源
- //根据资源类型和序号来获取指定的资源
- struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
- //根据序号获取资源中的中断号
- struct int platform_get_irq(struct platform_device *dev, unsigned int num);
- //根据名称和类别获取指定的资源
- struct resource * platform_get_resource_byname(struct platform_device *dev, unsigned int type, char *name);
- //根据名称获取资源中的中断号
- int platform_get_irq_byname(struct platform_device *dev, char *name);
例1.13 AT91RM9200的MMC平台设备资源实例
本例为AT91RM9200处理器的MMC卡设备的资源实例。核心代码如下所示:
- static u64 mmc_dmamask = 0xffffffffUL;
- static struct at91_mmc_data mmc_data;
- static struct resource mmc_resources[] = {
- [0] = {
- .start = AT91RM9200_BASE_MCI,
- .end = AT91RM9200_BASE_MCI + SZ_16K - 1,
- .flags = IORESOURCE_MEM,//内存资源
- },
- [1] = {
- .start = AT91RM9200_ID_MCI,
- .end = AT91RM9200_ID_MCI,
- .flags = IORESOURCE_IRQ,//中断资源
- },
- };
- //平台设备结构
- static struct platform_device at91rm9200_mmc_device = {
- .name = "at91_mci",
- .id = -1,
- .dev = {
- .dma_mask = &mmc_dmamask,
- .coherent_dma_mask = 0xffffffff,
- .platform_data = &mmc_data,
- },
- .resource = mmc_resources,
- .num_resources = ARRAY_SIZE(mmc_resources),
- };
注册MMC设备驱动代码如下:
- static struct platform_driver at91_mci_driver = {
- .remove = __exit_p(at91_mci_remove),
- .suspend = at91_mci_suspend,
- .resume = at91_mci_resume,
- .driver = {
- .name = "at91_mci",
- .owner = THIS_MODULE,
- },
- };
- static int __init at91_mci_init(void)
- {
- return platform_driver_probe(&at91_mci_driver, at91_mci_probe);
- }
- static int __init at91_mci_probe(struct platform_device *pdev)
- {
- struct mmc_host *mmc;
- struct at91mci_host *host;
- struct resource *res;
- int ret;
- pr_debug("Probe MCI devices\n");
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);//获取内存资源
- if (!res)
- return -ENXIO;
- //请求内存区域
- if (!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME))
- return -EBUSY;
- mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
- if (!mmc) {
- pr_debug("Failed to allocate mmc host\n");
- release_mem_region(res->start, res->end - res->start + 1);
- return -ENOMEM;
- }
- mmc->ops = &at91_mci_ops;
- mmc->f_min = 375000;
- mmc->f_max = 25000000;
- mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->max_blk_size = 4095;
- mmc->max_blk_count = mmc->max_req_size;
- host = mmc_priv(mmc);
- host->mmcmmc = mmc;
- host->buffer = NULL;
- host->bus_mode = 0;
- host->board = pdev->dev.platform_data;
- if (host->board->wire4) {
- if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
- mmc->caps |= MMC_CAP_4_BIT_DATA;
- else
- printk("AT91 MMC: 4 wire bus mode not supported - using 1 wire\n");
- }
- //获取控制器时钟信息
- host->mci_clk = clk_get(&pdev->dev, "mci_clk");
- if (IS_ERR(host->mci_clk)) {
- printk(KERN_ERR "AT91 MMC: no clock defined.\n");
- mmc_free_host(mmc);
- release_mem_region(res->start, res->end - res->start + 1);
- return -ENODEV;
- }
- host->baseaddr = ioremap(res->start, res->end - res->start + 1);//地址映射
- if (!host->baseaddr) {
- clk_put(host->mci_clk);
- mmc_free_host(mmc);
- release_mem_region(res->start, res->end - res->start + 1);
- return -ENOMEM;
- }
- clk_enable(host->mci_clk);//允许外设时钟
- at91_mci_disable(host);
- at91_mci_enable(host);
- //获取中断资源
- host->irq = platform_get_irq(pdev, 0);
- //申请中断
- ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host);
- if (ret) {
- printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n");
- clk_disable(host->mci_clk);
- clk_put(host->mci_clk);
- mmc_free_host(mmc);
- iounmap(host->baseaddr);
- release_mem_region(res->start, res->end - res->start + 1);
- return ret;
- }
- …
- return 0;
- }
- sysfs 文件系统
- SYSFS文件系统
- sysfs 文件系统
- sysfs文件系统
- sysfs 文件系统
- sysfs文件系统
- sysfs文件系统
- sysfs文件系统
- sysfs文件系统
- sysfs文件系统
- sysfs文件系统
- Sysfs文件系统
- sysfs文件系统
- sysfs 文件系统
- Sysfs文件系统
- sysfs 文件系统
- sysfs文件系统
- sysfs文件系统
- ImageSwitch和TextSwitch
- 数据库设计原则
- (Linux 2.6设备管理机制)kobject和kset
- window 通过改变注册表键值设置ie代理(超级有用)
- 长方形
- sysfs文件系统
- 发布Notification报错的问题
- 树上的三角形
- SGU 108 滚动数组优化打表
- java的异常机制浅谈--更好的为他人服务
- POJ 2985 Treap平衡树(求第k大的元素)
- icon font在firefox下无法显示
- TimePicker的使用
- hadoop 负载均衡