Linux Device Drivers

使用/proc檔案系統

 

        /proc是核心模擬出來的軟體檔案系統,它是核心對於外界的資訊窗口。在/proc下的每一個檔案,各自連繫到核心裡的專屬函式,當user-process讀取/proc下的檔案時,對應的函式便會即時(real-time)產生檔案的“內容”。以/proc/modules為例,它總是會告訴你核心當已載入哪些模組。

 

        但現在的發展趨勢,已經不在鼓勵於/proc下添增檔案,因為在核心開發團隊的眼中,/proc檔案系統的發展已經失控了,逐漸遠離其原本的用途─提供系統行程的運作狀態。新寫的驅動程式,應該改用sysfs來提供狀態。相較之下,建立/proc檔案要稍微簡單些,而且也比較適合偵錯用途。

 

        /proc檔其實與一般檔案沒兩樣,同樣都是透過read()write()系統呼叫來存取它們。如果你的驅動程式只提供能應付read()系統呼叫的作業函式,對應的/proc檔就是唯讀的,除非另外提供能應付write()系統呼叫的作業函式。

 

        支援/proc檔案系統的函式,都定義於<linux/proc_fs.h>

       

以下提供簡單的範例,用以知道該如何去設定。

 

Makefile

CFILES=hello.c

APP=proc_hello

KERNELDIR ?= $(shell pwd)/../../..

PWD := $(shell pwd)

 

obj-$(CONFIG_EMIL_LDD) := $(APP).o

$(APP)-objs := $(CFILES:.c=.o)

 

default:

           $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

 

clean:

           $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

 

hello.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/proc_fs.h>

 

MODULE_LICENSE("Dual BSD/GPL");

 

struct proc_dir_entry *HELLO=NULL;

int hello_val=0;

 

static int HELLO_READ_PROC(char *page, char **start, off_t off, int count, int *eof, void *data)

{

     int len;

     len = sprintf(page, "%d\n", hello_val);

     if (len <= off+count) *eof = 1;

         *start = page + off;

     len -= off;

     if (len>count) len = count;

     if (len<0) len = 0;

         return len;

          

}

 

static int HELLO_WRITE_PROC( struct file *filp, const char *buff,unsigned long len1, void *data )

{

           char tmpbuf[64];

 

           if (buff && !copy_from_user(tmpbuf, buff, len1)) {

                     tmpbuf[len1-1] = '\0';

                     if ( tmpbuf[0] == '1' ) {

                                printk(KERN_INFO "HELLO is HIGH!\n");

                                hello_val = 1;

                     }

                     else {

                                printk(KERN_INFO "HELLO is LOW!\n");

                                hello_val = 0;       

                     }

           }        

          

           return len1;

}

 

 

 

static int __init_hello(void)

{

 

           HELLO = create_proc_entry("HELLO", 0, NULL);

   if (HELLO) {

                     printk(KERN_INFO "Create successful!!!\n");

       HELLO->read_proc = HELLO_READ_PROC;

       HELLO->write_proc = HELLO_WRITE_PROC;

   }               

           return 0;

}

 

static void __exit_hello(void)

{

           printk(KERN_INFO "Goodbye, cruel world\n");

}

 

module_init(__init_hello);

module_exit(__exit_hello);

 

Test…

# insmod proc_hello.ko

Create successful!!!

# cat /proc/HELLO

0

# echo 1 > /proc/HELLO

HELLO is HIGH!

# cat /proc/HELLO

1

# echo 0 > /proc/HELLO

HELLO is LOW!

# cat /proc/HELLO

0

 

 

 

創作者介紹

十年磨一劍

flykof 發表在 痞客邦 PIXNET 留言(0) 人氣()