Linux內核開發-編寫一個proc文件

0.前言

上一章(點擊返回上一章)完成了一個內核模塊的編寫,實現了在內核運行時的動態加載和卸載。
在模塊的開發調測過程中或者模塊運行過程中,可能需要打印內核模塊的變量的值或者想要動態開關模塊的運行日志打印,那么就需要一個與內核交互的接口來實現這個目的。

1.什么是/proc文件

proc 文件系統是一個虛擬文件系統(類似的還有sys文件系統),對內核模塊中的全局變量,我們都可以為其生成一個/proc文件,在控制臺(即應用層)對其進行讀寫操作。

2.編寫一個/proc文件

需求:某個模塊在客戶現場出問題了,需要記錄內核模塊的日志用于記錄運行情況。
分析:在函數被調用不頻繁的情況下,可以直接使用printk來打印函數運行的分支情況。但是printk操作很消耗性能,在會產生大量打印的情況下,很可能會由于一直在print,cpu得不到調度而出發系統重啟。因此需要實現一個能根據需求動態調整打印的方式。

if (debug_enable)
{printk("[%s:%d], come here\n", __func__, __LINE__);
}

如上的代碼片段,我們只要能控制debug_enable這個變量就能控制日志打印的輸出。

2.1 代碼實現

2.1.1 km_proc文件

一般開發中,會有多個proc文件創建的需求,對于這些創建、讀、寫邏輯都統一放到一個文件中進行,本項目就放在km_proc.c和km_proc.h中,其中最重要的km_proc.c文件內容如下:

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/version.h>
#include "km_proc.h"/* 我們本次就是為此變量創建一個proc文件,并在控制臺讀寫它 */
extern int km_debug_enable;struct proc_dir_entry *km_proc_dir = NULL;         /* km模塊文件夾,用于存放模塊的所有proc文件 */
struct proc_dir_entry *km_debug_proc_file = NULL;  /* km_debug對應的proc文件 */static int km_debug_proc_show(struct seq_file* file, void* v)
{seq_printf(file, "km_debug_enable:%d\n", km_debug_enable);return 0;
}static int km_debug_proc_open(struct inode* inode, struct file* file)
{return single_open(file, km_debug_proc_show, NULL);
}static ssize_t km_debug_proc_write(struct file* file, const char __user *buffer, size_t count, loff_t *pos)
{char buf[2] = {0};if (count > 2){printk("error:please input 0 or 1");return -ENOSPC;}if (copy_from_user(buf, buffer, count)){return -EFAULT;}sscanf(buf, "%d", &km_debug_enable);printk("km_debug_enable:%d\n", km_debug_enable);return count;
}#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
static const struct proc_ops km_debug_proc_fops = {.proc_open = km_debug_proc_open,.proc_read = seq_read,.proc_release = single_release,.proc_write = km_debug_proc_write,
};
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
static const struct file_operations km_debug_proc_fops = {.owner = THIS_MODULE,.open = km_debug_proc_open,.read = seq_read,.release = single_release,.write = km_debug_proc_write,
};
#else
#error "Please make sure your kernel vision" /* proc文件相關結構體和接口與內核版本有關,需要單獨適配 */
#endifint km_init_proc(void)
{int ret = 0;/* 創建/proc/km文件夾 */km_proc_dir = proc_mkdir(KM_PROC_DIR, NULL);if (NULL == km_proc_dir) /* 創建失敗,退出 */{ret = -1;printk("proc_mkdir fail!\n");goto err;}/* 創建/proc/km/km_debug文件 */km_debug_proc_file = proc_create(KM_DEBUG_FILE, 0644, km_proc_dir, &km_debug_proc_fops);if (NULL == km_debug_proc_file){ret = -1;printk("create /proc/%s/%s fail!\n", KM_PROC_DIR, KM_DEBUG_FILE);goto err1;}printk("proc init success!\n");return ret;err1:/* 失敗,銷毀已經創建的文件 */remove_proc_entry(KM_PROC_DIR, NULL);
err:return ret;
}void km_exit_proc(void)
{/* 按反向順序一個個銷毀,即先銷毀文件、再銷毀文件夾 */if (km_debug_proc_file){remove_proc_entry(KM_DEBUG_FILE, km_proc_dir);km_debug_proc_file = NULL;}if (km_proc_dir){remove_proc_entry(KM_PROC_DIR, NULL);km_proc_dir = NULL;}printk("proc exit complete!\n");
}

其余變更見:github:kernel_module:為自己的內核模塊添加一個proc文件

2.2.2 編譯、運行、測試

# 源碼目錄下編譯
make# 插入模塊
insmod km.ko# 查看插入結果
lsmod

查看內核打印信息:

dmesg

可以看到:
在這里插入圖片描述
查看變量km_debug_enable的值:

cat /proc/km/km_debug

輸出:
在這里插入圖片描述
修改變量km_debug_enable的值:

sudo sh -c "echo 1 > /proc/km/km_debug"

在這里插入圖片描述
可以看到修改已經生效了。
注意:修改km_debug_enable值時,如果直接輸入echo,會提示權限不夠,原因可見:https://blog.csdn.net/change_can/article/details/115128218

3. 其他

在上面代碼中,可以看到有如下的條件編譯指令:

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)#else
#error "Please make sure your kernel vision" /* proc文件相關結構體和接口與內核版本有關,需要單獨適配 */
#endif

在實際開發中,一份代碼可能需要運行在各種機器上,機器使用的內核版本有差異,而不同的內核版本各個接口、結構體定義可能會有差異,這時候就可以用這種條件編譯指令通過判斷內核版本來編譯不同的代碼分支,減小代碼維護的復雜度。

4.下一章:待計劃

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35074.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35074.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35074.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

小盒子跑大模型!基于算能BM1684X+FPGA平臺實現大模型私有化部署

當前&#xff0c;在人工智能領域&#xff0c;大模型在豐富人工智能應用場景中扮演著重要的角色&#xff0c;經過不斷的探索&#xff0c;大模型進入到落地的階段。而大模型在落地過程中面臨兩大關鍵難題&#xff1a;對龐大計算資源的需求和對數據隱私與安全的考量。為應對這些挑…

springcloud-gateway include-expression 配置說明

在開發過程中遇到的一些配置問題&#xff0c;記錄下來以供參考 spring-gateway版本是2.2.9-release,使用的spring cloud dependence 是 Hoxton.SR12 在依賴eureka 服務發現并自動將發現服務器加入到router中的時候&#xff0c;需要指定對應的服務進行添加&#xff0c;根據文檔…

postman國內外競爭者及使用詳解分析

一、postman簡介 Postman 是一款廣泛使用的 API 開發和測試工具&#xff0c;適用于開發人員和測試人員。它提供了一個直觀的界面&#xff0c;用于發送 HTTP 請求、查看響應、創建和管理 API 測試用例&#xff0c;以及自動化 API 測試工作流程。以下是 Postman 的主要功能和特點…

linux的CP指令

實現 CP 指令 src 源文件 des 目標文件 執行流程&#xff1a; 打開源文件&#xff08; src &#xff09; open 打開目標文件&#xff08; des &#xff09; open 寫入目標文件 write 讀取 src 文件到緩存數組 read 關閉目標文件和源文件 close ./a.out src.c de…

開源網安參與編制的《代碼大模型安全風險防范能力要求及評估方法》正式發布

?代碼大模型在代碼生成、代碼翻譯、代碼補全、錯誤定位與修復、自動化測試等方面為研發人員帶來了極大便利的同時&#xff0c;也帶來了對安全風險防范能力的挑戰。基于此&#xff0c;中國信通院依托中國人工智能產業發展聯盟&#xff08;AIIA&#xff09;&#xff0c;聯合開源…

chmod,chown命令

一.chmod命令 1.chmod命令的作用 我們使用chmod命令來修改文件和文件夾的權限信息&#xff08;只有文件和文件夾的所屬用戶和root用戶可以修改該文件或文件夾的權限信息&#xff09; 2.chmod命令的語法 chmod [-R] 我們將要賦予用戶/用戶組/其他用戶的權限 要修改的文件/文件…

SpringBoot實現定時任務的動態停止和更新

目錄 定時任務管理器定時任務的任務接口定時任務和定時任務結果的緩存對象定時任務使用姿勢 定時任務管理器 負責啟動一個定時任務、停止一個定時任務、更新一個定時任務 /*** 定時任務管理器* 1、創建并啟動一個定時任務* 2、停止一個定時任務* 3、更新一個定時任務*/ publi…

Mybatis-plus學習|性能分析插件、條件構造器、代碼自動生成器

性能分析插件 我們在平時的開發中&#xff0c;會遇到一些慢sql。測試!druid…. MP也提供性能分析插件&#xff0c;如果超過這個時間就停止運行! 1、導入插件 該插件只允許在開發和測試環境中使用&#xff0c;故先設置開發環境為開發模式 在MP配置類中注冊這個插件&#xff0…

【Python機器學習】數據表示和特征工程的一些概念

對于由浮點數組成的二維數據&#xff0c;其中每一列是描述數據點的連續特征。 對于很多應用來說&#xff0c;數據的收集方式并不是這樣&#xff0c;一種特別常見的特征類型就是分類特征&#xff0c;也叫離散特征&#xff0c;這種特征通常不是說數值。 分類特征和連續特征之間…

Python:淺談迭代器、生成器與協程的演化路徑

“人生苦短&#xff0c;我用Python”&#xff0c;雖然說大量數學和統計分析庫是一個重要優勢&#xff0c;但是歸根結底&#xff0c;Python的最大優勢就是三點&#xff1a; 但是通常一般來講&#xff0c;當扯到并發的時候&#xff0c;無論是多服務器、多進程、多線程、還是協程&…

C# SocketUDP服務器,組播

SocketUDP 自己即是服務器又是客戶端 &#xff0c;在發消息只需要改成對方ip和端口號即可 前提對方必須開啟服務器 socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.107.72"), 8080)); 控件&#xff1a;Button,TextBox,RichTextBox 打開自己服務器 public…

【操作系統】信號處理與阻塞函數|時序競態問題

&#x1f525;博客主頁&#xff1a; 我要成為C領域大神&#x1f3a5;系列專欄&#xff1a;【C核心編程】 【計算機網絡】 【Linux編程】 【操作系統】 ??感謝大家點贊&#x1f44d;收藏?評論?? 本博客致力于知識分享&#xff0c;與更多的人進行學習交流 ? 關于阻塞函數和…

Windows環境部署MySQL_8.4.0 LTS的部署安裝、驗證連接以及卸載全過程實操手冊

前言&#xff1a; 什么是 MySQL MySQL 是一個關系型數據庫管理系統&#xff0c;由瑞典 MySQL AB 公司開發&#xff0c;目前屬于Oracle 公司。MySQL 是一種關系型數據庫管理系統&#xff0c;關系型數據庫將數據保存在不同的表中&#xff0c;而不是將所有數據放在一個大倉庫內&am…

secureCRT中使用python腳本自動化測試vela設備

利用vela設備自帶的wapi命令行&#xff0c;重復執行聯網斷網的命令&#xff0c;測試系統穩定性。 實現如下&#xff0c; # $language "python" # $interface "1.0"# This automatically generated script may need to be # edited in order to work co…

8.12 矢量圖層面要素單一符號使用七(隨機標記填充)

文章目錄 前言隨機標記填充&#xff08;Random Marker Fill&#xff09;QGis設置面符號為隨機標記填充&#xff08;Random Marker Fill&#xff09;二次開發代碼實現隨機標記填充&#xff08;Random Marker Fill&#xff09; 總結 前言 本章介紹矢量圖層線要素單一符號中使用隨…

分班查詢怎么發布?

在現代教育環境中&#xff0c;傳統的學生分班通知方式可能顯得有些過時和低效。通常&#xff0c;這些方式依賴于紙質通知單&#xff0c;這不僅需要大量的物理資源進行打印和分發&#xff0c;而且容易出錯&#xff0c;如丟失、錯誤分發或延遲。 幸運的是&#xff0c;現在有了更高…

掌握Perl并發:線程與進程編程全攻略

掌握Perl并發&#xff1a;線程與進程編程全攻略 引言 Perl作為一種功能強大的編程語言&#xff0c;提供了豐富的并發編程手段。無論是通過threads模塊實現的線程&#xff0c;還是通過fork系統調用產生的進程&#xff0c;Perl都能幫助開發者高效地處理多任務。本文將深入探討如…

解釋Java的垃圾回收機制以及垃圾回收器的工作原理。

Java的垃圾回收機制&#xff08;Garbage Collection&#xff0c;GC&#xff09;是Java虛擬機&#xff08;JVM&#xff09;的一個重要組成部分&#xff0c;它負責自動管理內存&#xff0c;確保內存泄漏和內存溢出錯誤不會發生。垃圾回收器&#xff08;Garbage Collector&#xf…

心靈館咨詢系統小程序心理咨詢平臺聊天咨詢

心靈館咨詢系統小程序&#xff1a;解鎖你的心靈密碼 &#x1f496; 心靈之旅的導航者 在繁忙的現代生活中&#xff0c;我們時常會面臨各種壓力與困惑。心靈館咨詢系統小程序&#xff0c;如同一位貼心的導航者&#xff0c;引領我們探索內心的世界&#xff0c;尋找真正的自我。 …