<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>richliu&#039;s blog &#187; debugfs</title>
	<atom:link href="http://blog.richliu.com/tag/debugfs/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.richliu.com</link>
	<description>Linux, 工作, 生活.</description>
	<lastBuildDate>Fri, 03 Sep 2010 11:41:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Debugfs</title>
		<link>http://blog.richliu.com/2010/01/20/843/</link>
		<comments>http://blog.richliu.com/2010/01/20/843/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 10:22:27 +0000</pubDate>
		<dc:creator>richliu</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[debugfs]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[linux kernel]]></category>

		<guid isPermaLink="false">http://blog.richliu.com/?p=843</guid>
		<description><![CDATA[以前都習慣用 printk 和 /proc 做輸入輸出的動作, 不過 debugfs 看起來是 User space 和 kernel space 交流更好的選擇.

先確認 Enable Kernel debugfs Function
Kernel hacking  &#8212;&#62;
-*- Debug Filesystem
先來個簡單的範例,
在你要 debug 的 modules 內, 加入 debugfs 的 include file
#include &#60;linux/debugfs.h&#62;
要將想要輸出的變數, 假設叫 pcie0_linked 輸出到 debugfs 上, 在 initial code 的地方加上
debugfs_create_u32(『pcie0_linked』, 0644, NULL, &#38;pcie0_linked);
接下來就可以重開機了 load 新 kernel 了,
mount debugfs
$ mount -t debugfs debug /debugfs
或是寫在 [...]]]></description>
			<content:encoded><![CDATA[<p>以前都習慣用 printk 和 /proc 做輸入輸出的動作, 不過 debugfs 看起來是 User space 和 kernel space 交流更好的選擇.<br />
<span id="more-843"></span></p>
<p>先確認 Enable Kernel debugfs Function</p>
<blockquote><p>Kernel hacking  &#8212;&gt;<br />
-*- Debug Filesystem</p></blockquote>
<p>先來個簡單的範例,<br />
在你要 debug 的 modules 內, 加入 debugfs 的 include file</p>
<blockquote><p>#include &lt;linux/debugfs.h&gt;</p></blockquote>
<p>要將想要輸出的變數, 假設叫 pcie0_linked 輸出到 debugfs 上, 在 initial code 的地方加上<br />
debugfs_create_u32(『pcie0_linked』, 0644, NULL, &amp;pcie0_linked);</p>
<p>接下來就可以重開機了 load 新 kernel 了,</p>
<p>mount debugfs</p>
<blockquote><p>$ mount -t debugfs debug /debugfs</p></blockquote>
<p>或是寫在 /etc/fstab</p>
<blockquote><p>debugfs    /debugfs    debugfs debug</p></blockquote>
<p>這時就可以 ls /debugfs/ , 就會出現 pcie0_linked 的檔案.</p>
<blockquote><p>$ cat /debugfs/pcie0_linked<br />
1<br />
$ echo 0 &gt; /debugfs/pcie0_linked<br />
$ cat /debugfs/pcie0_linked<br />
0</p></blockquote>
<p>像是 procfs 一樣, debugfs 也有 create directory 的 function, 以便讓變數可以在目錄內<br />
我們小小改一下上面的程式, 加上 create_dir 的功能</p>
<blockquote><p>struct dentry *pcie_dir;<br />
pcie_dir = debugfs_create_dir(『pcie』,NULL);<br />
if( pcie_dir != NULL ) {<br />
debugfs_create_u32(『pcie0_linked』, 0644, pcie_dir, &amp;pcie0_linked);<br />
}</p></blockquote>
<p>改了以上的輸出, 接下來就可以在 /debugfs 下, 看到多了一個 pcie 的目錄, 而 pcie0_linked 就在裡面.</p>
<p>如果想用 hex(16 進位), 可以改用 debugfs_create_x32.</p>
<p>proc file system 最棒的就是可以讀寫檔案了, 可以做更多的控制.<br />
debugfs 也有一個 function 可以讓使用者做檔案讀寫, 這邊寫一個簡單的 sample.</p>
<p>多 include 一個 header</p>
<blockquote><p>#include &lt;linux/seq_file.h&gt;</p>
<p>static int pcie_reg_open(struct seq_file *s, void *data)<br />
{<br />
seq_printf(s, 『pcie0_link status : %s\n』, pcie0_linked == 1 ? 『Enable』: 『D<br />
return 0;<br />
}</p>
<p>static int pcie_single_open(struct inode *inode, struct file *file)<br />
{<br />
return single_open(file, pcie_reg_open, inode-&gt;i_private);<br />
}<br />
static ssize_t pcie_debug_write(struct file *file,<br />
const char __user *userbuf,<br />
size_t count, loff_t *ppos)<br />
{<br />
char buf[20];</p>
<p>if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))<br />
return -EFAULT;</p>
<p>printk(『%s: %s \n』,__FUNCTION__, buf);</p>
<p>return count;<br />
}</p>
<p>static const struct file_operations pcie_ios_fops = {<br />
.open           = pcie_single_open,<br />
.read           = seq_read,<br />
.write          = pcie_debug_write,<br />
.llseek         = seq_lseek,<br />
.release        = single_release,</p>
<p>};<br />
debugfs_create_file(『file』, 0644, pcie_dir, NULL, &amp;pcie_ios_fops);</p></blockquote>
<p>這樣</p>
<blockquote><p>$ cat /debugs/pcie/file 會顯示<br />
pcie0_link status : Enable<br />
而<br />
$ echo 『richliu』 &gt; /debugfs/pcie/file 會顯示<br />
pcie_debug_write: richliu</p>
<p>$</p></blockquote>
<p>最後要介紹的是比較特別的一種格式 blob, 這是可以傳 binary 到 user space 的格式, blob 的 struct 是<br />
struct debugfs_blob_wrapper {<br />
void *data;<br />
unsigned long size;<br />
};</p>
<p>在剛剛的 Code 加上</p>
<blockquote><p>static struct debugfs_blob_wrapper blob; &#8211;&gt; 最好放  global.<br />
char data[100];<br />
sprintf(data, 『Data Pointer is : %08X \n』, data);<br />
blob.data = data;<br />
blob.size = 100;<br />
debugfs_create_blob(『blob』, S_IRUSR, pcie_dir, &amp;blob);</p></blockquote>
<p>在 Linux 下直接用 hexdump 去讀資料出來</p>
<blockquote><p>$ hexdump /debugfs/pcie/blob -c<br />
0000000   D   a   t   a       P   o   i   n   t   e   r       i   s<br />
0000010   :       C   4   0   5   C   1   6   0      \n  \0  \0  \0  \0<br />
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0<br />
*<br />
0000060</p></blockquote>
<p>請記得 Blob 這個檔案是 Read Only, 只能傳出, 不能傳入&#8230;</p>
<p>參考:<br />
<a href="http://lwn.net/Articles/115405/">Debugfs</a><br />
<a href="http://www.wretch.cc/blog/shinningball/33089435">Debugfs 中譯版(好像是從匪區抄過來的?)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.richliu.com/2010/01/20/843/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
