0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

printk函數(shù)的地址問題怎么解決

麥辣雞腿堡 ? 來源:嵌入式Linux充電站 ? 作者:Vincent ? 2023-09-26 16:49 ? 次閱讀

不知大家有沒有想過,在一個(gè)內(nèi)核模塊代碼中,會用到printk函數(shù),而這個(gè)函數(shù)不是我們實(shí)現(xiàn)的,它是內(nèi)核代碼的一部分,但我們?yōu)槭裁茨軌蚓幾g通過呢?

我們的代碼之所以能夠編譯通過,是因?yàn)閷δK的編譯 僅僅是編譯,并沒有鏈接 。

編譯出來的.ko文件是一個(gè)普通的ELF文件 ,使用file命令和nm命令,我們可以看到相關(guān)的信息

# file vser.ko
vser.ko ELF 32-bit LSB relocatable, Intel 80386, vserion 1 (SYSV), BuildID[sha1]=0x09ca747e6f75c65v19a5da9102113v98d7cea24, not stripped
# nm vser.ko
......
00000004 d port
    U printk
00000000 t vser_exit
00000000 t vser_init

vser_initvser_exit分別是模塊的入口函數(shù)和出口函數(shù),使用nm命令查看模塊目標(biāo)文件的符號信息時(shí),可以看到vser_exitvser_init的符號類型是t,表示它們是 函數(shù)

printk的 符號類型是U,表示它是一個(gè) 未決符號 。意思是說在編譯階段不知道這個(gè)符號的地址,因?yàn)樗欢x在其他文件中,沒有放在模塊代碼一起編譯。

那printk函數(shù)的地址問題怎么解決呢?答案是用EXPORT_SYMBOL宏將printk導(dǎo)出即可。

EXPORT_SYMBOL導(dǎo)出符號

大致原理:利用EXPORT_SYMBOL宏生成一個(gè)特定的結(jié)構(gòu)并放在ELF文件的一個(gè)特定段中,在 內(nèi)核的啟動(dòng)過程中,會將符號的確切地址填充到這個(gè)結(jié)構(gòu)的特定成員中 。

模塊加載時(shí),加載程序?qū)⑷ヌ幚砦礇Q符號,在特殊段中搜索符號的名字,如果找到,則將獲得的地址填充在被加載模塊的相應(yīng)段中,這樣符號的地址就可以確定。

使用這種方式處理未決符號,其實(shí)相當(dāng)于把鏈接的過程推后,進(jìn)行了動(dòng)態(tài)鏈接,和普通的應(yīng)用程序使用共享庫函數(shù)的道理是類似的 。可以發(fā)現(xiàn),內(nèi)核將會有大量的符號導(dǎo)出,為模塊提供了豐富的基礎(chǔ)設(shè)施。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1361

    瀏覽量

    40185
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11211

    瀏覽量

    208721
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4284

    瀏覽量

    62325
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    648

    瀏覽量

    32775
收藏 人收藏

    評論

    相關(guān)推薦

    C代碼實(shí)現(xiàn)程序的跳轉(zhuǎn)|函數(shù)指針

    凡是學(xué)過C語言函數(shù)的應(yīng)該都知道,函數(shù)名其實(shí)就是個(gè)地址,是函數(shù)的入口地址。如果用 %p 來輸出函數(shù)
    發(fā)表于 01-17 09:26 ?1400次閱讀

    Linux內(nèi)核學(xué)習(xí)筆記:printk調(diào)試

    很多內(nèi)核開發(fā)者喜歡的調(diào)試工具是printk,在Linux內(nèi)核中,使用printk()函數(shù)來打印信息,它與C庫的printf()函數(shù)類似。
    發(fā)表于 06-01 15:14 ?1082次閱讀

    四種獲取內(nèi)核函數(shù)地址的方法

    在內(nèi)核調(diào)試中,經(jīng)常需要知道某個(gè)函數(shù)地址,或者根據(jù)函數(shù)地址找到對應(yīng)的函數(shù),從而進(jìn)行更深一步的debug。
    的頭像 發(fā)表于 11-17 16:58 ?1218次閱讀
    四種獲取內(nèi)核<b class='flag-5'>函數(shù)</b><b class='flag-5'>地址</b>的方法

    printk()函數(shù)的總結(jié)

    我們在使用printk()函數(shù)中使用日志級別為的是使編程人員在編程過程中自定義地進(jìn)行信息的輸出,更加容易地掌握系統(tǒng)當(dāng)前的狀況。對程序的調(diào)試起到了很重要的作用。(下文中的日志級別和控制臺日志控制級別
    發(fā)表于 07-09 03:47

    linux內(nèi)核打印函數(shù)printk的方法

    1.linux內(nèi)核打印函數(shù)printk一、函數(shù)有頭文件二、定義的關(guān)鍵宏三、函數(shù)原型合理的創(chuàng)建標(biāo)題,有助于目錄的生成如何改變文本的樣式插入鏈接與圖片如何插入一段漂亮的代碼片生成一個(gè)適合你
    發(fā)表于 12-20 07:02

    如何配置和使用Linux內(nèi)核printk功能

    了解如何配置和使用Linux內(nèi)核printk功能,包括其動(dòng)態(tài)調(diào)試功能。 這樣可以選擇性地打印調(diào)試消息,而無需重新編譯內(nèi)核。
    的頭像 發(fā)表于 11-27 06:40 ?3058次閱讀

    內(nèi)核日志及printk結(jié)構(gòu)淺析

    做DPDK項(xiàng)目時(shí),調(diào)試rte_kni.ko時(shí),發(fā)現(xiàn)printk并不會向我們想想的那樣把log信息顯示在我們的終端上。
    發(fā)表于 04-22 17:45 ?1099次閱讀

    你知道Linux內(nèi)核調(diào)試關(guān)鍵技術(shù)之一的printk

    在內(nèi)核調(diào)試技術(shù)之中,最簡單的就是printk的使用了,它的用法和C語言應(yīng)用程序中的printf使用類似,在應(yīng)用程序中依靠的是stdio.h中的庫,而在linux內(nèi)核中沒有這個(gè)庫,所以在linux內(nèi)核中,使用這個(gè)printk就要對內(nèi)核的實(shí)現(xiàn)有一定的了解。
    發(fā)表于 05-10 11:18 ?1661次閱讀

    Linux中的Printk與dmesg功能

    結(jié):??????? Printf在終端顯示,printk()函數(shù)為內(nèi)核空間里邊的信息打印函數(shù),就像c編程時(shí)用的printf()函數(shù)一樣,專供內(nèi)核中的信息展示用,他沒有調(diào)用printf(
    發(fā)表于 04-02 14:39 ?454次閱讀

    PMT函數(shù)與相對絕對地址引用的資料說明

    PMT函數(shù)與相對絕對地址
    發(fā)表于 05-12 14:47 ?0次下載
    PMT<b class='flag-5'>函數(shù)</b>與相對絕對<b class='flag-5'>地址</b>引用的資料說明

    C語言-內(nèi)聯(lián)函數(shù)、遞歸函數(shù)、指針函數(shù)

    這篇文章介紹C語言的內(nèi)聯(lián)函數(shù)、遞歸函數(shù)、函數(shù)指針、指針函數(shù)、局部地址、const關(guān)鍵字、extern關(guān)鍵字等知識點(diǎn);這些知識點(diǎn)在實(shí)際項(xiàng)目開發(fā)
    的頭像 發(fā)表于 08-14 10:03 ?1637次閱讀

    使用LPNDR_ReadGlobalInfo函數(shù)塊讀取IP地址和MAC地址

    使用 LPNDR_ReadGlobalInfo 函數(shù)塊可以讀取 PROFINET 設(shè)備的 IP 地址和 MAC 地址。
    的頭像 發(fā)表于 11-14 10:09 ?3942次閱讀

    C語言如何獲得自身定義函數(shù)的實(shí)際地址和大小嗎

    我們先看地址。C語言無法定義函數(shù)外標(biāo)簽,函數(shù)內(nèi)標(biāo)簽從使用到訪問處處受限,我們好像只剩函數(shù)名可以用。但函數(shù)名表達(dá)式未必等同于
    發(fā)表于 12-02 10:52 ?1033次閱讀

    如何使用函數(shù)指針?

    在程序中定義一個(gè)函數(shù),則編譯時(shí)系統(tǒng)就會為這段代碼分配一段存儲空間,這段存儲空間的首地址稱為函數(shù)地址,且函數(shù)名代表的就是這個(gè)
    的頭像 發(fā)表于 03-30 15:09 ?826次閱讀

    Linux內(nèi)核pr_xx()函數(shù)封裝

    pr_xx( )封裝 在使用printk的時(shí)候需要手動(dòng)添加輸出等級KERN_INFO、KERN_WARNING等,這樣還是有些麻煩。因此,Linux內(nèi)核也對printk進(jìn)行了進(jìn)一步的封裝
    的頭像 發(fā)表于 09-27 15:58 ?720次閱讀