昨天下午stepbystep的為其他同學演示了核心模組程式設計hello,kernel!在陳老師的指導下,先為大家演示了最基本的c程式hello,world。然後又一步步的轉換成核心模組程式。在這一步步的轉變過程中,我也發現了自己在學習核心模組中的不足,下面將下午遇到的一些問題總結如下。
乙個簡單的hello,world程式如下:
1
#include <\stdio.h\>
2
int
main()
3
對於上面的程式,我們通常一步到位進行編譯:
1
gcc hello.c -o hello
這樣的命令簡單方便,不過通常會讓我們忽略從.c檔案到可執行檔案的整個編譯過程。通常在使用gcc編譯程式時,編譯過程通常會分為4個階段,即預處理(pre-processing),編譯(compiling),彙編(assembling),鏈結(linking)。
在預處理階段,一般輸入的是.c檔案,而輸出的是.i檔案。在此階段中通常會處理原始檔中的預處理命令,比如#define,#include,#ifdef等命令。如果想要生成這種.i中間檔案,那麼可以使用下面命令:
1
gcc -e hello.c -o hello.i
在編譯階段,輸入的是.i中間檔案,輸出的是.s組合語言檔案。可以使用下面的命令:
1
gcc -s hello.i -o test.s
1
gcc -c test.s -o test.o
在鏈結階段,輸入的是.o二進位制機器**檔案,連同其他的(如果有的話)機器**檔案和庫檔案一起匯集成乙個可執行的二進位制**檔案。
1
gcc test.o -o test
以上是乙個程式編譯完整的四個階段。一般來說我們會將前三個階段一步搞定,那麼整個編譯過程可以用下面兩條命令就完成:
1
gcc -c test.c -o test.o
2
gcc test.o -o test
也就是先生成目標檔案,再將目標檔案連線成可執行檔案。當你熟悉了整個編譯過程後,可以用一開始我們說的一條命令來完成。
了解普通檔案的編譯過程,我們現在就將hello.c中的**轉換成模組程式設計中的.c**。首先我們要更改標頭檔案:
1
#include <\linux/kernel.h\>
2
#include <\linux/module.h\>
這與我們一般的標頭檔案不同。一般我們在使用者態下編寫c程式,標頭檔案會放在:/usr/include/下,而我們模組程式設計時,它使用的是核心中的標頭檔案,一般在:cd /usr/src/linux-headers-2.6.32-21/include/。特別的我們這裡使用的是include/目錄下linux/這個子目錄中的標頭檔案,因此模組編譯的時候會自動在核心中的include/目錄下找linux/kernel.h這樣的標頭檔案。
其次,printf到printk是乙個典型的使用者態下程式設計與核心模組程式設計的不同。可能我們一開始會比較奇怪,為什麼我make成功,載入也成功,但是就是不能顯示printk裡面的語句呢?我們可以這麼想printk就是專門為核心「服務」。它一般輸出的語句都在核心的日誌檔案當中。
printf到printk的轉變
昨天下午stepbystep的為其他同學演示了核心模組程式設計hello,kernel!在陳老師的指導下,先為大家演示了最基本的c程式hello,world。然後又一步步的轉換成核心模組程式。在這一步步的轉變過程中,我也發現了自己在學習核心模組中的不足,下面將下午遇到的一些問題總結如下。乙個簡單的h...
printk和printf的區別
大部分常用的c庫函式在linux核心中都已經得到了實現。在所有沒有實現的函式中,最著名的就數printf 函式了。核心 雖然無法呼叫 printf 函式,但它可以呼叫printk 函式。printk 函式負責把格式化好的字串拷貝到核心日誌緩衝上,這樣syslog程式就可 以通過讀取該緩衝區來獲取核心...
linux之printk和printf的區別
大部分常用的c庫函式在linux核心中都已經得到了實現。在所有沒有實現的函式中,最著名的就數printf 函式了。核心 雖然無法呼叫 printf 函式,但它可以呼叫printk 函式。printk 函式負責把格式化好的字串拷貝到核心日誌緩衝上,這樣syslog程式就可 以通過讀取該緩衝區來獲取核心...