歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Ubuntu下Hello World驅動實現全過程

Ubuntu下Hello World驅動實現全過程

日期:2017/3/1 10:05:35   编辑:Linux編程

今天是一個值得紀念的日子,我也不知道我花了多長時間才編譯成功!在編寫這個驅動的過程中,真的體會到驅動編程不是那麼簡單的~,現在有點小小的激動,真的,很不容易啊~我把整個過程在重復一遍吧!

在編寫這個驅動的過程中參考了網上的很多文檔,最終的結果是弄的我頭都暈了,每個人寫的都不一樣,其實我現在還有一些概念不是很清楚。

1:到底丫的什麼是內核源碼樹?

2:為什麼要編譯內核源碼樹?

1:內核源碼樹我現在的理解就是整個linux內核源代碼,它是編譯驅動的前提。Ubuntu系統默認情況下是沒有的,

內核源碼樹是要自己下載的。

2:驅動最終以*.ko的形式生成,insmod的本質就是將ko文件與運行的內核進行鏈接的過程。類似於編譯helloworld的鏈接過程。

鏈接必然需要先進行編譯,以便確定所需的外部符號(EXPORT_SYMBOLS)是否存在,因為有些符號(函數或全局變量)在

內核中。在驅動中如果使用到這些符號,必須預留一個位置,insmod時進一步確定這些符號的具體位置(符號綁定)。

如果內核都沒有編譯過,怎麼知道這些符號有沒有編入內核中

Hello World驅動實現全過程

1:首先要查看自己系統是使用的內核版本

www.linuxidc.com @linux:~$ uname -r

3.2.0-34-generic-pae //我用的是ubuntu12.04版本的,比較高

如果系統自動安裝了源碼。在/usr/src目錄下面會有對應的使用的版本,我那個版本沒有,我是自己下載的

www.linuxidc.com @linux:/usr/src$ ls

linux-headers-3.2.0-34 linux-source-3.2.0(我下載的)

linux-headers-3.2.0-34-generic-pae

如果沒有源碼,查看一下可以下載的源碼包(不要使用超級用戶使用此命令,他會提示沒有這個命令)

#apt-cache search linux-source

www.linuxidc.com @linux:/usr/src$ apt-cache search linux-source

linux-source - Linux kernel source with Ubuntu patches

linux-source-3.2.0 - Linux kernel source for version 3.2.0 with Ubuntu patches

2:然後下載linux-source-3.2.0

#sudo apt-get install linux-source-3.2.0

下載完成之後,會在/usr/src下,文件名為linux-source-3.2.0.tar.bz2這個壓縮包,解壓之後就可以得到整個源代碼

# sudo tar jxvf linux-source-3.2.0.tar.bz2

解壓之後會生成一個新的目錄/usr/src/linux-source-3.2.0,現在所有的源代碼都在裡面

3:現在開始配置內核,有三種選擇選擇方式1:make oldconfig 2:make menuconfig 3:make xconfig

我選擇的是最快的配置原版的配置方法

#sudo make oldconfig

(如果配置的過程中出現問題,原因是因為你沒有下載配置環境的那個依賴的庫文件,可以自己下載)

配置完成之後就要開始對內核進行編譯了

4:編譯內核

#sudo make

這個過程很漫長,建議去做做別別的事情吧~,我大概花了一個多小時,吃完晚飯回來就ok了

#sudo make zImage

編譯內核的結果最終出現了幾個錯誤,但最終對那個Hello World 沒有造成影響

執行結束之後,會在當前目錄下面生成一個新的文件:vmlinux

5:然後就是編譯模塊了

#sudo make modules

6:安裝模塊

#sudo make modules_install

執行結束之後,會在/lib/modules下生成一個新的目錄/lib/modules/3.2.31/

在隨後的編譯模塊文件時,需要用到這個路徑下的build目錄。到這一不,內核就編譯完成了

好了,下了很長時間的Hello World 程序現在終於可以派上用場了

我的Hello World在/hoem/xiongyao/下面


//hello.c

#include<linux/init.h> //初始換函數
#include<linux/kernel.h> //內核頭文件
#include<linux/module.h> //模塊的頭文件

MODULE_LICENSE("Xiongyao BSD/GPL");

static int hello_init(void)
{
printk(KERN_ALTER"Hello, world\n"); //模塊運行在內核態,不能使用用戶態C庫函數中的printf函數,而要使用printk函數
//打印調試信息
return 0;
}

static int hello_exit(void)
{
printk("KERN_ALTER"Goodbye,Hello world\n");
}
module_init(hello_init);
module_exit(hello_exit);


Makefile 文件

obj-m:=hello.o //生成目標文件
KERNELDIR:=/lib/modules/3.2.31/build
PWD :=$(shell pwd)

modules:
(這裡要用一個tab鍵)$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules
(這裡用一個tab鍵) $(MAKE) -C $(KERNELDIR)M=$(PWD) modules_install

最好關鍵的一步到了,所有准備就緒,進入makefile的那個目錄

www.linuxidc.com @linux:~$ sudo make
make -C /lib/modules/3.2.31/build M=/home/xiongyao
make[1]: 正在進入目錄 `/usr/src/linux-source-3.2.0/linux-source-3.2.0'
LD /home/xiongyao/built-in.o
CC [M] /home/xiongyao/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/xiongyao/hello.mod.o
LD [M] /home/xiongyao/hello.ko
make[1]:正在離開目錄 `/usr/src/linux-source-3.2.0/linux-source-3.2.0'

上面證明已經成功了

然後加載模塊
#sudo insmod ./hello.ko

本應該會在終端顯示hello,world 但是終端什麼也沒有顯示(以後在去解決)

查看加載模塊

#sudo lsmod

裡面已經生成了hello

hello 2560 0

^_^,已經加載上了

刪除模塊

#sudo rmmod hello

那麼程序的輸出到底在哪裡呢?在網上看到,如果不出現在終端,則會下進syslog中

#cat /var/log/syslog |grep world

#Hello,world
#Goodbye,linux world

現在所有工作全部完成了,希望做這個Hello World 是我進入linux驅動的第一步~,相信你們也能編譯的!成功的編譯成功的。

Copyright © Linux教程網 All Rights Reserved