日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

使用/proc文件系統(tǒng)來(lái)訪問(wèn)Linux內(nèi)核(下)

 todaytomo 2006-12-30
page 參數(shù)是這些數(shù)據(jù)寫(xiě)入到的位置,其中 count 定義了可以寫(xiě)入的最大字符數(shù)。在返回多頁(yè)數(shù)據(jù)(通常一頁(yè)是 4KB)時(shí),我們需要使用 start 和 off 參數(shù)。當(dāng)所有數(shù)據(jù)全部寫(xiě)入之后,就需要設(shè)置 eof(文件結(jié)束參數(shù))。與 write 類似,data 表示的也是私有數(shù)據(jù)。此處提供的 page 緩沖區(qū)在內(nèi)核空間中。因此,我們可以直接寫(xiě)入,而不用調(diào)用 copy_to_user。

其他有用的函數(shù)

  我們還可以使用 proc_mkdir、symlinks 以及 proc_symlink 在 /proc 文件系統(tǒng)中創(chuàng)建目錄。對(duì)于只需要一個(gè) read 函數(shù)的簡(jiǎn)單 /proc 項(xiàng)來(lái)說(shuō),可以使用 create_proc_read_entry,這會(huì)創(chuàng)建一個(gè) /proc 項(xiàng),并在一個(gè)調(diào)用中對(duì) read_proc 函數(shù)進(jìn)行初始化。這些函數(shù)的原型如清單 8 所示。


清單 8. 其他有用的 /proc 函數(shù)
代碼:
/* Create a directory in the proc filesystem */
struct proc_dir_entry *proc_mkdir( const char *name,
                                     struct proc_dir_entry *parent );

/* Create a symlink in the proc filesystem */
struct proc_dir_entry *proc_symlink( const char *name,
                                       struct proc_dir_entry *parent,
                                       const char *dest );

/* Create a proc_dir_entry with a read_proc_t in one call */
struct proc_dir_entry *create_proc_read_entry( const char *name,
                                                  mode_t mode,
                                                  struct proc_dir_entry *base,
                                                  read_proc_t *read_proc,
                                                  void *data );

/* Copy buffer to user-space from kernel-space */
unsigned long copy_to_user( void __user *to,
                              const void *from,
                              unsigned long n );

/* Copy buffer to kernel-space from user-space */
unsigned long copy_from_user( void *to,
                                const void __user *from,
                                unsigned long n );

/* Allocate a ‘virtually‘ contiguous block of memory */
void *vmalloc( unsigned long size );

/* Free a vmalloc‘d block of memory */
void vfree( void *addr );

/* Export a symbol to the kernel (make it visible to the kernel) */
EXPORT_SYMBOL( symbol );

/* Export all symbols in a file to the kernel (declare before module.h) */
EXPORT_SYMTAB
 



通過(guò) /proc 文件系統(tǒng)實(shí)現(xiàn)財(cái)富分發(fā)

下面是一個(gè)可以支持讀寫(xiě)的 LKM。這個(gè)簡(jiǎn)單的程序提供了一個(gè)財(cái)富甜點(diǎn)分發(fā)。在加載這個(gè)模塊之后,用戶就可以使用 echo 命令向其中導(dǎo)入文本財(cái)富,然后再使用 cat 命令逐一讀出。

  清單 9 給出了基本的模塊函數(shù)和變量。init 函數(shù)(init_fortune_module)負(fù)責(zé)使用 vmalloc 來(lái)為這個(gè)點(diǎn)心罐分配空間,然后使用 memset 將其全部清零。使用所分配并已經(jīng)清空的 cookie_pot 內(nèi)存,我們?cè)?/proc 中創(chuàng)建了一個(gè) proc_dir_entry 項(xiàng),并將其稱為 fortune。當(dāng) proc_entry 成功創(chuàng)建之后,對(duì)自己的本地變量和 proc_entry 結(jié)構(gòu)進(jìn)行了初始化。我們加載了 /proc read 和 write 函數(shù)(如清單 9 和清單 10 所示),并確定這個(gè)模塊的所有者。cleanup 函數(shù)簡(jiǎn)單地從 /proc 文件系統(tǒng)中刪除這一項(xiàng),然后釋放 cookie_pot 所占據(jù)的內(nèi)存。

  cookie_pot 是一個(gè)固定大小(4KB)的頁(yè),它使用兩個(gè)索引進(jìn)行管理。第一個(gè)是 cookie_index,標(biāo)識(shí)了要將下一個(gè) cookie 寫(xiě)到哪里去。變量 next_fortune 標(biāo)識(shí)了下一個(gè) cookie 應(yīng)該從哪里讀取以便進(jìn)行輸出。在所有的 fortune 項(xiàng)都讀取之后,我們簡(jiǎn)單地回到了 next_fortune。


清單 9. 模塊的 init/cleanup 和變量
代碼:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Fortune Cookie Kernel Module");
MODULE_AUTHOR("M. Tim Jones");

#define MAX_COOKIE_LENGTH       PAGE_SIZE
static struct proc_dir_entry *proc_entry;

static char *cookie_pot;  // Space for fortune strings
static int cookie_index;  // Index to write next fortune
static int next_fortune;  // Index to read next fortune


int init_fortune_module( void )
{
  int ret = 0;

  cookie_pot = (char *)vmalloc( MAX_COOKIE_LENGTH );

  if (!cookie_pot) {
    ret = -ENOMEM;
  } else {

    memset( cookie_pot, 0, MAX_COOKIE_LENGTH );

    proc_entry = create_proc_entry( "fortune", 0644, NULL );

    if (proc_entry == NULL) {

      ret = -ENOMEM;
      vfree(cookie_pot);
      printk(KERN_INFO "fortune: Couldn‘t create proc entry\n");

    } else {

      cookie_index = 0;
      next_fortune = 0;

      proc_entry->read_proc = fortune_read;
      proc_entry->write_proc = fortune_write;
      proc_entry->owner = THIS_MODULE;
      printk(KERN_INFO "fortune: Module loaded.\n");

    }

  }

  return ret;
}


void cleanup_fortune_module( void )
{
  remove_proc_entry("fortune", &proc_root);
  vfree(cookie_pot);
  printk(KERN_INFO "fortune: Module unloaded.\n");
}


module_init( init_fortune_module );
module_exit( cleanup_fortune_module );






  向這個(gè)罐中新寫(xiě)入一個(gè) cookie 非常簡(jiǎn)單(如清單 10 所示)。使用這個(gè)寫(xiě)入 cookie 的長(zhǎng)度,我們可以檢查是否有這么多空間可用。如果沒(méi)有,就返回 -ENOSPC,它會(huì)返回給用戶空間。否則,就說(shuō)明空間存在,我們使用 copy_from_user 將用戶緩沖區(qū)中的數(shù)據(jù)直接拷貝到 cookie_pot 中。然后增大 cookie_index(基于用戶緩沖區(qū)的長(zhǎng)度)并使用 NULL 來(lái)結(jié)束這個(gè)字符串。最后,返回實(shí)際寫(xiě)入 cookie_pot 的字符的個(gè)數(shù),它會(huì)返回到用戶進(jìn)程。


清單 10. 對(duì) fortune 進(jìn)行寫(xiě)入操作所使用的函數(shù)


  對(duì) fortune 進(jìn)行讀取也非常簡(jiǎn)單,如清單 11 所示。由于我們剛才寫(xiě)入數(shù)據(jù)的緩沖區(qū)(page)已經(jīng)在內(nèi)核空間中了,因此可以直接對(duì)其進(jìn)行操作,并使用 sprintf 來(lái)寫(xiě)入下一個(gè) fortune。如果 next_fortune 索引大于 cookie_index(要寫(xiě)入的下一個(gè)位置),那么我們就將 next_fortune 返回為 0,這是第一個(gè) fortune 的索引。在將這個(gè) fortune 寫(xiě)入用戶緩沖區(qū)之后,在 next_fortune 索引上增加剛才寫(xiě)入的 fortune 的長(zhǎng)度。這樣就變成了下一個(gè)可用 fortune 的索引。這個(gè) fortune 的長(zhǎng)度會(huì)被返回并傳遞給用戶。

清單 11. 對(duì) fortune 進(jìn)行讀取操作所使用的函數(shù)
代碼:
int fortune_read( char *page, char **start, off_t off,
                   int count, int *eof, void *data )
{
  int len;

  if (off > 0) {
    *eof = 1;
    return 0;
  }

  /* Wrap-around */
  if (next_fortune >= cookie_index) next_fortune = 0;

  len = sprintf(page, "%s\n", &cookie_pot[next_fortune]);

  next_fortune += len;

  return len;
}




從這個(gè)簡(jiǎn)單的例子中,我們可以看出通過(guò) /proc 文件系統(tǒng)與內(nèi)核進(jìn)行通信實(shí)際上是件非常簡(jiǎn)單的事情?,F(xiàn)在讓我們來(lái)看一下這個(gè) fortune 模塊的用法(參見(jiàn)清單 12)。


清單 12. 展示 fortune cookie LKM 的用法
代碼:
[root@plato]# insmod fortune.ko
[root@plato]# echo "Success is an individual proposition.  Thomas Watson" > /proc/fortune
[root@plato]# echo "If a man does his best, what else is there?  Gen. Patton" > /proc/fortune
[root@plato]# echo "Cats: All your base are belong to us.  Zero Wing" > /proc/fortune
[root@plato]# cat /proc/fortune
Success is an individual proposition.  Thomas Watson
[root@plato]# cat /proc/fortune
If a man does his best, what else is there?  General Patton
[root@plato]#




/proc 虛擬文件系統(tǒng)可以廣泛地用來(lái)報(bào)告內(nèi)核的信息,也可以用來(lái)進(jìn)行動(dòng)態(tài)配置。我們會(huì)發(fā)現(xiàn)它對(duì)于驅(qū)動(dòng)程序和模塊編程來(lái)說(shuō)都是非常完整的。在下面的 參考資料 中,我們可以學(xué)習(xí)到更多相關(guān)知識(shí)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多