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

分享

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

 todaytomo 2006-12-30
 清單 4. 編譯 LKM
代碼:
[root@plato]# make -C /usr/src/linux-`uname -r` SUBDIRS=$PWD modules
make: Entering directory `/usr/src/linux-2.6.11‘
  CC [M]  /root/projects/misc/module2.6/simple/simple-lkm.o
  Building modules, stage 2.
  MODPOST
  CC      /root/projects/misc/module2.6/simple/simple-lkm.mod.o
  LD [M]  /root/projects/misc/module2.6/simple/simple-lkm.ko
make: Leaving directory `/usr/src/linux-2.6.11‘
[root@plato]#




  結(jié)果會(huì)生成一個(gè) simple-lkm.ko 文件。這個(gè)新的命名約定可以幫助將這些內(nèi)核對(duì)象(LKM)與標(biāo)準(zhǔn)對(duì)象區(qū)分開(kāi)來(lái)?,F(xiàn)在可以加載或卸載這個(gè)模塊了,然后可以查看它的輸出。要加載這個(gè)模塊,請(qǐng) 使用 insmod 命令;反之,要卸載這個(gè)模塊,請(qǐng)使用 rmmod 命令。lsmod 可以顯示當(dāng)前加載的 LKM(參見(jiàn)清單 5)。

清單 5. 插入、檢查和刪除 LKM
代碼:
[root@plato]# insmod simple-lkm.ko
[root@plato]# lsmod
Module                  Size  Used by
simple_lkm              1536  0
autofs4                26244  0
video                  13956  0
button                  5264  0
battery                 7684  0
ac                      3716  0
yenta_socket           18952  3
rsrc_nonstatic          9472  1 yenta_socket
uhci_hcd               32144  0
i2c_piix4               7824  0
dm_mod                 56468  3
[root@plato]# rmmod simple-lkm
[root@plato]#




注意,內(nèi)核的輸出進(jìn)到了內(nèi)核回環(huán)緩沖區(qū)中,而不是打印到 stdout 上,這是因?yàn)?stdout 是進(jìn)程特有的環(huán)境。要查看內(nèi)核回環(huán)緩沖區(qū)中的消息,可以使用 dmesg 工具(或者通過(guò) /proc 本身使用 cat /proc/kmsg 命令)。清單 6 給出了 dmesg 顯示的最后幾條消息。


清單 6. 查看來(lái)自 LKM 的內(nèi)核輸出
代碼:
[root@plato]# dmesg | tail -5
cs: IO port probe 0xa00-0xaff: clean.
eth0: Link is down
eth0: Link is up, running at 100Mbit half-duplex
my_module_init called.  Module is now loaded.
my_module_cleanup called.  Module is now unloaded.
[root@plato]#




可以在內(nèi)核輸出中看到這個(gè)模塊的消息?,F(xiàn)在讓我們暫時(shí)離開(kāi)這個(gè)簡(jiǎn)單的例子,來(lái)看幾個(gè)可以用來(lái)開(kāi)發(fā)有用 LKM 的內(nèi)核 API。

集成到 /proc 文件系統(tǒng)中

內(nèi)核程序員可以使用的標(biāo)準(zhǔn) API,LKM 程序員也可以使用。LKM 甚至可以導(dǎo)出內(nèi)核使用的新變量和函數(shù)。有關(guān) API 的完整介紹已經(jīng)超出了本文的范圍,因此我們?cè)谶@里只是簡(jiǎn)單地介紹后面在展示一個(gè)更有用的 LKM 時(shí)所使用的幾個(gè)元素。

創(chuàng)建并刪除 /proc 項(xiàng)

要在 /proc 文件系統(tǒng)中創(chuàng)建一個(gè)虛擬文件,請(qǐng)使用 create_proc_entry 函數(shù)。這個(gè)函數(shù)可以接收一個(gè)文件名、一組權(quán)限和這個(gè)文件在 /proc 文件系統(tǒng)中出現(xiàn)的位置。create_proc_entry 的返回值是一個(gè) proc_dir_entry 指針(或者為 NULL,說(shuō)明在 create 時(shí)發(fā)生了錯(cuò)誤)。然后就可以使用這個(gè)返回的指針來(lái)配置這個(gè)虛擬文件的其他參數(shù),例如在對(duì)該文件執(zhí)行讀操作時(shí)應(yīng)該調(diào)用的函數(shù)。 create_proc_entry 的原型和 proc_dir_entry 結(jié)構(gòu)中的一部分如清單 7 所示。


清單 7. 用來(lái)管理 /proc 文件系統(tǒng)項(xiàng)的元素
代碼:
struct proc_dir_entry *create_proc_entry( const char *name, mode_t mode,
                                             struct proc_dir_entry *parent );

struct proc_dir_entry {
   const char *name;         // virtual file name
   mode_t mode;            // mode permissions
   uid_t uid;            // File‘s user id
   gid_t gid;            // File‘s group id
   struct inode_operations *proc_iops;   // Inode operations functions
   struct file_operations *proc_fops;   // File operations functions
   struct proc_dir_entry *parent;      // Parent directory
   ...
   read_proc_t *read_proc;         // /proc read function
   write_proc_t *write_proc;      // /proc write function
   void *data;            // Pointer to private data
   atomic_t count;            // use count
   ...
};

void remove_proc_entry( const char *name, struct proc_dir_entry *parent );




稍后我們就可以看到如何使用 read_proc 和 write_proc 命令來(lái)插入對(duì)這個(gè)虛擬文件進(jìn)行讀寫(xiě)的函數(shù)。

要從 /proc 中刪除一個(gè)文件,可以使用 remove_proc_entry 函數(shù)。要使用這個(gè)函數(shù),我們需要提供文件名字符串,以及這個(gè)文件在 /proc 文件系統(tǒng)中的位置(parent)。這個(gè)函數(shù)原型如清單 7 所示。

parent 參數(shù)可以為 NULL(表示 /proc 根目錄),也可以是很多其他值,這取決于我們希望將這個(gè)文件放到什么地方。表 1 列出了可以使用的其他一些父 proc_dir_entry,以及它們?cè)谶@個(gè)文件系統(tǒng)中的位置。


表 1. proc_dir_entry 快捷變量
代碼:
proc_dir_entry 在文件系統(tǒng)中的位置
proc_root_fs /proc
proc_net /proc/net
proc_bus /proc/bus
proc_root_driver /proc/driver


回調(diào)函數(shù)

我們可以使用 write_proc 函數(shù)向 /proc 中寫(xiě)入一項(xiàng)。這個(gè)函數(shù)的原型如下:

代碼:
  int mod_write( struct file *filp, const char __user *buff,
               unsigned long len, void *data );




  filp 參數(shù)實(shí)際上是一個(gè)打開(kāi)文件結(jié)構(gòu)(我們可以忽略這個(gè)參數(shù))。buff 參數(shù)是傳遞給您的字符串?dāng)?shù)據(jù)。緩沖區(qū)地址實(shí)際上是一個(gè)用戶(hù)空間的緩沖區(qū),因此我們不能直接讀取它。len 參數(shù)定義了在 buff 中有多少數(shù)據(jù)要被寫(xiě)入。data 參數(shù)是一個(gè)指向私有數(shù)據(jù)的指針(參見(jiàn) 清單 7)。在這個(gè)模塊中,我們聲明了一個(gè)這種類(lèi)型的函數(shù)來(lái)處理到達(dá)的數(shù)據(jù)。

Linux 提供了一組 API 來(lái)在用戶(hù)空間和內(nèi)核空間之間移動(dòng)數(shù)據(jù)。對(duì)于 write_proc 的情況來(lái)說(shuō),我們使用了 copy_from_user 函數(shù)來(lái)維護(hù)用戶(hù)空間的數(shù)據(jù)。

讀回調(diào)函數(shù)

我們可以使用 read_proc 函數(shù)從一個(gè) /proc 項(xiàng)中讀取數(shù)據(jù)(從內(nèi)核空間到用戶(hù)空間)。這個(gè)函數(shù)的原型如下:

代碼:
  int mod_read( char *page, char **start, off_t off,
              int count, int *eof, void *data );

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(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)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多