# Chapter 7 - 9 ( /proc、sysfs、talking to device files) ###### tags: `Linux Kernel Module` `Linux Kernel` ## 5. The /proc File System kenel 和 kenel module 可以透過 /proc 提供自身資訊資訊,它是一個 virtual file system (or pseudo file system is better ?) 因為它並非有硬體位置,只存在記憶體。 (根據 [document](https://man7.org/linux/man-pages/man5/proc.5.html) 他是 pseudo file system,jserv 提到 virtual 跟 pseudo 不一樣,但聽了之後還是有點不太懂,要再釐清一下) 7.1結 從7.2開始看。 ### 7.2 讀寫 /proc 檔案 ### 7.3 > file vs inode operations: file operations 是直接處理檔案本身的內容,而 inode 是處理如何存取到該檔案,例如: 創造一個指向檔案的連結。 ... ## 6. sysfs: Interacting with module [2] sysfs 的功用就是可以在 userspace 能跟 kernel 互動(讀取或設定 module 的 variables),目的是能夠 debug 或者是對於應用層是或腳本是一個 interface。 透過以下指令可以看到 sysfs 底下的檔案和目錄: ``` $ ls -l /sys ``` ... 這邊會使用到 **kobjects** [1],所以稍微介紹一下這個資料結構。 > 但根據 document [3],說這是設備模型最難懂的其中之一,ㄏㄏ...可能要辛苦的理解一陣子ㄅ 簡單的說,就是每個 kobject 都會在 /sys 底下以目錄的形式呈現,有個 reference count (被引用的次數),當變成 0 後就會釋放這個 Kobject。 > 並且還有 Kset和Ktype > * Ktype: 解釋困難,這邊暫不解釋 > * Kset: 是一個特殊的 ktype,所以也會在 sys 裡面以目錄形式出現,用來集合相似的 Ktype,可以是不同屬性或同屬性。 Kobject 由以下兩個檔案實現: **include/linux/kobject.h**、**lib/kobject.c**,長成以下這樣,更多細節就參考 [1],以下只是概述一下! ```c= struct kobject { const char* name; // kobject 的名稱,同時也是sysfs中的目錄名 struct list_head entry; //將Kobject加入到Kset中的list_head struct kobject* parent; //指向parent kobject,以此形成層次結構,在sys中表現為目錄結構 struct kset* kset; //該kobject屬於的Kset struct kobj_type* ktype; //該Kobject屬於的kobj_type,每個Kobject必須有一個ktype。 struct sysfs_dirent* sd;//該Kobject在sysfs中的表示 struct kref kref; //可用於原子操作的引用計數 unsigned int state_initialized: 1; //該Kobject是否已經初始化 unsigned int state_in_sysfs: 1; //該Kobject是否已在sysfs中呈現 unsigned int state_add_uevent_sent: 1; unsigned int state_remove_uevent_sent: 1; unsigned int uevent_suppress: 1; }; ``` ... 屬性可以為 kobjects 以一般檔案的形式存在在檔案系統中。(Attributes can be exported for kobjects in the form of regular files in the filesystem) Sysfs 將文件I/O操作轉發給為屬性定義的方法,提供一種讀寫 kernel 屬性的方法。 (Sysfs forwards file I/O operations to methods defined for the attributes, providing a means to read and write kernel attributes) ```c= struct attribute { const char *name; umode_t mode; #ifdef CONFIG_DEBUG_LOCK_ALLOC bool ignore_lockdep:1; struct lock_class_key *key; struct lock_class_key skey; #endif }; static inline int __must_check sysfs_create_file(struct kobject *kobj, const struct attribute *attr); static inline void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr); ``` hello-sysfs.c 範例程式碼中 [4],使用簡單的 kobject 在 sysfs 下創造一個名為 mymodule 的目錄,並且能夠跟他的 attributes 溝通。如以下指令。 > echo "32" > /sys/kernel/mymodule/myvariable 程式碼中也引用了 [include/linux/sysfs.h](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/sysfs.h) [5] 中的 __ATTR macro,能夠很容易定義屬性,更簡潔和可讀。 代碼解釋: 可以透過__ATTR,更方便設定 kobj_attribute 結構,也就是 kobject的屬性,再將他和 kobject 結構帶入到 sysfs_create_file,最後回傳整數表示成功或失敗。 ... ## 參考資料: [1] [Linux設備模型(2)_Kobject](https://cntofu.com/book/46/linux_driver/linuxshe_bei_mo578b28_2__kobject.md) [2] [sysfs(5) — Linux manual page](https://man7.org/linux/man-pages/man5/sysfs.5.html) [3] [Documentation/kobject.txt](https://lwn.net/Articles/266722/) [4] [hello-sysfs.c](https://github.com/Xueyi-Chen-David/Linux_kernel_module/blob/main/sysfs/hello-sysfs.c) [5] [kernel/git/stable/linux.git](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/sysfs.h) [6] [kobject.h](https://github.com/torvalds/linux/blob/master/include/linux/kobject.h) [7] [原始碼](https://github.com/sysprog21/lkmpg)