在linux中 應用程式如何調用模組內的函數

來源:互聯網
上載者:User

在bbs上發了個如題所示的大土帖,結果沒一個回複,哎,真丟人~~~,蒙師兄指點,才初步搞清楚linux模組函數的調用機制:

首先,應用程式是無法直接存取模組中的函數的(即使是你自編自掛的模組--實際上它也是核心模組),使用者空間與核心空間之間只有通過一些特定的系統函數來進行通訊(如什麼user_to_kernel),而絕對不可能通過“直接調用模組裡的函數”這種形式來通訊。


麼,所編寫的模組裡的函數怎麼才能被執行?由誰調用?其實答案很簡單,它們是由核心來調用的,注意,是由核心來調用的。比如
init_module() 和  cleanup_module()
函數,分別是在掛載模組(insmod)和卸載模組(rmmod)的時候,核心根據命令參數來調用此兩個函數的,它們分別負責模組的初始化及後處理。


自然的,下一個疑問接踵而至,--模組裡的其他函數如何被調用?比如我寫的模組中除了 init_module()
和  cleanup_module() 函數外,還寫了一個 hello_world() 函數,簡單的輸出“hello
world”到控制台,好,接下來就是這次分析的關鍵,前面我們強調了模組中的函數是由核心來調用的,除此之外沒有別的機會使它被執行到。那如果我們的
hello_world()
函數不能被核心調用,這不就意味著它永遠也不可能被執行到嗎?確實是這樣,換句話說,在這種情況下它就是一段垃圾代碼,永無見天日之時。怎麼樣才能使我們
的 hello_world()
函數被執行?顯然,關鍵在於讓核心認識它,即核心能找到它。那麼,怎樣才能使核心找到這個函數?再進一步的問題是,核心為什麼要去找這個函數?

第一問的答案是,核心通過系統中特定的資料結構來找到函數的,當然,這意味著在你的模組程式中,僅僅寫上 hello_world() 函數的代碼是不夠的,還應該再做幾步工作:

a,首先,系統中的各類資料結構那麼多,要使用哪個呢?這由你這個模組的註冊性質決定,譬如你的模組是一個USB裝置驅動模組,那麼你就需要填寫usb裝置驅動程式的資料結構(通常資料結構都是結構體(struct)的形式)
struct usb_driver{第一項;第二項;第三項;.......}
這裡的各項有些是字串,有些是函數指標,具體請查資料。

b,
把 hello_world()
的函數指標放進一個資料結構中。我們還是接著舉usb裝置驅動程式模組的例子吧,在它的資料結構usb_driver{}中,選一個恰好是函數指標的項,
把 hello_world() 函數的指標放進去(通過函數名),再填滿這個資料結構的其他部分(不想填的話就空著吧:P,用分號分隔即可)。

c,
填完之後,回到第一問中,怎樣使核心能夠找到這個 hello_world()
函數?回頭想想,當我們填完了資料結構,也就決定了我們所編的模組的性質,在此例中它是作為一個usb裝置驅動模組,但是要讓核心知道它的性質,還得通過
執行usb裝置驅動程式的系統註冊函數 usb_register(struct usb_struct
*drv),向核心註冊這個模組以及這個填好的資料結構。注意到了吧,註冊函數的參數就是我們前面所填寫的usb裝置驅動模組的資料結構,也就是說,執行
了這個註冊函數之後,核心裡就認識了這個模組,並且得到了 hello_world() 函數的指標!哈哈,這就為我們的 hello_world()
函數找到了生存的意義--它有可能被執行了!(偶覺得,程式生存的意義就在於被執行,就跟偶們生存的意義在於編程式一樣:P)

d,還得補
充一下,usb_register(struct usb_struct *drv) 函數必須被放在 init_module()
中,因為在註冊這個決定模組性質的資料結構之前(短語太長,可約為“這個資料結構”),模組中可以被直接執行到的函數只有 init_module()
和 cleanup_module() 兩個,如果不把握這個機會趕緊註冊資料結構的話,那我們的 hello_world()
函數又要永不見天日了:(。

現在來看第二問,核心為什麼要去找這個函數?還是用usb裝置驅動模組來解釋,其他類型的模組偶不了
解,還請大蝦們補充。對於usb裝置驅動模組,核心找這個函數的原因當然是,使用者程式對usb裝置進行了某種操作,而這種操作需要usb裝置驅動程式的函
數來進行實現。我們前面的工作中已將這個usb裝置驅動模組的資料結構註冊進核心資料結構鏈表,核心根據我們這個模組對應的資料結構usb_driver
的各項定義,找到對應使用者要求的那個操作的那個函數。假設我們把 hello_world() 函數的指標放在usb_driver的 write()
選項中,那麼當使用者對usb裝置進行寫操作的時候,就調用了 hello_world() 函數,控制台螢幕上會打出“hello world
”,其他什麼操作都沒有,哈哈,一定很有趣。(這裡我們假設此usb裝置的驅動程式正好是我們編的那個)

自己的一點心得,大部分是憑空想像的,錯誤之處一定數不勝數,還請各位大蝦費心批評指教!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.