.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_CN.rst :Original: :doc:`../../../filesystems/debugfs` ======= Debugfs ======= è¯è :: ä¸æçç»´æ¤è ï¼ ç½æ¥æ Chucheng Luo <luochucheng@vivo.com> ä¸æçç¿»è¯è ï¼ ç½æ¥æ Chucheng Luo <luochucheng@vivo.com> ä¸æçæ ¡è¯è : ç½æ¥æ Chucheng Luo <luochucheng@vivo.com> çæææ2020 ç½æ¥æ <luochucheng@vivo.com> Debugfsæ¯å æ ¸å¼å人åå¨ç¨æ·ç©ºé´è·åä¿¡æ¯çç®åæ¹æ³ãä¸/procä¸åï¼procåªæä¾è¿ç¨ ä¿¡æ¯ãä¹ä¸åsysfs,å ·æä¸¥æ ¼çâæ¯ä¸ªæ件ä¸ä¸ªå¼âçè§åãdebugfsæ ¹æ¬æ²¡æè§å,å¼å 人åå¯ä»¥å¨è¿éæ¾ç½®ä»ä»¬æ³è¦çä»»ä½ä¿¡æ¯ãdebugfsæ件系ç»ä¹ä¸è½ç¨ä½ç¨³å®çABIæ¥å£ã ä»ç论ä¸è®²ï¼debugfs导åºæ件çæ¶å没æä»»ä½çº¦æãä½æ¯[1]å®é æ åµå¹¶ä¸æ»æ¯é£ä¹ ç®åãå³ä½¿æ¯debugfsæ¥å£ï¼ä¹æå¥½æ ¹æ®éè¦è¿è¡è®¾è®¡,并尽éä¿ææ¥å£ä¸åã Debugfsé常使ç¨ä»¥ä¸å½ä»¤å®è£ :: mount -t debugfs none /sys/kernel/debug ï¼æçæç/etc/fstabè¡ï¼ã debugfsæ ¹ç®å½é»è®¤ä» å¯ç±rootç¨æ·è®¿é®ãè¦æ´æ¹å¯¹æ件æ ç访é®ï¼è¯·ä½¿ç¨â uidâï¼â gidâ åâ modeâæè½½é项ã请注æï¼debugfs APIä» æç §GPLå议导åºå°æ¨¡åã 使ç¨debugfsç代ç åºå å«<linux/debugfs.h>ãç¶åï¼é¦å æ¯å建è³å°ä¸ä¸ªç®å½æ¥ä¿å ä¸ç»debugfsæ件:: struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); å¦ææåï¼æ¤è°ç¨å°å¨æå®çç¶ç®å½ä¸å建ä¸ä¸ªå为nameçç®å½ãå¦æparentåæ°ä¸ºç©ºï¼ åä¼å¨debugfsæ ¹ç®å½ä¸å建ãå建ç®å½æåæ¶ï¼è¿åå¼æ¯ä¸ä¸ªæådentryç»æä½çæéã 该dentryç»æä½çæéå¯ç¨äºå¨ç®å½ä¸å建æ件ï¼ä»¥åæåå°å ¶æ¸ çå¹²åï¼ãERR_PTR ï¼-ERRORï¼è¿åå¼è¡¨æåºéãå¦æè¿åERR_PTRï¼-ENODEVï¼ï¼å表æå æ ¸æ¯å¨æ²¡ædebugfs æ¯æçæ åµä¸æ建çï¼å¹¶ä¸ä¸è¿°å½æ°é½ä¸ä¼èµ·ä½ç¨ã å¨debugfsç®å½ä¸å建æ件çæéç¨æ¹æ³æ¯:: struct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); å¨è¿éï¼nameæ¯è¦å建çæ件çå称ï¼modeæè¿°äºè®¿é®æ件åºå ·æçæéï¼parentæå åºè¯¥ä¿åæ件çç®å½ï¼dataå°åå¨å¨äº§ççinodeç»æä½çi_privateå段ä¸ï¼èfopsæ¯ ä¸ç»æ件æä½å½æ°ï¼è¿äºå½æ°ä¸å®ç°æ件æä½çå ·ä½è¡ä¸ºãè³å°ï¼readï¼ï¼å/æ writeï¼ï¼æä½åºæä¾ï¼å ¶ä»å¯ä»¥æ ¹æ®éè¦å æ¬å¨å ãåæ ·çï¼è¿åå¼å°æ¯æåå建æ件 çdentryæéï¼é误æ¶è¿åERR_PTRï¼-ERRORï¼ï¼ç³»ç»ä¸æ¯ædebugfsæ¶è¿åå¼ä¸ºERR_PTR ï¼-ENODEVï¼ãå建ä¸ä¸ªåå§å¤§å°çæ件ï¼å¯ä»¥ä½¿ç¨ä»¥ä¸å½æ°ä»£æ¿:: struct dentry *debugfs_create_file_size(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops, loff_t file_size); file_sizeæ¯åå§æ件大å°ãå ¶ä»åæ°è·å½æ°debugfs_create_fileçç¸åã å¨è®¸å¤æ åµä¸ï¼æ²¡å¿ è¦èªå·±å»å建ä¸ç»æ件æä½;对äºä¸äºç®åçæ åµ,debugfs代ç æä¾ äºè®¸å¤å¸®å©å½æ°ãå å«å个æ´æ°å¼çæ件å¯ä»¥ä½¿ç¨ä»¥ä¸ä»»ä½ä¸é¡¹å建:: void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value); è¿äºæ件æ¯æ读åååå ¥ç»å®å¼ãå¦ææ个æ件ä¸æ¯æåå ¥ï¼åªéæ ¹æ®éè¦è®¾ç½®mode åæ°ä½ãè¿äºæ件ä¸çå¼ä»¥åè¿å¶è¡¨ç¤ºï¼å¦æéè¦ä½¿ç¨åå è¿å¶ï¼å¯ä»¥ä½¿ç¨ä»¥ä¸å½æ° æ¿ä»£:: void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); è¿äºåè½åªæå¨å¼å人åç¥é导åºå¼ç大å°çæ¶åææç¨ãæäºæ°æ®ç±»åå¨ä¸åçæ¶æä¸ æä¸åç宽度ï¼è¿æ ·ä¼ä½¿æ åµåå¾æäºå¤æãå¨è¿ç§ç¹æ®æ åµä¸å¯ä»¥ä½¿ç¨ä»¥ä¸å½æ°:: void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value); ä¸åºææï¼æ¤å½æ°å°å建ä¸ä¸ªdebugfsæ件æ¥è¡¨ç¤ºç±»å为size_tçåéã åæ ·å°ï¼ä¹æ导åºæ 符å·é¿æ´ååéçå½æ°ï¼åå«ä»¥åè¿å¶ååå è¿å¶è¡¨ç¤ºå¦ä¸:: struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); void debugfs_create_xul(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); å¸å°å¼å¯ä»¥éè¿ä»¥ä¸æ¹å¼æ¾ç½®å¨debugfsä¸:: struct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value); 读åç»ææ件å°äº§çYï¼å¯¹äºéé¶å¼ï¼æNï¼åè·æ¢è¡ç¬¦åå ¥çæ¶åï¼å®åªæ¥å大åæå°å å¼æ1æ0ãä»»ä½å ¶ä»è¾å ¥å°è¢«å¿½ç¥ã åæ ·ï¼atomic_tç±»åçå¼ä¹å¯ä»¥æ¾ç½®å¨debugfsä¸:: void debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value) 读åæ¤æ件å°è·å¾atomic_tå¼ï¼åå ¥æ¤æ件å°è®¾ç½®atomic_tå¼ã å¦ä¸ä¸ªéæ©æ¯éè¿ä»¥ä¸ç»æä½åå½æ°å¯¼åºä¸ä¸ªä»»æäºè¿å¶æ°æ®å:: struct debugfs_blob_wrapper { void *data; unsigned long size; }; struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob); 读åæ¤æ件å°è¿åç±æéæådebugfs_blob_wrapperç»æä½çæ°æ®ãä¸äºé©±å¨ä½¿ç¨âblobsâ ä½ä¸ºä¸ç§è¿åå è¡ï¼éæï¼æ ¼å¼åææ¬çç®åæ¹æ³ãè¿ä¸ªå½æ°å¯ç¨äºå¯¼åºäºè¿å¶ä¿¡æ¯ï¼ä½ ä¼¼ä¹å¨ä¸»çº¿ä¸æ²¡æä»»ä½ä»£ç è¿æ ·åã请注æï¼ä½¿ç¨debugfs_create_blobï¼ï¼å½ä»¤å建ç æææ件æ¯åªè¯»çã å¦ææ¨è¦è½¬å¨ä¸ä¸ªå¯åå¨åï¼å¨å¼åè¿ç¨ä¸ç»å¸¸ä¼è¿ä¹åï¼ä½æ¯è¿æ ·çè°è¯ä»£ç å¾å°ä¸ä¼ å°ä¸»çº¿ä¸ãDebugfsæä¾ä¸¤ä¸ªå½æ°ï¼ä¸ä¸ªç¨äºåå»ºä» å¯åå¨æ件ï¼å¦ä¸ä¸ªæä¸ä¸ªå¯åå¨å æå ¥ä¸ä¸ªé¡ºåºæ件ä¸:: struct debugfs_reg32 { char *name; unsigned long offset; }; struct debugfs_regset32 { struct debugfs_reg32 *regs; int nregs; void __iomem *base; }; struct dentry *debugfs_create_regset32(const char *name, umode_t mode, struct dentry *parent, struct debugfs_regset32 *regset); void debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix); âbaseâåæ°å¯è½ä¸º0ï¼ä½æ¨å¯è½éè¦ä½¿ç¨__stringifyæ建reg32æ°ç»ï¼å®é ä¸æ许å¤å¯åå¨ å称ï¼å®ï¼æ¯å¯åå¨åå¨åºåä¸çåèå移éã å¦æè¦å¨debugfsä¸è½¬å¨u32æ°ç»ï¼å¯ä»¥ä½¿ç¨ä»¥ä¸å½æ°å建æ件:: void debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, u32 *array, u32 elements); âarrayâåæ°æä¾æ°æ®ï¼èâelementsâåæ°ä¸ºæ°ç»ä¸å ç´ çæ°éã注æï¼æ°ç»å建åï¼æ°ç» 大å°æ æ³æ´æ¹ã æä¸ä¸ªå½æ°æ¥å建ä¸è®¾å¤ç¸å ³çseq_file:: struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, struct dentry *parent, int (*read_fn)(struct seq_file *s, void *data)); âdevâåæ°æ¯ä¸æ¤debugfsæ件ç¸å ³ç设å¤ï¼å¹¶ä¸âread_fnâæ¯ä¸ä¸ªå½æ°æéï¼è¿ä¸ªå½æ°å¨ æå°seq_fileå 容çæ¶å被åè°ã è¿æä¸äºå ¶ä»çé¢åç®å½çå½æ°:: struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, struct dentry *new_dir, const char *new_name); struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, const char *target); è°ç¨debugfs_rename()å°ä¸ºç°æçdebugfsæ件éå½åï¼å¯è½åæ¶åæ¢ç®å½ã new_name å½æ°è°ç¨ä¹åä¸è½åå¨ï¼è¿åå¼ä¸ºold_dentryï¼å ¶ä¸å å«æ´æ°çä¿¡æ¯ãå¯ä»¥ä½¿ç¨ debugfs_create_symlinkï¼ï¼å建符å·é¾æ¥ã æædebugfsç¨æ·å¿ é¡»èèçä¸ä»¶äºæ¯ï¼ debugfsä¸ä¼èªå¨æ¸ é¤å¨å ¶ä¸å建çä»»ä½ç®å½ãå¦æä¸ä¸ªæ¨¡åå¨ä¸æ¾å¼å é¤debugfsç®å½ç æ åµä¸å¸è½½æ¨¡åï¼ç»æå°ä¼éçå¾å¤éæéï¼ä»è导è´ç³»ç»ä¸ç¨³å®ãå æ¤ï¼æædebugfs ç¨æ·-è³å°æ¯é£äºå¯ä»¥ä½ä¸ºæ¨¡åæ建çç¨æ·-å¿ é¡»å模åå¸è½½çæ¶ååå¤å é¤å¨æ¤å建ç æææ件åç®å½ãä¸ä»½æ件å¯ä»¥éè¿ä»¥ä¸æ¹å¼å é¤:: void debugfs_remove(struct dentry *dentry); dentryå¼å¯ä»¥ä¸ºNULLæé误å¼ï¼å¨è¿ç§æ åµä¸ï¼ä¸ä¼æä»»ä½æ件被å é¤ã å¾ä¹ 以åï¼å æ ¸å¼åè 使ç¨debugfsæ¶éè¦è®°å½ä»ä»¬å建çæ¯ä¸ªdentryæéï¼ä»¥ä¾¿æåææ æ件é½å¯ä»¥è¢«æ¸ çæãä½æ¯ï¼ç°å¨debugfsç¨æ·è½è°ç¨ä»¥ä¸å½æ°éå½æ¸ é¤ä¹åå建çæ件:: void debugfs_remove_recursive(struct dentry *dentry); å¦æå°å¯¹åºé¡¶å±ç®å½çdentryä¼ éç»ä»¥ä¸å½æ°ï¼å该ç®å½ä¸çæ´ä¸ªå±æ¬¡ç»æå°ä¼è¢«å é¤ã 注éï¼ [1] http://lwn.net/Articles/309298/