Chinese translated version of Documentation/filesystems/sysfs.rst If you have any comment or update to the content, please contact the original document maintainer directly. However, if you have a problem communicating in English you can also ask the Chinese maintainer for help. Contact the Chinese maintainer if this translation is outdated or if there is a problem with the translation. Maintainer: Patrick Mochel <mochel@osdl.org> Mike Murphy <mamurph@cs.clemson.edu> Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> --------------------------------------------------------------------- Documentation/filesystems/sysfs.rst çä¸æç¿»è¯ å¦ææ³è¯è®ºææ´æ°æ¬æçå 容ï¼è¯·ç´æ¥èç³»åææ¡£çç»´æ¤è ãå¦æä½ ä½¿ç¨è±æ 交æµæå°é¾çè¯ï¼ä¹å¯ä»¥åä¸æçç»´æ¤è æ±å©ãå¦ææ¬ç¿»è¯æ´æ°ä¸åæ¶æè ç¿» è¯åå¨é®é¢ï¼è¯·èç³»ä¸æçç»´æ¤è ã è±æçç»´æ¤è ï¼ Patrick Mochel <mochel@osdl.org> Mike Murphy <mamurph@cs.clemson.edu> ä¸æçç»´æ¤è ï¼ å ç Fu Wei <tekkamanninja@gmail.com> ä¸æçç¿»è¯è ï¼ å ç Fu Wei <tekkamanninja@gmail.com> ä¸æçæ ¡è¯è ï¼ å ç Fu Wei <tekkamanninja@gmail.com> 以ä¸ä¸ºæ£æ --------------------------------------------------------------------- sysfs - ç¨äºå¯¼åºå æ ¸å¯¹è±¡(kobject)çæä»¶ç³»ç» Patrick Mochel <mochel@osdl.org> Mike Murphy <mamurph@cs.clemson.edu> 修订: 16 August 2011 åå§çæ¬: 10 January 2003 sysfs ç®ä»: ~~~~~~~~~~ sysfs æ¯ä¸ä¸ªæååºäº ramfs ä¸ä½äºå åçæ件系ç»ãå®æä¾å¯¼åºå æ ¸ æ°æ®ç»æåå ¶å±æ§ï¼ä»¥åå®ä»¬ä¹é´çå ³èå°ç¨æ·ç©ºé´çæ¹æ³ã sysfs å§ç»ä¸ kobject çåºå±ç»æç´§å¯ç¸å ³ã请é 读 Documentation/core-api/kobject.rst æ档以è·å¾æ´å¤å ³äº kobject æ¥å£ç ä¿¡æ¯ã ä½¿ç¨ sysfs ~~~~~~~~~~~ åªè¦å æ ¸é ç½®ä¸å®ä¹äº CONFIG_SYSFS ï¼sysfs æ»æ¯è¢«ç¼è¯è¿å æ ¸ãä½ å¯ éè¿ä»¥ä¸å½ä»¤æè½½å®: mount -t sysfs sysfs /sys å建ç®å½ ~~~~~~~~ ä»»ä½ kobject å¨ç³»ç»ä¸æ³¨åï¼å°±ä¼æä¸ä¸ªç®å½å¨ sysfs ä¸è¢«å建ãè¿ä¸ª ç®å½æ¯ä½ä¸ºè¯¥ kobject çç¶å¯¹è±¡æå¨ç®å½çåç®å½å建çï¼ä»¥åç¡®å°ä¼ é å æ ¸ç对象å±æ¬¡å°ç¨æ·ç©ºé´ãsysfs ä¸ç顶å±ç®å½ä»£è¡¨çå æ ¸å¯¹è±¡å±æ¬¡ç å ±åç¥å ï¼ä¾å¦ï¼æäºå¯¹è±¡å±äºæ个åç³»ç»ã Sysfs å¨ä¸å ¶ç®å½å ³èç kernfs_node 对象ä¸å é¨ä¿åä¸ä¸ªæåå®ç° ç®å½ç kobject çæéã以åï¼è¿ä¸ª kobject æé被 sysfs ç´æ¥ç¨äº kobject æ件æå¼åå ³éçå¼ç¨è®¡æ°ãèç°å¨ç sysfs å®ç°ä¸ï¼kobject å¼ç¨è®¡æ°åªè½éè¿ sysfs_schedule_callback() å½æ°ç´æ¥ä¿®æ¹ã å±æ§ ~~~~ kobject çå±æ§å¯å¨æ件系ç»ä¸ä»¥æ®éæ件çå½¢å¼å¯¼åºãSysfs 为å±æ§å®ä¹ äºé¢åæ件 I/O æä½çæ¹æ³ï¼ä»¥æä¾å¯¹å æ ¸å±æ§ç读åã å±æ§åºä¸º ASCII ç ææ¬æ件ã以ä¸ä¸ªæ件åªåå¨ä¸ä¸ªå±æ§å¼ä¸ºå®ãä½ä¸ä¸ª æ件åªå å«ä¸ä¸ªå±æ§å¼å¯è½å½±åæçï¼æ以ä¸ä¸ªå å«ç¸åæ°æ®ç±»åçå±æ§å¼ æ°ç»ä¹è¢«å¹¿æ³å°æ¥åã æ··åç±»åã表达å¤è¡æ°æ®ä»¥åä¸äºæªå¼çæ°æ®æ ¼å¼ä¼éå°å¼ºçå对ãè¿æ ·åæ¯ å¾ä¸¢è¸ç,èä¸å ¶ä»£ç ä¼å¨æªéç¥ä½è çæ åµä¸è¢«éåã ä¸ä¸ªç®åçå±æ§ç»æå®ä¹å¦ä¸: struct attribute { char * name; struct module *owner; umode_t mode; }; int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr); ä¸ä¸ªåç¬çå±æ§ç»æ并ä¸å å«è¯»åå ¶å±æ§å¼çæ¹æ³ãåç³»ç»æ好为å¢å ç¹å® 对象类åçå±æ§å®ä¹èªå·±çå±æ§ç»æä½åå°è£ å½æ°ã ä¾å¦:驱å¨ç¨åºæ¨¡åå®ä¹ç device_attribute ç»æä½å¦ä¸: 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); }; int device_create_file(struct device *, const struct device_attribute *); void device_remove_file(struct device *, const struct device_attribute *); 为äºå®ä¹è®¾å¤å±æ§ï¼åæ¶å®ä¹äºä¸ä¸è¾ å©å®: #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) ä¾å¦:声æ static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo); çåäºå¦ä¸ä»£ç ï¼ static struct device_attribute dev_attr_foo = { .attr = { .name = "foo", .mode = S_IWUSR | S_IRUGO, .show = show_foo, .store = store_foo, }, }; åç³»ç»ç¹æçåè°å½æ° ~~~~~~~~~~~~~~~~~~~ å½ä¸ä¸ªåç³»ç»å®ä¹ä¸ä¸ªæ°çå±æ§ç±»åæ¶ï¼å¿ é¡»å®ç°ä¸ç³»åç sysfs æä½ï¼ 以帮å©è¯»åè°ç¨å®ç°å±æ§ææè çæ¾ç¤ºåå¨åæ¹æ³ã struct sysfs_ops { ssize_t (*show)(struct kobject *, struct attribute *, char *); ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t); }; [åç³»ç»åºå·²ç»å®ä¹äºä¸ä¸ª struct kobj_type ç»æä½ä½ä¸ºè¿ä¸ªç±»åç æ述符ï¼å¹¶å¨æ¤ä¿å sysfs_ops çæéãæ´å¤çä¿¡æ¯åè§ kobject ç ææ¡£] sysfs ä¼ä¸ºè¿ä¸ªç±»åè°ç¨éå½çæ¹æ³ãå½ä¸ä¸ªæ件被读åæ¶ï¼è¿ä¸ªæ¹æ³ä¼ å°ä¸è¬çkobject å attribute ç»æä½æé转æ¢ä¸ºéå½çæéç±»åå è°ç¨ç¸å ³èçå½æ°ã 示ä¾: #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct device_attribute *dev_attr = to_dev_attr(attr); struct device *dev = kobj_to_dev(kobj); ssize_t ret = -EIO; if (dev_attr->show) ret = dev_attr->show(dev, dev_attr, buf); if (ret >= (ssize_t)PAGE_SIZE) { printk("dev_attr_show: %pS returned bad count\n", dev_attr->show); } return ret; } 读åå±æ§æ°æ® ~~~~~~~~~~~~ å¨å£°æå±æ§æ¶ï¼å¿ é¡»æå® show() æ store() æ¹æ³ï¼ä»¥å®ç°å±æ§ç 读æåãè¿äºæ¹æ³çç±»ååºè¯¥å以ä¸ç设å¤å±æ§å®ä¹ä¸æ ·ç®åã 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); ä¹å°±æ¯è¯´,ä»ä»¬åºåªä»¥ä¸ä¸ªå¤ç对象ãä¸ä¸ªå±æ§åä¸ä¸ªç¼å²æéä½ä¸ºåæ°ã sysfs ä¼åé ä¸ä¸ªå¤§å°ä¸º (PAGE_SIZE) çç¼å²åºå¹¶ä¼ éç»è¿ä¸ªæ¹æ³ã Sysfs å°ä¼ä¸ºæ¯æ¬¡è¯»åæä½è°ç¨ä¸æ¬¡è¿ä¸ªæ¹æ³ãè¿ä½¿å¾è¿äºæ¹æ³å¨æ§è¡æ¶ ä¼åºç°ä»¥ä¸çè¡ä¸º: - å¨è¯»æ¹é¢ï¼read(2)ï¼ï¼show() æ¹æ³åºè¯¥å¡«å æ´ä¸ªç¼å²åºãåæ³å±æ§ åºåªå¯¼åºäºä¸ä¸ªå±æ§å¼ææ¯ä¸ä¸ªåç±»åå±æ§å¼çæ°ç»ï¼æ以è¿ä¸ªä»£ä»·å° ä¸ä¼ä¸å¤ªé«ã è¿ä½¿å¾ç¨æ·ç©ºé´å¯ä»¥å±é¨å°è¯»åä»»æçååæç´¢æ´ä¸ªæ件ãå¦æç¨æ·ç©ºé´ ååæç´¢å°é¶æ使ç¨â0âå移æ§è¡ä¸ä¸ªpread(2)æä½ï¼show()æ¹æ³å° å次被è°ç¨ï¼ä»¥éæ°å¡«å ç¼åã - å¨åæ¹é¢ï¼write(2)ï¼ï¼sysfs å¸æå¨ç¬¬ä¸æ¬¡åæä½æ¶å¾å°æ´ä¸ªç¼å²åºã ä¹å Sysfs ä¼ éæ´ä¸ªç¼å²åºç» store() æ¹æ³ã å½è¦å sysfs æ件æ¶ï¼ç¨æ·ç©ºé´è¿ç¨åºé¦å 读åæ´ä¸ªæ件ï¼ä¿®è¯¥æ³è¦ æ¹åçå¼ï¼ç¶åååæ´ä¸ªç¼å²åºã å¨è¯»åå±æ§å¼æ¶ï¼å±æ§æ¹æ³çæ§è¡åºæä½ç¸åçç¼å²åºã 注记: - åæä½å¯¼è´ç show() æ¹æ³éè½½ï¼ä¼å¿½ç¥å½åæ件ä½ç½®ã - ç¼å²åºåºæ»æ¯ PAGE_SIZE 大å°ã对äºi386ï¼è¿ä¸ªå¼ä¸º4096ã - show() æ¹æ³åºè¯¥è¿ååå ¥ç¼å²åºçåèæ°ï¼ä¹å°±æ¯ scnprintf()ç è¿åå¼ã - show() æ¹æ³å¨å°æ ¼å¼åè¿åå¼è¿åç¨æ·ç©ºé´çæ¶åï¼ç¦æ¢ä½¿ç¨snprintf()ã å¦æå¯ä»¥ä¿è¯ä¸ä¼åçç¼å²åºæº¢åºï¼å¯ä»¥ä½¿ç¨sprintf()ï¼å¦åå¿ é¡»ä½¿ç¨ scnprintf()ã - store() åºè¿åç¼å²åºçå·²ç¨åèæ°ãå¦ææ´ä¸ªç¼åé½å·²å¡«æ»¡ï¼åªéè¿å count åæ°ã - show() æ store() å¯ä»¥è¿åé误å¼ãå½å¾å°ä¸ä¸ªéæ³å¼ï¼å¿ é¡»è¿åä¸ä¸ª é误å¼ã - ä¸ä¸ªä¼ éç»æ¹æ³ç对象å°ä¼éè¿ sysfs è°ç¨å¯¹è±¡å åµçå¼ç¨è®¡æ°åºå®å¨ å åä¸ã尽管å¦æ¤ï¼å¯¹è±¡ä»£è¡¨çç©çå®ä½(å¦è®¾å¤)å¯è½å·²ä¸åå¨ãå¦æå¿ è¦ï¼ åºè¯¥å®ç°ä¸ä¸ªæ£æµæºå¶ã ä¸ä¸ªç®åç(æªç»å®éªè¯å®ç)设å¤å±æ§å®ç°å¦ä¸ï¼ static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "%s\n", dev->name); } static ssize_t store_name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { snprintf(dev->name, sizeof(dev->name), "%.*s", (int)min(count, sizeof(dev->name) - 1), buf); return count; } static DEVICE_ATTR(name, S_IRUGO, show_name, store_name); ï¼æ³¨æï¼çæ£çå®ç°ä¸å 许ç¨æ·ç©ºé´è®¾ç½®è®¾å¤åãï¼ é¡¶å±ç®å½å¸å± ~~~~~~~~~~~~ sysfs ç®å½çå®ææ¾ç¤ºäºå æ ¸æ°æ®ç»æä¹é´çå ³ç³»ã é¡¶å± sysfs ç®å½å¦ä¸: block/ bus/ class/ dev/ devices/ firmware/ net/ fs/ devices/ å å«äºä¸ä¸ªè®¾å¤æ çæ件系ç»è¡¨ç¤ºãä»ç´æ¥æ å°äºå é¨çå æ ¸ 设å¤æ ï¼åæ äºè®¾å¤çå±æ¬¡ç»æã bus/ å å«äºå æ ¸ä¸åç§æ»çº¿ç±»åçå¹³é¢ç®å½å¸å±ãæ¯ä¸ªæ»çº¿ç®å½å å«ä¸¤ä¸ª åç®å½: devices/ drivers/ devices/ å å«äºç³»ç»ä¸åºç°çæ¯ä¸ªè®¾å¤ç符å·é¾æ¥ï¼ä»ä»¬æå root/ ä¸ç 设å¤ç®å½ã drivers/ å å«äºæ¯ä¸ªå·²ä¸ºç¹å®æ»çº¿ä¸ç设å¤èæè½½ç驱å¨ç¨åºçç®å½(è¿é åå®é©±å¨æ²¡æè·¨è¶å¤ä¸ªæ»çº¿ç±»å)ã fs/ å å«äºä¸ä¸ªä¸ºæ件系ç»è®¾ç«çç®å½ãç°å¨æ¯ä¸ªæ³è¦å¯¼åºå±æ§çæ件系ç»å¿ é¡» å¨ fs/ ä¸å建èªå·±çå±æ¬¡ç»æ(åè§Documentation/filesystems/fuse.rst)ã dev/ å å«ä¸¤ä¸ªåç®å½ï¼ char/ å block/ãå¨è¿ä¸¤ä¸ªåç®å½ä¸ï¼æ以 <major>:<minor> æ ¼å¼å½åç符å·é¾æ¥ãè¿äºç¬¦å·é¾æ¥æå sysfs ç®å½ ä¸ç¸åºç设å¤ã/sys/dev æä¾ä¸ä¸ªéè¿ä¸ä¸ª stat(2) æä½ç»æï¼æ¥æ¾ è®¾å¤ sysfs æ¥å£å¿«æ·çæ¹æ³ã æ´å¤æå ³ driver-model çç¹æ§ä¿¡æ¯å¯ä»¥å¨ Documentation/driver-api/driver-model/ ä¸æ¾å°ã TODO: å®æè¿ä¸èã å½åæ¥å£ ~~~~~~~~ 以ä¸çæ¥å£å±æ®éåå¨äºå½åçsysfsä¸: - è®¾å¤ (include/linux/device.h) ---------------------------------- ç»æä½: 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); }; 声æ: DEVICE_ATTR(_name, _mode, _show, _store); å¢/å å±æ§: int device_create_file(struct device *dev, const struct device_attribute * attr); void device_remove_file(struct device *dev, const struct device_attribute * attr); - æ»çº¿é©±å¨ç¨åº (include/linux/device.h) -------------------------------------- ç»æä½: struct bus_attribute { struct attribute attr; ssize_t (*show)(struct bus_type *, char * buf); ssize_t (*store)(struct bus_type *, const char * buf, size_t count); }; 声æ: BUS_ATTR(_name, _mode, _show, _store) å¢/å å±æ§: int bus_create_file(struct bus_type *, struct bus_attribute *); void bus_remove_file(struct bus_type *, struct bus_attribute *); - 设å¤é©±å¨ç¨åº (include/linux/device.h) ----------------------------------------- ç»æä½: struct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *, char * buf); ssize_t (*store)(struct device_driver *, const char * buf, size_t count); }; 声æ: DRIVER_ATTR(_name, _mode, _show, _store) å¢/å å±æ§ï¼ int driver_create_file(struct device_driver *, const struct driver_attribute *); void driver_remove_file(struct device_driver *, const struct driver_attribute *); ææ¡£ ~~~~ sysfs ç®å½ç»æ以åå ¶ä¸å å«çå±æ§å®ä¹äºä¸ä¸ªå æ ¸ä¸ç¨æ·ç©ºé´ä¹é´ç ABIã 对äºä»»ä½ ABIï¼å ¶èªèº«ç稳å®åéå½çææ¡£æ¯é常éè¦çãæææ°ç sysfs å±æ§å¿ é¡»å¨ Documentation/ABI ä¸æææ¡£ãè¯¦è§ Documentation/ABI/READMEã