小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

使用/proc文件系統(tǒng)來訪問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ū)分開來。現(xiàn)在可以加載或卸載這個(gè)模塊了,然后可以查看它的輸出。要加載這個(gè)模塊,請(qǐng) 使用 insmod 命令;反之,要卸載這個(gè)模塊,請(qǐng)使用 rmmod 命令。lsmod 可以顯示當(dāng)前加載的 LKM(參見清單 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 工具(或者通過 /proc 本身使用 cat /proc/kmsg 命令)。清單 6 給出了 dmesg 顯示的最后幾條消息。


清單 6. 查看來自 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í)離開這個(gè)簡(jiǎn)單的例子,來看幾個(gè)可以用來開發(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,說明在 create 時(shí)發(fā)生了錯(cuò)誤)。然后就可以使用這個(gè)返回的指針來配置這個(gè)虛擬文件的其他參數(shù),例如在對(duì)該文件執(zhí)行讀操作時(shí)應(yīng)該調(diào)用的函數(shù)。 create_proc_entry 的原型和 proc_dir_entry 結(jié)構(gòu)中的一部分如清單 7 所示。


清單 7. 用來管理 /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 命令來插入對(duì)這個(gè)虛擬文件進(jìn)行讀寫的函數(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àng)。這個(gè)函數(shù)的原型如下:

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




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

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

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

我們可以使用 read_proc 函數(shù)從一個(gè) /proc 項(xiàng)中讀取數(shù)據(jù)(從內(nèi)核空間到用戶空間)。這個(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)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(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)論公約

    類似文章 更多