實驗目的
1、 熟悉 linux 下驅動程序設計 2、 了解 linux 下字符設備驅動設計
實驗要求
一、內核編譯提供以下實驗的環境 二、ubantu14.04 32 位下第一個 hello world 驅動程序 ??編寫驅動程序時,首先必須建立內核源碼樹,即下載源碼后,執行 make 編譯后的形式,它是編譯驅動的前提。ubuntu 系統默認情況下是沒有的。先前的內核只需要有一套內核頭文件就夠了,內核模塊編譯時需要內核源碼樹中的目標文件,通過這種方式,可得到一個更加健壯的模塊裝載器,但也需要這些目標文件存在于內核目錄樹中。 三、 ubantu14.04 第二個 memory 驅動程序 四、ubantu14.04 第三個使用文件私有數據的 globalmem 的設備
實驗環境
Pc電腦一臺 ,學校機房C203,17號電腦(Linux系統) 內核編譯教程 Linux設備驅動指導
實驗步驟、過程
(含原理圖、流程圖、關鍵代碼,或實驗過程中的記錄、數據等)
實驗步驟
一、內核編譯提供以下實驗的環境
uname -r 查看內核版本 ,輸出: 4.10.0-19-generic 如果安裝系統時,自動安裝了源碼。在 /usr/src 目錄下有對應的使用的版本目錄,ubuntu 系統默認情況下是沒有的,如下所示: ls /usr/src,輸出:linux-headers- 4.10.0-19,linux-headers- 4.10.0-19-generic 。 查看一下可一下載的源碼包(切記不要使用超級用戶使用此命令否則……會提示沒有此命令)執行:apt-cache search linux-source,輸出: linux-source-4.10.0-19 - Linux kernel source for version 4.10.0-19 with Ubuntu patches 。 執行:sudo apt-get install linux-source-4.10.0-19 下載完成后,在/usr/src 下會有壓縮包,然后解壓,解壓后生成一個新的目錄/usr/src/linux-source-4.10.0-19 開始配置內核 選擇最快的原版的配置(默認)方式 。 執行:make oldconfig 當然你也可以使用 自己喜歡的配置方式 如 menuconfig , xconfig(必須有 GTK 環境吧)。 執行:make bzImage 執行結束后,可以看到在當前目錄下生成了一個新的文件: vmlinux 。 執行:make modules 和 make modules_install,執行結束之后,會在/lib/modules 下生成新的目錄/lib/modules/3.13.0-32-generic/,若由于主機本身內核版本就為 3.13.0-32-generic,所以/lib/modules/3.13.0-32-generic/本身就存在,所以 make modules 和 make modules_install 兩步就不需要執行了。至此,構造內核源碼樹完成。【注意:如果沒有建立內核源碼樹,按下面步驟,雖然能夠生成 hello.ko,但執行 sudo insmod hello.ko 后,執行 lsmod 會沒反應,導致系統報告問題,會導致下次開機或重啟時有問題,若啟動不了,可以進入 recovery 模式,執行 fsck,開機做嵌入式 linux 開發一般在 PC 機上編譯好了,下到板子上去運行,板子上的 linux 內核和 PC 機上的 linux 版本很多時候都是不一樣的,比如 pc 機上的是 linux2.6,板子上的是 linux3.1,這個時候就要下 linux3.1 的內核,用它編譯的驅動模塊在板子上才能加載上,不然會出錯。】
二、ubantu14.04 32 位下第一個 hello world 驅動程序
c 文件以及 Makefile 文件 到hello.c文件目錄下執行make,會生成hello.ko文件以及其他相關文件。 執行sudo insmod .hell.ko 加載模塊 執行lsmod就可以看到hello模塊了 sudo rmmod hello
三、 ubantu14.04 第二個 memory 驅動程序
編寫mydm1.c 編寫 Makefile文件 編寫test.c文件 運行: ①到包含 Makefile 和 mydm1.c 的目錄下執行 make,生成 mydm1.ko; ②執行 sudo insmod mydm1.ko; ③驗證:lsmod | grep mydm1 ④需要創建一個文件(該設備文件用于和設備驅動操作)mknod /dev/fgj c 224 0 c 代表字符設備 224為主設備號,0 為從設備號 ⑤ gcc test.c,然后執行:sudo ./a.out 輸出如下:open/dev/fgjsuccessfully ,write successfully。
四、ubantu14.04 第三個使用文件私有數據的 globalmem 的設備
編寫globalmem.c代碼如下。 編寫 Makefile文件。 執行:make ,然后 sudo insmod globalmem.ko。 驗證:lsmod 可以看到該模塊,mknod /dev/globalmem c 354 0, echo ‘good global’ > /dev/globalmem, cat /dev/globalmem 可以看到輸出 good global; 還出現了:cat: /dev/globalmem: 沒有那個設備或地址,目前不知道是什么問題。 測試:輸出如下: open/dev/globalmem successfully ,write successfully ,read successfully:mem。
程序說明及實現
一、內核編譯提供以下實驗的環境
uname -r查看內核版本。如圖1所示。
圖1 內核版本
2. ls /usr/src,輸出。如圖2所示。
圖2 查看src目錄
3. 查看一下可一下載的源碼包(切記不要使用超級用戶使用此命令否則……會提示沒有此命令)執行:apt-cache search linux-source。因為機房電腦的電腦已經存在了編譯好的內核因此這一步可以跳過。如圖3所示。 圖3查看源碼包(因為apt緩存沒有)
圖3 查看源碼包(因為apt緩存沒有)
4. 執行:sudo apt-get install linux-source-4.10.0-19。如圖4所示。 圖4 sudo apt-get install結果圖
圖4 sudo apt-get install結果圖
執行:make oldconfig 。當然你也可以使用 自己喜歡的配置方式 如 menuconfig , xconfig(必須有GTK環境吧),如圖5所示。之后,使用“ll”查看一下目錄,如圖6所示。。并且查看一下“.config”文件。如圖7所示。
圖5 執行“make config”
圖6 查看目錄”
圖7 “.config”文件”
執行:make bzImage。執行結束后,可以看到在當前目錄下生成了一個新的文件: vmlinux。如圖8所示。
圖8 查看增加的vmlinux
執行:make modules和make modules_install,執行結束之后,會在/lib/modules下生成新的目錄/lib/modules/3.13.0-32-generic/,若由于主機本身內核版本就為3.13.0-32-generic,所以/lib/modules/3.13.0-32-generic/本身就存在,所以make modules和make modules_install兩步就不需要執行了。 內核編譯結束,環境準備工作完成。
二、ubantu14.04 32 位下第一個 hello world 驅動程序
新建一個文件夾“test1”用來存放hello world 驅動程序相關文件。 編寫hello.c文件以及Makefile文件。源代碼實驗報告已經提供,因此使用“vi”+文件名的方式創建文件并且將源代碼copy進入到文件中,創建兩個文件如圖9所示。
圖9 創建兩個文件
① hello.c文件。源代碼如圖10所示。
圖10 hello.c文件源代碼
② Makefile文件。源代碼如圖11所示。
圖11 Makefile文件源代碼
對Makefile文件的編寫進行簡單解釋:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
這句是Makefile的規則:這里的$ (MAKE)就相當于make,-C 選項的作用是指將當前工作目錄轉移到你所指定的位置。“M=”選項的作用是,當用戶需要以某個內核為基礎編譯一個外部模塊的話,需要在make modules 命令中加入“M=dir”,程序會自動到你所指定的dir目錄中查找模塊源碼,將其編譯,生成ko文件 注意:$ (MAKE) -C $ (KERNELDIR) M=$ (PWD) modules和$ (MAKE) -C $ (KERNELDIR) M=$ (PWD) modules_install前面為tab占位符。
在test1目錄下執行“make”命令。效果如圖12所示。執行“make”命令之后,查看當前目錄下的文件,如圖13所示。
圖12 執行“make”效果
圖13 test1目錄下文件
執行sudo insmod ./hello.ko加載模塊。 執行lsmod就可以看到hello模塊。如圖14所示。
圖14 加載hello模塊
執行“cat /var/log/syslog | grep world查看輸出”。如圖15所示。
圖15 第一個hello world驅動程序最終效果圖
三、 ubantu14.04 第二個 memory 驅動程序
新建一個文件夾“test2”用來存放memory 驅動程序相關文件。 編寫mydm1.c文件以及Makefile文件。源代碼實驗報告已經提供,因此使用“vi”+文件名的方式創建文件并且將源代碼copy進入到文件中,創建兩個文件 如圖16所示。
圖16 創建兩個文件
編寫mydm1.c文件。如圖17所示。
圖17 mydm1.c文件源代碼
編寫 Makefile文件。如圖18所示。
圖18 Makefile文件源代碼
創建并編寫test.c文件用于測試。如圖19所示。
圖19 test.c文件源代碼
運行: ①到包含 Makefile 和 mydm1.c 的目錄下執行 make,生成 mydm1.ko,如圖20所示。并且使用“ll”查看當前目錄可以看到相關文件,如圖21所示。
圖20 執行“make”命令效果
圖21 test2目錄
②執行“sudo insmod mydm1.ko”加載模塊并執行“lsmod”查看加載情況,如圖22,圖23所示。
圖22 加載“mydm1”模塊
圖23 查看是否加載“mydm1”模塊
③驗證:“lsmod | grep mydm1”輸出如圖24所示。
圖24 驗證結果
④需要創建一個文件(該設備文件用于和設備驅動操作)“mknod /dev/fgj c 224 0 ”代表字符設備 224為主設備號,0 為從設備號。如圖25所示。
圖25 創建設備驅動相關文件
⑤“gcc test.c”,如圖26所示。然后執行:“sudo ./a.out ”輸出如圖27所示。
圖26 “gcc test.c”編譯test.c文件
圖27 執行“a.out”文件效果
四、ubantu14.04 第三個使用文件私有數據的 globalmem 的設備
新建一個文件夾“test3”用來存放globalmem 驅動程序相關文件。 編寫globalmem.c文件以及Makefile文件。源代碼實驗報告已經提供,因此使用“vi”+文件名的方式創建文件并且將源代碼copy進入到文件中,創建兩個文件如圖28所示。
圖28 創建兩個文件
編寫globalmem.c文件。如圖29所示。
圖29 globalmem.c文件源代碼
編寫 Makefile文件。如圖30所示。
圖30 Makefile文件源代碼
到包含 Makefile 和 globalmem.c 的目錄下執行 make,生成 globalmem.ko,如圖31所示。
圖31 執行“make”命令
執行“sudo insmod globalmem.ko”加載模塊,如圖32所示。并且查看是否已加載成功,如圖33所示。
圖32 執行加載模塊
圖33 查看模塊globalmem是否加載成功
驗證:分別執行 “mknod /dev/globalmem c 354 0”;“echo ‘hello global’ > /dev/globalmem”;“cat /dev/globalmem” 可以看到輸出“hello global”(自己改寫了內容); 還出現了:cat: /dev/globalmem: 沒有那個設備或地址,目前不知道是什么問題。如圖34所示。
圖34 驗證結果
測試: ① 創建并編寫test.c文件用于測試。如圖35,圖36所示。
圖35 創建test.c文件
圖36 test.c文件源代碼
② 執行“gcc test.c”編譯test.c文件,如圖37所示。然后執行:“sudo ./a.out ”輸出如圖38所示。
圖37 編譯test.c文件
圖38 最終執行結果
實驗結果或總結
(對實驗結果進行相應分析,或總結實驗的心得體會,并提出實驗的改進意見) 實驗結果: 一、 內核編譯提供以下實驗的環境 實驗室已經有提供編譯好的內核,因為本人將編譯內核的流程大致進行了一遍。 二、 ubantu14.04 32 位下第一個 hello world 驅動程序
圖39 第一個hello world驅動程序最終效果圖
三、 ubantu14.04 第二個 memory 驅動程序
圖40 第二個 memory 驅動程序最終效果圖
四、 ubantu14.04 第三個使用文件私有數據的 globalmem 的設備
圖41 第三個使用文件私有數據的 globalmem 的設備最終效果圖
將本實驗用到的“test1,test2,test3”三個文件夾的目錄結構展示如圖42,圖43,圖44。
圖42 test1文件夾目錄結構
圖43 test2文件夾目錄結構
圖44 test3文件夾目錄結構
建議
提供可以編譯內核虛擬機環境,這樣可以節省不少時間。
心得體會
通過這次可以總結編寫Linux系統下的驅動程序步驟:①建立Linux的驅動骨架(裝載和卸載Linux驅動)任何類型的程序都有一個基本結構,linux驅動程序也不例外。Linux內核在使用驅動時首先需要裝載驅動。在裝載過程中也需要進行一些初始化的工作。②注冊和注銷設備文件任何一個linux驅動都需要一個設備文件,否則應用程序將無法與驅動程序交互。③指定與驅動相關的信息驅動程序是自描述的。④指定回調函數一個驅動程序并不一定要指定所有的回調函數。⑤編寫業務邏輯⑥編寫Makefile文件⑦編寫Linux驅動程序⑦安裝和卸載Linux驅動。基本了解了Linux系統下的驅動程序編寫方法,對驅動程序有了更加深刻的認識。 在剛開始接觸驅動程序時,遇到了很多很多的問題,當時就特別想放棄,好在我及時的尋求了同學的幫助。同學很熱心的幫助我解答問題,我這才慢慢找到了驅動程序的“套路”。通過本次實驗,我同樣學到了Linux系統下“make”命令的用法。起初,我對“make”知之甚少,只是聽說過,但是從來沒有用過。直到這次實驗,我才認識到它的強大用處。“make”是用來編譯的,它從Makefile中讀取指令,然后進行編譯。它的強大之處就在于不僅可以用于編譯眾多互相關聯的源代碼文件,而且還可以編譯內核模塊。
總結
以上是生活随笔 為你收集整理的计算机操作系统-设备驱动实现实验报告 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。