日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 内核读写文件

發布時間:2023/12/10 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 内核读写文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Linux 內核讀寫文件

需要調試的驅動程中讀寫文件數據,比如說當驅動需要記錄的日志比較多的情況下,可以將printk()函數打印的信息都寫到文件做后續分析。在kernel中操作文件沒有標準庫可用,需要利用kernel的一些函數,這些函數主要有: filp_open() filp_close(), kernel_read(),kernel_write()這些函數在linux/fs.h和asm/uaccess.h頭文件中聲明。下面介紹主要步驟:

一、打開文件

filp_open()在kernel中可以打開文件,其原形如下:
strcut file* filp_open(const char* filename, int open_mode, int mode);
該函數返回strcut file*結構指針,供后繼函數操作使用,該返回值用IS_ERR()來檢驗其有效性。

參數說明:
filename: 表明要打開或創建文件的名稱(包括路徑部分)。在內核中打開的文件時需要注意打開的時機,很容易出現需要打開文件的驅動很早就加載并打開文件,但需要打開的文件所在設備還不有掛載到文件系統中,而導致打開失敗。

open_mode: 文件的打開方式,其取值與標準庫中的open相應參數類似,可以取O_CREAT,O_RDWR,O_RDONLY等。
mode: 創建文件時使用,設置創建文件的讀寫權限,其它情況可以匆略設為0

二、讀寫文件

kernel中文件的讀寫操作可以使用kernel_read()和kernel_write,均為內核導出函數內核函數原型為:

ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) {ssize_t ret;ret = rw_verify_area(READ, file, pos, count);if (ret)return ret;return __kernel_read(file, buf, count, pos); } EXPORT_SYMBOL(kernel_read);ssize_t kernel_write(struct file *file, const void *buf, size_t count,loff_t *pos) {ssize_t ret;ret = rw_verify_area(WRITE, file, pos, count);if (ret)return ret;file_start_write(file);ret = __kernel_write(file, buf, count, pos);file_end_write(file);return ret; } EXPORT_SYMBOL(kernel_write);

里面的參數和ring3讀寫是一樣的,拿到filp句柄之后就可以對文件進行讀寫操作了。

三、關閉文件

int filp_close(struct file*filp, fl_owner_t id);
該函數的使用很簡單,第二個參數一般傳遞NULL值,也有用current->files作為實參的。

使用以上函數的其它注意點:

  • 其實Linux Kernel組成員不贊成在kernel中獨立的讀寫文件(這樣做可能會影響到策略和安全問題),對內核需要的文件內容,最好由應用層配合完成。
  • 在可加載的kernel module中使用這種方式讀寫文件可能使模塊加載失敗,原因是內核可能沒有EXPORT你所需要的所有這些函數。
    3.分析以上某些函數的參數可以看出,這些函數的正確運行需要依賴于進程環境,因此,有些函數不能在中斷的handle或Kernel中不屬于任可進程的代碼中執行,否則可能出現崩潰,要避免這種情況發生,可以在kernel中創建內核線程,將這些函數放在線程環境下執行(創建內核線程的方式請參數kernel_thread()函數)。
  • 四、驅動代碼

    #include <asm/uaccess.h>#define MY_FILE "/tmp/log.txt"char buf[256]; loff_t pos = 0; struct file *filep = NULL;static int __init init(void) {printk("Hello, I'm the module that intends to write messages to file.\n");if(filep == NULL) {filep = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0644);}if (IS_ERR(filep)) {printk("Open file %s error\n", MY_FILE);return -1;}sprintf(buf,"%s\n", "This is test message!");memset(buf, 0, sizeof(buf));kernel_write(filep, buf, strlen(buf), &pos);memset(buf, 0, sizeof(buf));kernel_read(filep, buf, sizeof(buf), &pos);printk("Read buf -> %s\n", buf);return 0; }static void __exit fini(void) {printk("Kernel read/write exit\n");if(filep != NULL) {filp_close(filep, NULL);} }module_init(init); module_exit(fini); MODULE_LICENSE("GPL");

    注意事項:

    1、當驅動需要持續讀寫文件的話,需要考慮并發的情況,需要給buf的讀寫加鎖。

    查看log日志:

    curtis@curtis-Aspire-E5-471G:~/write_code/kernel_write$ dmesg [145731.662192] Hello, I'm the module that intends to write messages to file. [145731.662206] pos -> 0 [145731.662210] Read buf -> This is test message! curtis@curtis-Aspire-E5-471G:~/write_code/kernel_write$ cat /tmp/log.txt This is test message!

    參考鏈接:Linux內核中讀寫文件數據的方法_wxie的Linux人生-CSDN博客

    總結

    以上是生活随笔為你收集整理的Linux 内核读写文件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。