所有的程序員入門的第一個程序都是從 Holle World 開始,linux嵌入式驅動開發也不例外,《Linux設備驅動程序》這本書的第一個程序就是hello world。然而,人生寫驅動程序的第一次編譯就異常的艱難。
以下是hello world 的程序,很簡單,基本上學過C就能看懂,該程序包括兩個頭文件,引用了4個外部函數,內建2個函數。
1 #include <linux/init.h> 2 #include <linux/module.h> 3 4 MODULE_LICENSE("Dual BSD/GPL"); 5 6 static int hello_init(void) 7 { 8 printk(KERN_ALERT "Hello world\n"); 9 return 0; 10 } 11 12 static void hello_exit(void) 13 { 14 printk(KERN_ALERT "goodbye,cruel world\n"); 15 } 16 17 module_init(hello_init); 18 module_exit(hello_exit);
這個程序相當的清晰的指出了,驅動程序的程序結構,整個驅動程序由init函數引導加載,exit函數引導卸載。值得注意的是,驅動程序不需要main函數,這是驅動程序和普通程序一個比較明顯的區別。
注:如果你使用的是老版本的書或者PDF,hello world的代碼會和上述代碼有所區別,建議使用上述代碼,比較老版本是2.0時代的代碼了(第一版是2000年左右出版的),不過書的內容並沒有變化太大。
下面我們進入今天的正題。
寫完這個簡單的函數就可以進行編譯了,然而這個時候如果你直接使用GCC編譯的話你就會得到如下結果。
這里mo.c就是我的源程序文件。
可以看到這個時候編譯器報錯,No such file or directory,書上並沒有到如何解決,只能求助於萬能的度娘了。百度一圈之后,我發現,原來默認編譯器就沒引用這個頭文件,頭文件的地址就在/usr/src/linux-headers-3.16.0-30下面,於是我用-I來引用頭文件,然而並不能通過。
經過一番研究我發現,網上各路大神都是使用makefile進行編譯
1 obj-m := mo.o 2 3 CURRENT_DIR :=$(shell pwd) 4 5 KERNEL_DIR := /usr/src/linux-headers-$(shell uname -r) 6 all: 7 $(MAKE) -C $(KERNEL_DIR) M=$(CURRENT_DIR) modules 8 9 clean: 10 rm -rf %.o
這些總可以開開心心編譯了吧,呵呵,make之后
這錯誤信息到底是啥意思?常識了10個小時,我終於發現
mdzz
總之makefile報錯記得用權限跑一下 。。。。