當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式大雜燴
[導(dǎo)讀]從內(nèi)核的角度看,內(nèi)核是通過怎么樣的方式把這些信息暴露給用戶呢?這篇筆記我們來學(xué)習(xí)一下!

點(diǎn)擊上方「嵌入式大雜燴」,「星標(biāo)公眾號(hào)」第一時(shí)間查看嵌入式筆記!

上一篇:《文件系統(tǒng)有很多,但這幾個(gè)最為重要》介紹了procfs(進(jìn)程文件系統(tǒng)的縮寫),包含一個(gè)偽文件系統(tǒng)(啟動(dòng)時(shí)動(dòng)態(tài)生成的文件系統(tǒng)),用于通過內(nèi)核訪問進(jìn)程信息。這個(gè)文件系統(tǒng)通常被掛載到 /proc 目錄, /proc中不僅僅放了進(jìn)程相關(guān)信息,也存放著很多系統(tǒng)相關(guān)的信息。

這些信息都是內(nèi)核開放給用戶的,/proc 就是用戶與內(nèi)核直接交互的一個(gè)入口。從內(nèi)核的角度看,內(nèi)核是通過怎么樣的方式把這些信息暴露給用戶呢?這篇筆記我們來學(xué)習(xí)一下:

內(nèi)核創(chuàng)建proc節(jié)點(diǎn)的例子

我們先來看一個(gè)例子(Linux-4.9.88\fs\proc\cpuinfo.c):

這就是創(chuàng)建/proc下cpuinfo這個(gè)節(jié)點(diǎn)的相關(guān)代碼,有了cpuinfo節(jié)點(diǎn),我們就可以通過訪問這個(gè)節(jié)點(diǎn)來得到cpu的一些信息:

從以上代碼中,我們可以看到,其用proc_create這個(gè)函數(shù)來創(chuàng)造相關(guān)節(jié)點(diǎn)的,這個(gè)函數(shù)是一個(gè)內(nèi)聯(lián)函數(shù),存放在Linux-4.9.88\include\linux\proc_fs.h下:

static?inline?struct?proc_dir_entry?*proc_create(
?const?char?*name,?umode_t?mode,?struct?proc_dir_entry?*parent,
?const?struct?file_operations?*proc_fops)

{
?return?proc_create_data(name,?mode,?parent,?proc_fops,?NULL);
}

知識(shí)點(diǎn):什么是內(nèi)聯(lián)函數(shù)?

內(nèi)聯(lián)函數(shù)簡(jiǎn)單來說就是編譯器將指定的函數(shù)體插入并取代每一處調(diào)用該函數(shù)的地方上下文,從而節(jié)省了每次調(diào)用函數(shù)帶來的額外時(shí)間開支。

一般用于能夠快速執(zhí)行的函數(shù),因?yàn)樵谶@種情況下函數(shù)調(diào)用的時(shí)間消耗顯得更為突出。這種方法對(duì)于很小的函數(shù)也有空間上的益處,并且它也使得一些其他的優(yōu)化成為可能。

這么一看,似乎與宏有點(diǎn)相似?與宏有何不同?

  • 宏調(diào)用并不執(zhí)行類型檢查,甚至連正常參數(shù)也不檢查,但是函數(shù)調(diào)用卻要檢查。
  • C語(yǔ)言的宏使用的是文本替換,可能導(dǎo)致無法預(yù)料的后果,因?yàn)樾枰匦掠?jì)算參數(shù)和操作順序。
  • 在宏中的編譯錯(cuò)誤很難發(fā)現(xiàn),因?yàn)樗鼈円玫氖菙U(kuò)展的代碼,而不是程序員鍵入的。
  • 許多結(jié)構(gòu)體使用宏或者使用不同的語(yǔ)法來表達(dá)很難理解。內(nèi)聯(lián)函數(shù)使用與普通函數(shù)相同的語(yǔ)言,可以隨意的內(nèi)聯(lián)和不內(nèi)聯(lián)。
  • 內(nèi)聯(lián)代碼的調(diào)試信息通常比擴(kuò)展的宏代碼更有用。

以上介紹摘選自百度百科,關(guān)于內(nèi)聯(lián)更詳細(xì)的介紹可自行查閱。

接著上面,proc_create函數(shù)有四個(gè)參數(shù),分別為:

name:要?jiǎng)?chuàng)建的文件名。

mode:文件的訪問權(quán)限。

parent:父文件夾的proc_dir_entry指針。

proc_fops:改文件的操作函數(shù)。

看到這個(gè)函數(shù),有沒有感到很熟悉?我們?cè)趯W(xué)習(xí)驅(qū)動(dòng)基礎(chǔ)的時(shí)候,有用到了device_create函數(shù)來創(chuàng)建節(jié)點(diǎn):

device_create創(chuàng)建的設(shè)備節(jié)點(diǎn)存放于/dev目錄下,而proc_create函數(shù)創(chuàng)建的與系統(tǒng)信息相關(guān)的節(jié)點(diǎn)存放于/proc目錄下。既然它們這么相似,下面我們就模仿編寫驅(qū)動(dòng)的方式來編寫我們關(guān)于proc的測(cè)試代碼。

proc實(shí)踐

我們模仿字符設(shè)備驅(qū)動(dòng)的編寫方式,來編寫基于proc的“驅(qū)動(dòng)”。首先需要?jiǎng)?chuàng)建一個(gè)文件操作結(jié)構(gòu)體hello_proc_operations,創(chuàng)建一些hello_proc_open、hello_proc_close、hello_proc_read、hello_proc_write填到這個(gè)操作表里:

左右滑動(dòng)查看全部代碼>>>

#include?
#include?
#include?
#include?
#include?

static?char?kernel_buf[1024];

#define?MIN(a,?b)?(a?

static?int?hello_proc_open(struct?inode?*node,?struct?file?*file)
{
?printk("%s?%s?line?%d\n",?__FILE__,?__FUNCTION__,?__LINE__);
?return?0;
}

static?ssize_t?hello_proc_read(struct?file?*file,?char?__user?*buf,?size_t?size,?loff_t?*offset)
{
?int?err;
?printk("%s?%s?line?%d\n",?__FILE__,?__FUNCTION__,?__LINE__);
?err?=?copy_to_user(buf,?kernel_buf,?MIN(1024,?size));
?return?MIN(1024,?size);
}

static?ssize_t?hello_proc_write(struct?file?*file,?const?char?__user?*buf,?size_t?size,?loff_t?*offset)
{
?int?err;
?printk("%s?%s?line?%d\n",?__FILE__,?__FUNCTION__,?__LINE__);
?err?=?copy_from_user(kernel_buf,?buf,?MIN(1024,?size));
?return?MIN(1024,?size);
}

static?int?hello_proc_close(struct?inode?*node,?struct?file?*file)
{
?printk("%s?%s?line?%d\n",?__FILE__,?__FUNCTION__,?__LINE__);
?return?0;
}

static?const?struct?file_operations?hello_proc_operations?=?
{

?.owner??=?THIS_MODULE,
?.open??=?hello_proc_open,
?.read????=?hello_proc_read,
?.write???=?hello_proc_write,
?.release?=?hello_proc_close,
};

static?int?__init?hello_proc_init(void)
{
?proc_create("hello_proc",?0,?NULL,?&hello_proc_operations);
?return?0;
}

static?void?__exit?hello_proc_exit(void)
{
?remove_proc_entry("hello_proc",?NULL);
}

module_init(hello_proc_init);
module_exit(hello_proc_exit);
MODULE_DESCRIPTION("proc?test");
MODULE_LICENSE("GPL");

最上邊的那個(gè)例子中用了一個(gè)fs_initcall宏,這與module_init的底層是差不多相同的(有宏參數(shù)不一樣):

① module_init -> _initcall ?-> ?device_initcall -> ?_define_initcall

② fs_initcall-> _define_initcall

為了方便,我們直接用module_init 。

Makefile文件:

左右滑動(dòng)查看全部代碼>>>

KERN_DIR?=?/home/book/100ask_imx6ull-sdk/Linux-4.9.88

#??-C?表示將當(dāng)前的工作目錄切換到指定目錄中,M?表示模塊源碼目錄,?modules?表示編譯模塊
all:
?make?-C?$(KERN_DIR)?M=`pwd`?modules?

clean:
?make?-C?$(KERN_DIR)?M=`pwd`?modules?clean
?rm?-rf?modules.order

#?obj-m?表示將?proc_test.c?這個(gè)文件編譯為?proc_test.ko?模塊
obj-m?+=?proc_test.o

編譯:

傳到板子里測(cè)試:

可以看到,我們已經(jīng)成功地在proc中留下了一個(gè)hello_proc小腳印??梢钥吹?,我們創(chuàng)建的基于/proc下的“驅(qū)動(dòng)”與創(chuàng)建基于/dev下的真實(shí)的設(shè)備驅(qū)動(dòng)的思路及套路是很相似的。這些都是屬于內(nèi)核的范疇,都是屬于內(nèi)核的東西,內(nèi)核把想給我們能直接使用的東西(文件)都放于/proc、/dev等目錄下,我們?cè)趹?yīng)用端就可以很方便地訪問這些文件開發(fā)我們的應(yīng)用。

如果文章中有錯(cuò)誤,歡迎指出。

碼字不易,如果覺得文章有用,期待你的點(diǎn)贊、在看與轉(zhuǎn)發(fā),給小編更多的動(dòng)力分享更多的東西。

猜你喜歡

Linux下應(yīng)用開發(fā)基礎(chǔ)

【Linux筆記】LED驅(qū)動(dòng)實(shí)驗(yàn)(總線設(shè)備驅(qū)動(dòng)模型)

【Linux筆記】設(shè)備樹實(shí)例分析

學(xué)習(xí)STM32的一些經(jīng)驗(yàn)分享

我的單片機(jī)轉(zhuǎn)嵌入式Linux之路

STM32的map文件學(xué)習(xí)筆記

基于RT-Thread的智慧路燈案例實(shí)驗(yàn)分享

C語(yǔ)言、嵌入式中幾個(gè)非常實(shí)用的宏技巧


1024G 嵌入式資源大放送!包括但不限于C/C++、單片機(jī)、Linux等。在公眾號(hào)聊天界面回復(fù)1024,即可免費(fèi)獲??!

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉