---
# System prepended metadata

title: Chapter 7 - 9 ( /proc、sysfs、talking to device files)
tags: [Linux Kernel Module, Linux Kernel]

---

# 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)