導航:首頁 > 操作系統 > linuxhello驅動

linuxhello驅動

發布時間:2023-09-08 01:54:49

『壹』 如何編譯一個linux下的驅動模塊

linux下編譯運行驅動
嵌入式linux下設備驅動的運行和linux x86 pc下運行設備驅動是類似的,由於手頭沒有嵌入式linux設備,先在vmware上的linux上學習驅動開發。
按照如下方法就可以成功編譯出hello world模塊驅動。
1、首先確定本機linux版本
怎麼查看Linux的內核kernel版本?
'uname'是Linux/unix系統中用來查看系統信息的命令,適用於所有Linux發行版。配合使用'uname'參數可以查看當前伺服器內核運行的各個狀態。
#uname -a
Linux whh 3.5.0-19-generic #30-Ubuntu SMPTue Nov 13 17:49:53 UTC 2012 i686 i686 i686 GNU/Linux

只列印內核版本,以及主要和次要版本:
#uname -r
3.5.0-19-generic

要列印系統的體系架構類型,即的機器是32位還是64位,使用:
#uname -p
i686

/proc/version 文件也包含系統內核信息:
# cat /proc/version
Linux version 3.5.0-19-generic(buildd@aatxe) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) ) #30-UbuntuSMP Tue Nov 13 17:49:53 UTC 2012

發現自己的機器linux版本是:3.5.0-19-generic
2、下載機器內核對應linux源碼
到下面網站可以下載各個版本linux源碼https://www.kernel.org/
如我的機器3.5.0版本源碼下載地址為:https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.tar.bz2
下載完後,找一個路徑解壓,如我解壓到/linux-3.5/
然後很重要的一步是:執行命令uname -r,可以看到Ubuntu的版本信息是3.5.0-19-generic
。進入linux源碼目錄,編輯Makefile,將EXTRAVERSION = 修改為EXTRAVERSION= -19-generic。
這些都是要配置源碼的版本號與系統版本號,如果源碼版本號和系統版本號不一致,在載入模塊的時候會出現如下錯誤:insmod: error inserting 'hello.ko': -1 Invalid mole format。
原因很明確:編譯時用的hello.ko的kenerl 不是我的pc的kenerl版本。

執行命令cp /boot/config-3.5.0-19-generic ./config,覆蓋原有配置文件。
進入linux源碼目錄,執行make menuconfig配置內核,執行make編譯內核。

3、寫一個最簡單的linux驅動代碼hello.c

/*======================================================================
Asimple kernel mole: "hello world"
======================================================================*/
#include <linux/init.h>
#include <linux/mole.h>
MODULE_LICENSE("zeroboundaryBSD/GPL");
static int hello_init(void)
{
printk(KERN_INFO"Hello World enter\n");
return0;
}

static void hello_exit(void)
{
printk(KERN_INFO"Hello World exit\n ");
}

mole_init(hello_init);
mole_exit(hello_exit);

MODULE_AUTHOR("zeroboundary");
MODULE_DESCRIPTION("A simple HelloWorld Mole");
MODULE_ALIAS("a simplestmole");

4、寫一個Makefile對源碼進行編譯
KERN_DIR = /linux-3.5
all:
make-C $(KERN_DIR) M=`pwd` moles
clean:
make-C $(KERN_DIR) M=`pwd` clean

obj-m += hello.o

5、模塊載入卸載測試
insmod hello.ko
rmmod hello.ko

然後dmesg|tail就可以看見結果了

最後,再次編譯驅動程序hello.c得到hello.ko。執行insmod ./hello.ko,即可正確insert模塊。

使用insmod hello.ko 將該Mole加入內核中。在這里需要注意的是要用 su 命令切換到root用戶,否則會顯示如下的錯誤:insmod: error inserting 'hello.ko': -1 Operation not permitted

內核模塊版本信息的命令為modinfo hello.ko
通過lsmod命令可以查看驅動是否成功載入到內核中
通過insmod命令載入剛編譯成功的time.ko模塊後,似乎系統沒有反應,也沒看到列印信息。而事實上,內核模塊的列印信息一般不會列印在終端上。驅動的列印都在內核日誌中,我們可以使用dmesg命令查看內核日誌信息。dmesg|tail

可能還會遇到這種問題insmod: error inserting 'hello.ko': -1 Invalid mole format
用dmesg|tail查看內核日誌詳細錯誤
disagrees about version of symbolmole_layout,詳細看這里。
http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmoles/index.html
在X86上我的辦法是:
make -C/usr/src/linux-headers-3.5.0-19-generic SUBDIRS=$PWD moles

『貳』 如何編譯一個linux下的驅動模塊

這是一個簡單而完整的實例,對於理解Linux下的驅動模塊是非常有幫助的。

1.源碼如下:
/*
* hello.c -- the example of printf "hello world!" in the screen of driver program
*/
#include <linux/init.h>
#include <linux/mole.h>
MODULE_LICENSE("Dual BSD/GPL");/* declare the license of the mole ,it is necessary */
static int hello_init(void)
{
printk(KERN_ALERT "Hello World enter!\n");
return 0;
}
static int hello_exit(void)
{
printk(KERN_ALERT "Hello world exit!\n");
}
mole_init(hello_init); /* load the mole */
mole_exit(hello_exit); /* unload the mole */
進入目錄:
[root@Alex_linux /]#cd /work/jiakun_test/moletest
[root@Alex_linux moletest]# vi hello.c
然後拷入上面書上的源碼。
2.編譯代碼:
1>.首先我在2.4內核的虛擬機上進行編譯,編譯過程如下:
[root@Alex_linux moletest]#gcc -D__KERNEL__ -I /usr/src/linux -DMODULE -Wall -O2 -c -o hello.o hello.c
其中-I選項指定內河源碼,也就是內核源碼樹路徑。編譯結果:
hello.c:1:22: net/sock.h: No such file or directory
hello.c: In function `hello_init':
hello.c:6: warning: implicit declaration of function `printk'
hello.c:6: `KERN_ALERT' undeclared (first use in this function)
hello.c:6: (Each undeclared identifier is reported only once
hello.c:6: for each function it appears in.)
hello.c:6: parse error before string constant
hello.c: In function `hello_exit':
hello.c:11: `KERN_ALERT' undeclared (first use in this function)
hello.c:11: parse error before string constant
hello.c: At top level:
hello.c:13: warning: type defaults to `int' in declaration of `mole_init'
hello.c:13: warning: parameter names (without types) in function declaration
hello.c:13: warning: data definition has no type or storage class
hello.c:14: warning: type defaults to `int' in declaration of `mole_exit'
hello.c:14: warning: parameter names (without types) in function declaration
hello.c:14: warning: data definition has no type or storage class
在網上查詢有網友提示沒有引入kernel.h
解決:vi hello.c
在第一行加入:#include <linux/kernel.h>
再次編譯仍然報KERN_ALERT沒有聲明
修改編譯條件-I,再次編譯:
[root@Alex_linux moletest]#gcc -D__KERNEL__ -I /usr/src/linux -DMODULE -Wall -O2 -c -o hello.o hello.c
[root@Alex_linux moletest]#ls
hello.c hello.o Makefile
[root@Alex_linux moletest]#
2>.接著我嘗試在2.6內核的虛擬機上進行編譯
編譯過程如下:
[root@JiaKun moletest]# ls
hello.c makefile
[root@JiaKun moletest]# vi hello.c
[root@JiaKun moletest]# make
make -C /mylinux/kernel/2.4.18-rmk7 M=/home/alex/test/moletest moles
make: *** /mylinux/kernel/2.4.18-rmk7: No such file or directory. Stop.
make: *** [moles] Error 2
[root@JiaKun moletest]# vi makefile
[root@JiaKun moletest]# make
make -C /usr/src/kernels/2.6.18-53.el5-i686 M=/home/alex/test/moletest moles
make[1]: Entering directory `/usr/src/kernels/2.6.18-53.el5-i686'
scripts/Makefile.build:17: /home/alex/test/moletest/Makefile: No such file or directory
make[2]: *** No rule to make target `/home/alex/test/moletest/Makefile'. Stop.
make[1]: *** [_mole_/home/alex/test/moletest] Error 2
make[1]: Leaving directory `/usr/src/kernels/2.6.18-53.el5-i686'
make: *** [moles] Error 2
[root@JiaKun moletest]# mv makefile Makefile
[root@JiaKun moletest]# make
make -C /usr/src/kernels/2.6.18-53.el5-i686 M=/home/alex/test/moletest moles
make[1]: Entering directory `/usr/src/kernels/2.6.18-53.el5-i686'
CC [M] /home/alex/test/moletest/hello.o
Building moles, stage 2.
MODPOST
CC /home/alex/test/moletest/hello.mod.o
LD [M] /home/alex/test/moletest/hello.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.18-53.el5-i686'
[root@JiaKun moletest]# ls
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile Mole.symvers

3.執行代碼,載入驅動模塊:
2.4內核載入模塊:
insmod ./hello.o
但是此時並沒有輸出printk列印的信息。但是可以在/var/log/messages 中看到列印的信息,這是由於KERN_ALERT優先順序不夠高。這里
需要修改為:KERN_EMERG。再次編譯,載入模塊即可以看到結果
2.6內核載入模塊:
[root@JiaKun moletest]# insmod hello.ko
[root@JiaKun moletest]#
Message from syslogd@ at Sat Jul 26 19:52:44 2008 ...
JiaKun kernel: Hello, world
有的朋友可能會出現insmod命令找不到的錯誤,這可能有下面幾個原因:
<1> 你的系統沒有安裝mole-init-tools工具,關於此問題,只需安裝即可,但是一般裝完系統是有這個命令的。
<2> 環境變數沒有添加導致不能使用該命令。使用echo $PATH即可查看PATH環境變數,發現沒有/sbin這個路徑,所以你當然不能使用insmod這個命令了。解決的方法很簡單,只需在命令行輸入:
PATH = "$PATH:/sbin"即可添加。(insmod在/sbin這個目錄下,你可以使用whereis insmod查看)。
<3> insmod這個命令需要在root許可權下才能使用。
載入完成後你可以輸入lsmod查看hello這個模塊哦。

4.卸載驅動模塊:rmmod hello.
載入模塊後就可在屏幕上看到如下信息:Hello world enter.
卸載時就可在屏幕上看到如下信息:hello world exit.
[root@JiaKun moletest]# rmmod hello.ko
[root@JiaKun moletest]#
Message from syslogd@ at Sat Jul 26 19:52:58 2008 ...
JiaKun kernel: Goodbye, cruel world

另外,如果有多個文件,則按下列方式編寫Makefile文件(file1.c、file2.c):
obj -m := molename.o
mole-objs := file1.o file2.o

『叄』 ubuntu 驅動編譯無法通過 求神來解決

復制代碼
1 #ifndef __KERNEL__
2 # define __KERNEL__
3 #endif
4 #ifndef MODULE
5 # define MODULE
6 #endif
7
8 // 下面的是主要的內容
9 #include <linux/kernel.h>
10 #include <linux/mole.h>
11 #include <linux/init.h>
12
13 MODULE_LICENSE("GPL");
14
15 static int year=2012;
16
17 int hello_init()
18 {
19 printk(KERN_WARNING "Hello kernel, it's %d!\n",year);
20 return 0;
21 }
22
23
24 void hello_exit()
25 {
26 printk("Bye, kernel!\n");
27 }
28
29 // 下面兩個為關鍵的模塊函數
30 mole_init(hello_init);
31 mole_exit(hello_exit);
復制代碼
如果上面的代碼看起來不太熟悉,那麼需要查看以下相關的書籍,比如《Linux設備驅動程序,第三版》,也就是大名鼎鼎的LDD;

2、老式驅動模塊編譯方法:

直接寫出make規則到makefile文件中,引用內核體系的頭文件路徑,舉例如下:

復制代碼
1 # The path of kernel source code
2 INCLUDEDIR = /media/GoldenResources/linux/linux-2.6.30/include
3
4 # Compiler
5 CC = gcc
6
7 # Options
8 CFLAGS = -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR)
9
10 # Target
11 OBJS = hello.o
12
13 all: $(OBJS)
14
15 $(OBJS): hello.c
16 $(CC) $(CFLAGS) -c $<
17
18 install:
19 insmod $(OBJS)
20
21 uninstall:
22 rmmod hello
23
24 .PHONY: clean
25 clean:
26 rm -f *.o
復制代碼
這里有我是用的一個linux內核源代碼路徑:/media/GoldenResources/linux/linux-2.6.30/include ,注意設置到正確的源碼路徑。

嘗試這編譯:

復制代碼
$make
gcc -D__KERNEL__ -DMODULE -O -Wall -I/media/GoldenResources/linux/linux-2.6.30/include -c hello.c
In file included from /media/GoldenResources/linux/linux-2.6.30/include/linux/kernel.h:11:0,
from hello.c:8:
/media/GoldenResources/linux/linux-2.6.30/include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory
compilation terminated.
make: *** [hello.o] Error 1
復制代碼

『肆』 linux內核模塊的小問題

使用 locate include/generated/autoconf.h 來查找系統中有沒有這個文件,如果有的話看看它給的路徑的你寫的路徑有無出入。如果沒有的話我就不知道怎麼回事了。
還有你的命令只怕也寫錯了,這樣在父目錄中創建一個與以本目錄為前綴,加上moles為名的新目錄,而不是在本目錄中創建一個名為moles的子目錄。 $(pwd)moles 似應該為 $(pwd)/moles, 另外如果這樣改的話,那麼 moles/Makefile 中的hello.c 也應該改為../hello.c , 要不路徑就錯誤了

『伍』 如何學習嵌入式Linux驅動程序開發求解

2. 編一應用程序,可以用makefile跑起來
3. 學會寫驅動的makefile
4. 寫一簡單char驅動,makefile編譯通過,可以insmod, lsmod, rmmod. 在驅動的init函數里列印hello world, insmod後應該能夠通過dmesg看到輸出。
5. 寫一完整驅a動, 加上read, write, ioctl, polling等各種函數的驅動實現。 在ioctl里完成從用戶空間向內賀畢孫核空間傳遞結構體的實現。
6. 寫一block驅動, 加上read,write,ioctl,poll等各種函數實現。
7. 簡單學習下內存管理, 這個是最難的,明白各種memory alloc的函數實現細節。這是linux開發的基本功。
8. 學習鎖機制的應用,這個不是最難的但是最容易犯錯的,涉及到很多同步和並發的問題。
9. 看內核中實際應用的驅動代碼。 你會發現最基本的你已經知道了, 大的框架都是數悶一樣的, 無非是read, write, ioctl等函數的實現, 但裡麵包含了很多很多細小的實現細節是之前不知道的。 這時候就要考慮到很多禪鏈別的問題而不僅僅是基本功能的實現。例如:凌陽教育嵌入式linux培訓課程的第四階段:嵌入式微處理器及Linux設備驅動開發的學習主要是通過:ARM硬體介面原理,嵌入式Linux設備驅動開發,嵌入式Linux高級驅動程序設計這三大塊深入淺出的學習驅動程序開發。讓學員熟悉Linux的內核機制、驅動程序與用戶級應用程序的介面,掌握系統對設備的並發操作。

閱讀全文

與linuxhello驅動相關的資料

熱點內容
2200工程機接收命令瞬間消失 瀏覽:251
壓縮機工藝管是多大的 瀏覽:310
安卓刷什麼系統穩定 瀏覽:33
程序員寫炫酷代碼 瀏覽:928
大話存儲pdf 瀏覽:524
中銘機器人怎麼編程 瀏覽:812
把字母變為數字的加密法 瀏覽:523
噬血狂襲第三季哪個app能看 瀏覽:421
江蘇螺桿壓縮機 瀏覽:980
android底部彈出對話框 瀏覽:501
怎麼查伺服器同行fc號 瀏覽:1000
什麼伺服器雲鳥最便宜 瀏覽:221
vs編譯器反匯編 瀏覽:570
程序員直播做項目創業 瀏覽:403
linux下samba配置 瀏覽:797
程序員面試銀行崗位會有編制嗎 瀏覽:414
ex表怎麼加密碼保護 瀏覽:174
小孩上編程課用哪款好 瀏覽:559
如何製作伺服器商店 瀏覽:736
壓縮氣管閥門 瀏覽:466