Linux, 工作, 生活, 家人

Linux

Debugfs

以前都習慣用 printk 和 /proc 做輸入輸出的動作, 不過 debugfs 看起來是 User space 和 kernel space 交流更好的選擇.

先確認 Enable Kernel debugfs Function

Kernel hacking —>
-*- Debug Filesystem

先來個簡單的範例,
在你要 debug 的 modules 內, 加入 debugfs 的 include file

#include <linux/debugfs.h>

要將想要輸出的變數, 假設叫 pcie0_linked 輸出到 debugfs 上, 在 initial code 的地方加上
debugfs_create_u32(“pcie0_linked”, 0644, NULL, &pcie0_linked);

接下來就可以重開機了 load 新 kernel 了,

mount debugfs

$ mount -t debugfs debug /debugfs

或是寫在 /etc/fstab

debugfs /debugfs debugfs debug

這時就可以 ls /debugfs/ , 就會出現 pcie0_linked 的檔案.

$ cat /debugfs/pcie0_linked
1
$ echo 0 > /debugfs/pcie0_linked
$ cat /debugfs/pcie0_linked
0

像是 procfs 一樣, debugfs 也有 create directory 的 function, 以便讓變數可以在目錄內
我們小小改一下上面的程式, 加上 create_dir 的功能

struct dentry *pcie_dir;
pcie_dir = debugfs_create_dir(“pcie”,NULL);
if( pcie_dir != NULL ) {
debugfs_create_u32(“pcie0_linked”, 0644, pcie_dir, &pcie0_linked);
}

改了以上的輸出, 接下來就可以在 /debugfs 下, 看到多了一個 pcie 的目錄, 而 pcie0_linked 就在裡面.

如果想用 hex(16 進位), 可以改用 debugfs_create_x32.

proc file system 最棒的就是可以讀寫檔案了, 可以做更多的控制.
debugfs 也有一個 function 可以讓使用者做檔案讀寫, 這邊寫一個簡單的 sample.

多 include 一個 header

#include <linux/seq_file.h>

static int pcie_reg_open(struct seq_file *s, void *data)
{
seq_printf(s, “pcie0_link status : %s\n”, pcie0_linked == 1 ? “Enable”: “D
return 0;
}

static int pcie_single_open(struct inode *inode, struct file *file)
{
return single_open(file, pcie_reg_open, inode->i_private);
}
static ssize_t pcie_debug_write(struct file *file,
const char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[20];

if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
return -EFAULT;

printk(“%s: %s \n”,__FUNCTION__, buf);

return count;
}

static const struct file_operations pcie_ios_fops = {
.open = pcie_single_open,
.read = seq_read,
.write = pcie_debug_write,
.llseek = seq_lseek,
.release = single_release,

};
debugfs_create_file(“file”, 0644, pcie_dir, NULL, &pcie_ios_fops);

這樣

$ cat /debugs/pcie/file 會顯示
pcie0_link status : Enable

$ echo “richliu” > /debugfs/pcie/file 會顯示
pcie_debug_write: richliu

$

最後要介紹的是比較特別的一種格式 blob, 這是可以傳 binary 到 user space 的格式, blob 的 struct 是
struct debugfs_blob_wrapper {
void *data;
unsigned long size;
};

在剛剛的 Code 加上

static struct debugfs_blob_wrapper blob; –> 最好放 global.
char data[100];
sprintf(data, “Data Pointer is : %08X \n”, data);
blob.data = data;
blob.size = 100;
debugfs_create_blob(“blob”, S_IRUSR, pcie_dir, &blob);

在 Linux 下直接用 hexdump 去讀資料出來

$ hexdump /debugfs/pcie/blob -c
0000000 D a t a P o i n t e r i s
0000010 : C 4 0 5 C 1 6 0 \n \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0000060

請記得 Blob 這個檔案是 Read Only, 只能傳出, 不能傳入…

參考:
Debugfs
Debugfs 中譯版(好像是從匪區抄過來的?)

1 留言

  1. 匿名訪客

    good! from 匪区

回覆留言對象 取消回覆