歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Ubuntu下Hello World驅動實現全過程

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

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

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