📄 00000002.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>如何在proc中加入一个档案 <BR> <BR>简介 <BR> <BR>PROC是一个特殊的档案系统,核心藉由这个档案系统可以提供应用程式一个 安全的界 <BR>面来存取某些特别的资料。例如实体记忆体的使用状况,或者是某 个行程开启了那些 <BR>档案。 <BR> <BR>当我们在核心中加入某个新的功能或是驱动程式後,可能会想提供一个方法 让应用程 <BR>式可以取得驱动程式中某些状态,一般来说这个功能可能需要经由写作 一个处理ioctl <BR>的呼叫来达成。这个界面对於一些比较『功能性』的资料可能是很 适合的,因为使用 <BR>者程式可能必须将这些资料读出後再做一定的处理。但对於一 些『资讯性』的资料, <BR>例如记忆体的使用状况,或者是驱动装置的统计资料等。 我们可能需要一个比较简单 <BR>易用的界面来取得它们。 <BR> <BR>PROC档案系统硬提供了我们这样的一个界面,我们可以用cat,more或任何的 文书编辑 <BR>程式来观看这些资料,例如来观看一个系统记忆体的使用状况可以用 <BR> <BR># cat /proc/meminfo <BR> total: used: free: shared: buffers: cached: <BR>Mem: 31698944 12648448 19050496 6770688 1581056 6815744 <BR>Swap: 0 0 0 <BR>MemTotal: 30956 kB <BR>MemFree: 18604 kB <BR>MemShared: 6612 kB <BR>Buffers: 1544 kB <BR>Cached: 6656 kB <BR>SwapTotal: 0 kB <BR>SwapFree: 0 kB <BR> <BR>目前在Linux中几乎所有的资料都可以经由PROC档案系统取得一些统计性甚或功能 性的 <BR>资料。有些驱动程式甚至允许经由PROC档案系统改变某个功能变数的值,例 如JAVA执 <BR>行档格式的驱动程式允许我们经由PROC档案系统设定JAVA直译程式的执 行档名称。 <BR> <BR>加入一个档案 <BR> <BR>如果你的驱动程式不是很复杂,那直接在PROC的根目录底下加入一个档案是比较简 单 <BR>的做法。下面举一个例子告诉大家这是多麻简单的一件事,但如果你想要提供比 较复 <BR>杂的资讯,後面会有更进一步的说明。 <BR> <BR>接下来我以一个很简单的例子做说明,在这个例子之中我们在PROC的根目录底 下加入 <BR>一个叫做test的档案,你可以用下面的命令读出其中的值。 <BR> <BR># cat /proc/test <BR>test status <BR> <BR>要达到这个目的我们必须改变三个档案,第一个是include/linux/proc_fs.h这个 档 <BR>案。 <BR> <BR>enum root_directory_inos { <BR> PROC_ROOT_INO = 1, <BR> PROC_LOADAVG, <BR> PROC_UPTIME, <BR> PROC_MEMINFO, <BR> PROC_KMSG, <BR> PROC_VERSION, <BR> PROC_CPUINFO, <BR> PROC_PCI, <BR> PROC_SELF, /* will change inode # */ <BR> PROC_NET, <BR> PROC_SCSI, <BR> PROC_MALLOC, <BR> PROC_KCORE, <BR> PROC_MODULES, <BR> PROC_STAT, <BR> PROC_DEVICES, <BR> PROC_INTERRUPTS, <BR> PROC_FILESYSTEMS, <BR> PROC_KSYMS, <BR> PROC_DMA, <BR> PROC_IOPORTS, <BR>#ifdef __SMP_PROF__ <BR> PROC_SMP_PROF, <BR>#endif <BR> PROC_PROFILE, /* whether enabled or not */ <BR> PROC_CMDLINE, <BR> PROC_SYS, <BR> PROC_MTAB, <BR> PROC_MD, <BR> PROC_RTC, <BR> PROC_LOCKS <BR>#ifdef CONFIG_TESTPROC <BR> ,PROC_TEST <BR>#endif <BR>}; <BR> <BR>在CONFIG_TESTPROC中的程式是我们新加入的部份,这个enumerate中宣告的是在PROC <BR>根目录下的一些档案代码。PROC是一个虚拟的档案系统,所以实际上的资料可能散见 <BR>於各驱动程式之中,而非在任何装置之上。那INODE中的位置栏位记载些什麽呢? 对 一 <BR>般的档案系统而言它们应该是装置的逻辑位置,而在PROC中记载的就是上列的数值 <BR>了。 <BR> <BR>PROC提供了一些其本的支援给驱动程式可以很容易的在档案系统中加入一个档案, 而 <BR>不必各自去做一些处理INODE的动作。在我们的要求中只需在根目录中加入一个叫 test <BR>的档案就可以了。所以我们可以直接修改root.c这个档案的proc_root_init这 个函 <BR>数,这个函数负责在根目录中加入各种不同驱动程式需要的档案。 <BR> <BR>#ifdef CONFIG_TESTPROC <BR> proc_register(&proc_root, &(struct proc_dir_entry) { <BR> PROC_TEST, 4, "test", <BR> S_IFREG | S_IRUGO, 1, 0, 0, <BR> }); <BR>#endif <BR> <BR>请注意"test"和PROC_TEST这二个引数,前者是在目录中的档案名称,而後者是这个 档 <BR>案所对映的代码。接下来我们会看到,这个代码被用来呼叫定义於驱动程式中的函 <BR>数。这个函数的功能是提供这个档案的内容。 <BR> <BR>到此PROC档案系统中的修改已经完成了,当核心被重新建立後已经可以在档案 系统中 <BR>看见test这个档案了。但这个档案的内容是空的,如何为它加入内容呢? 这 件工作应 <BR>该由驱动程式来做,但如何将二者连起来呢? 这就要靠刚才定义的PROC_TEST 这个代码 <BR>来完成,在array.c中的get_root_array是用来将代码转换为函式的位置, 它的程式为 <BR> <BR>static int get_root_array(char * page, int type, char **start, off_t offset, int length) <BR>{ <BR> switch (type) { <BR> case PROC_LOADAVG: <BR> return get_loadavg(page); <BR> <BR> case PROC_UPTIME: <BR> return get_uptime(page); <BR> <BR> case PROC_MEMINFO: <BR> return get_meminfo(page); <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -