精华内容
下载资源
问答
  •  sysfs是在内存中存在文件系统,它的文件都只在内存中存在。因此 对文件的读写实际是对内存的读写,不涉及对硬盘的操作   4.3.1 读文件的过程的分析  a  a 申请内存页函数: fastcall unsigned long...

    4.3     sysfs文件的读写

            sysfs是在内存中存在文件系统,它的文件都只在内存中存在。因此 对文件的读写实际是对内存的读写,不涉及对硬盘的操作
            

    4.3.1 读文件的过程的分析

            a
            a

    申请内存页函数:

    fastcall unsigned long get_zeroed_page(gfp_t gfp_mask)
    {
    	struct page * page;
    
    	/*
    	 * get_zeroed_page() returns a 32-bit address, which cannot represent
    	 * a highmem page
    	 */
    	BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);
    
    	page = alloc_pages(gfp_mask | __GFP_ZERO, 0);
    	if (page)
    		return (unsigned long) page_address(page);
    	return 0;
    }

    分配页面空间函数 alloc_pages:

    #ifdef CONFIG_NUMA
    extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order);
    
    static inline struct page *
    alloc_pages(gfp_t gfp_mask, unsigned int order)
    {
    	if (unlikely(order >= MAX_ORDER))
    		return NULL;
    
    	return alloc_pages_current(gfp_mask, order);
    }
    extern struct page *alloc_page_vma(gfp_t gfp_mask,
    			struct vm_area_struct *vma, unsigned long addr);
    #else
    #define alloc_pages(gfp_mask, order) \
    		alloc_pages_node(numa_node_id(), gfp_mask, order)
    #define alloc_page_vma(gfp_mask, vma, addr) alloc_pages(gfp_mask, 0)
    #endif

    mm/Mempolicy.h :

    /**
     * 	alloc_pages_current - Allocate pages.
     *
     *	@gfp:
     *		%GFP_USER   user allocation,
     *      	%GFP_KERNEL kernel allocation,
     *      	%GFP_HIGHMEM highmem allocation,
     *      	%GFP_FS     don't call back into a file system.
     *      	%GFP_ATOMIC don't sleep.
     *	@order: Power of two of allocation size in pages. 0 is a single page.
     *
     *	Allocate a page from the kernel page pool.  When not in
     *	interrupt context and apply the current process NUMA policy.
     *	Returns NULL when no page can be allocated.
     *
     *	Don't call cpuset_update_task_memory_state() unless
     *	1) it's ok to take cpuset_sem (can WAIT), and
     *	2) allocating for current task (not interrupt).
     */
    struct page *alloc_pages_current(gfp_t gfp, unsigned order)
    {
    	struct mempolicy *pol = current->mempolicy;
    
    	if ((gfp & __GFP_WAIT) && !in_interrupt())
    		cpuset_update_task_memory_state();
    	if (!pol || in_interrupt())
    		pol = &default_policy;
    	if (pol->policy == MPOL_INTERLEAVE)
    		return alloc_page_interleave(gfp, order, interleave_nodes(pol));
    	return __alloc_pages(gfp, order, zonelist_policy(gfp, pol));
    }
    EXPORT_SYMBOL(alloc_pages_current);

    include/linux/Gfp.h

    static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
    						unsigned int order)
    {
    	if (unlikely(order >= MAX_ORDER))
    		return NULL;
    
    	/* Unknown node is current node */
    	if (nid < 0)
    		nid = numa_node_id();
    
    	return __alloc_pages(gfp_mask, order,
    		NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask));
    }

    a

    4.3.2 写文件的过程分析

            普通文件的写函数是sysfs_write_file,它的代码如下:


            a

    展开全文
  • 4.2 sysfs文件的打开操作 4.2.1 real_lookup函数详解  a 4.2.2 为文件创建inode结构 4.2.3 为dentry结构绑定属性 4.2.4 调用文件系统的open函数

    4.2    sysfs文件的打开操作


    4.2.1 real_lookup函数详解

            a

    4.2.2 为文件创建inode结构


    4.2.3 为dentry结构绑定属性


    4.2.4 调用文件系统的open函数

    展开全文
  • 最初开发 /proc 文件系统是为了提供有关系统中进程的信息。但是由于这个文件系统非常有用,因此内核中的很多元素也开始使用它来报告信息,或启用动态运行时配置。 entry = create_proc_entry(XXX_DEVICE_PROC_NAME...

    PROC

    最初开发 /proc 文件系统是为了提供有关系统中进程的信息。但是由于这个文件系统非常有用,因此内核中的很多元素也开始使用它来报告信息,或启用动态运行时配置。

            entry = create_proc_entry(XXX_DEVICE_PROC_NAME, 0, NULL);  
            if(entry) {  
                entry->owner = THIS_MODULE;  
                entry->read_proc = xxx_proc_read;  
                entry->write_proc = xxx_proc_write;  
            }  
        }  
    
        static ssize_t xxx_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data) {  
       
        //先把用户提供的缓冲区值拷贝到内核缓冲区中去
        copy_from_user...
    
        }  
    
     static ssize_t xxx_proc_read(char* page, char** start, off_t off, int count, int* eof, void* data) {  
     
    
    //在用户或应用程序访问该proc文件时,就会调用这个函数,实现这个函数时只需将想要让用户看到的内容放入page即可
    //page 参数是这些数据写入到的位置,其中 count 定义了可以写入的最大字符数。在返回多页数据(通常一页是 4KB)时,我们需要使用 start和 off 参数
    //此处提供的 page 缓冲区在内核空间中
    
        }  
        
    

    其他的一些函数

    create_proc_entry()创建一个文件
    proc_symlink() 创建符号链接
    proc_mknod() 创建设备文件
    proc_mkdir() 创建目录
    remove_proc_entry() 删除文件或目录
    
    

    SYSFS

    比proc组织更好

    • /sys
    block/       块设备,提供以设备名(如mmcblk0)到/sys/devices的符号链接
    bus/         每个总线包含两个目录 devices/ drivers/  ,提供到连接该总线的设备的符号链接
    class/     按设备功能分类
    dev/
    devices/   被发现的物理设备
    firmware/
    net/
    fs/
    
    • /sys/block
    lrwxrwxrwx root     root              1970-01-01 08:00 loop0 -> ../devices/virtual/block/loop0
    lrwxrwxrwx root     root              1970-01-01 08:00 loop1 -> ../devices/virtual/block/loop1
    lrwxrwxrwx root     root              1970-01-01 08:00 loop2 -> ../devices/virtual/block/loop2
    lrwxrwxrwx root     root              1970-01-01 08:00 loop3 -> ../devices/virtual/block/loop3
    lrwxrwxrwx root     root              1970-01-01 08:00 loop4 -> ../devices/virtual/block/loop4
    lrwxrwxrwx root     root              1970-01-01 08:00 loop5 -> ../devices/virtual/block/loop5
    lrwxrwxrwx root     root              1970-01-01 08:00 loop6 -> ../devices/virtual/block/loop6
    lrwxrwxrwx root     root              1970-01-01 08:00 loop7 -> ../devices/virtual/block/loop7
    lrwxrwxrwx root     root              1970-01-01 08:00 mmcblk0 -> ../devices/platform/sunxi-mmc.2/mmc_host/mmc0/mmc0:0001/block/mmcblk0
    lrwxrwxrwx root     root              1970-01-01 08:00 mmcblk0boot0 -> ../devices/platform/sunxi-mmc.2/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot0
    lrwxrwxrwx root     root              1970-01-01 08:00 mmcblk0boot1 -> ../devices/platform/sunxi-mmc.2/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot1
    lrwxrwxrwx root     root              1970-01-01 08:00 zram0 -> ../devices/virtual/block/zram0
    
    
    • /sys/bus
    clocksource
    cpu
    hid
    i2c
    mdio_bus
    mmc
    platform
    scsi
    sdio
    serio
    spi
    usb
    usb-serial
    
    • /sys/bus/i2c
    devices
    drivers
    drivers_autoprobe
    drivers_probe
    uevent
    
    • /sys/bus/i2c/devices
    lrwxrwxrwx root     root              2019-12-19 15:02 1-0033 -> ../../../devices/platform/twi.1/i2c-1/1-0033
    lrwxrwxrwx root     root              2019-12-19 14:56 i2c-0 -> ../../../devices/platform/twi.0/i2c-0
    lrwxrwxrwx root     root              2019-12-19 14:56 i2c-1 -> ../../../devices/platform/twi.1/i2c-1
    lrwxrwxrwx root     root              2019-12-19 14:56 i2c-2 -> ../../../devices/platform/twi.2/i2c-2
    
    • /sys/bus/i2c/drivers
    drwxr-xr-x root     root              1970-01-01 08:00 A350
    drwxr-xr-x root     root              2019-12-19 15:01 dummy
    
    • /sys/dev
    block
    char                    
    
    • /sys/dev/char
      major:minor为名到 /sys/devices 的符号链接
    10:47 -> ../../devices/virtual/misc/alarm
    251:0 -> ../../devices/platform/uart.0/tty/ttyS0
    189:0 -> ../../devices/platform/sunxi-ehci.1/usb1
    116:16 -> ../../devices/platform/audiocodec/sound/card0/pcmC0D0p
    
    • /sys/class
    android_usb
    axppower
    bdi
    block
    bluetooth
    bsg
    capture
    cedar_dev
    cuse
    devfreq
    disp
    dma
    firmware
    gpio
    graphics
    hwmon
    i2c-adapter
    ieee80211
    input
    
    • /sys/devices
    platform    芯片内部各种控制器和外设, CPU直接寻址
    system   芯片内部的核心结构,比如cpu,clocksource
    virtual
    
    • /sys/devices/platform
    alarmtimer
    audiocodec
    disp
    ion-sunxi.0
    mali-utgard.0
    power
    power.0
    sunxi-codec
    sunxi-mmc.1
    sunxi-mmc.2
    sunxi-rtc
    sunxi_pwm
    sunxi_usb_udc
    switch-gpio.0
    twi.0
    twi.1
    twi.2
    uart.0
    uart.1
    uart.2
    uart.3
    uevent
    wifi_pm.0
    
    • /sys/devices/system
    clocksource
    cpu
    
    

    sysfs接口创建驱动对应的属性,使得可以在用户空间通过sysfs接口的show和store函数与硬件交互;

    函数宏

    DEVICE_ATTR;
    BUS_ATTR
    DRIVER_ATTR
    
    #define DEVICE_ATTR(_name, _mode, _show, _store) \
         struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
         
     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);
     };
    
      static ssize_t xxx_show(struct device *d, struct device_attribute*attr, char *buf)
      {
     
      }
      
      static ssize_t xxx_store(struct device *d, struct device_attribute *attr,const char *buf,size_t count)
      {
    
     }
      
     static DEVICE_ATTR(xxx_name, S_IWUSR |S_IRUGO, xxx_show, xxx_store);
    //属性结构体数组最后一项必须以NULL结尾。
     static struct attribute *xxx_attrs[] = {
            &dev_attr_xxx.attr,
            NULL
     };
    
    

    模块加载的时候创建/sys/class/classxxx, /dev/devXXX

    没有总线的字符设备驱动

    在驱动init实现

    1. /sys/class/下创建类目录
    struct class *class_create(struct module *owner, const char *name)
    

    返回 class 结构体
    一个struct class结构体类型变量对应一个类

    2. 创建设备节点
    static struct device_attribute door_dev_attrs[] = {
    	__ATTR(door_io2, S_IWUGO, NULL, door_io2_store),
    	__ATTR(door_io1, S_IRUGO, door_io1_show, NULL),
    	__ATTR_NULL
    };
    
    	g_door_class->dev_attrs = door_dev_attrs;
    	device_create(g_door_class, NULL, g_devid, &(door_devdata->io_data), DEV_NAME);
    
    devt:设备号
    alloc_chrdev_region(&g_devid, 0, 1, DEV_NAME);
    或者
    MKDEV(tmp_major, 0)
    

    platform总线驱动下添加

    在probe函数中实现

    调用device_create_file创建属性节点

    ret = device_create_file(psy->dev,&axp_charger_attrs[j]);
    

    一次创建多个属性节点group

     static const struct attribute_group xxx_attr_grp = {
             .attrs = xxx_attrs,
             
      }
    
    ret = sysfs_create_group(&pdev->dev.kobj,&gpio_attr_grp);
    
    //sysfs_create_group()在kobj目录下创建一个属性集合,并显示集合中的属性文件。如果文件已存在,会报错
    

    类的属性的创建

    class_attribute

    static struct class_attribute axppower_class_attrs[] = {
    	__ATTR(vbuslimit,S_IRUGO|S_IWUSR,vbuslimit_show,vbuslimit_store),
    	__ATTR(axpdebug,S_IRUGO|S_IWUSR,axpdebug_show,axpdebug_store),
    	__ATTR(longkeypoweroff,S_IRUGO|S_IWUSR,longkeypoweroff_show,longkeypoweroff_store),
    	__ATTR(out_factory_mode,S_IRUGO|S_IWUSR,out_factory_mode_show,out_factory_mode_store),
    	__ATTR(pmu_temp,S_IRUGO|S_IWUSR,pmu_temp_show,pmu_temp_store),
    	__ATTR_NULL
    };
    static struct class axppower_class = {
    	.name = "axppower",
    	.class_attrs = axppower_class_attrs,
    };
    
    class_register(&axppower_class);
    
    

    注册
    class_register 和class_create作用相同,参数用法不同而已。

    展开全文
  • 4.1 文件和目录的创建 4.1.1 sysfs文件系统的初始化 4.1.2 sysfs文件系统目录的创建 4.1.3 普通文件的创建

    4.1    文件和目录的创建


    4.1.1 sysfs文件系统的初始化


    4.1.2 sysfs文件系统目录的创建


    4.1.3 普通文件的创建


    展开全文
  • (1)linux文件系统目录结构介绍  进入Linux根目录/之后,运行:ls -l 即可查看。 /bin:包含基本命令文件,如ls,cp等,这个文件中的文件都是可执行的。 /boot:Linux系统的内核及引导系统程序所需要的文件,如...
  • 对于一位专业的工程师而言:自己所属的工作不能存在丝毫马虎 ...这里需要sysfs 虚拟文件系统相关的背景知识,最好去了解sysfs 的机制与理论知识,本文尽量不牵扯太多。 一、什么是属性?什么是Kobject?  
  • 一、以led灯 的android 系统架构作为实例 开门见山,我们知道在Android operation system 的四层架构;见右图   其中HAL层以下,即kernel层运行在system space,HAL-》framework一直以上运行在user space。 HAL ...
  • 1 kobject 和 kset 的关系 kset结构里面封装了一个kobject结构,同时包括一个链表头,属于这个kset的所有kobject都要链接到kset的链表头。 2、kobject实例:总线的注册
  • 在多任务处理操作系统中,每个CPU(或核心)在一个时间点上只能处理一个进程。在进程运行时,它对CPU时间和资源分配的要求会不断变化,从而为进程分配一个状态,它随着环境要求而改变。 就绪态和执行态:TASK_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,716
精华内容 686
关键字:

文件系统sysfs