加載TQ2440驅動-hello world 模塊

開發平臺:
ubuntu10.04,內核版本2.6.32-33-generic,
交叉編譯器:天嵌公司提供的arm-linux-gcc 4.3.3,
內核樹:/opt/EmbedSky/linux-2.6.30.4/

目標平臺:
天嵌公司的TQ2440開發板ARM9,內核版本2.6.30.4

 
1.      首先解壓天嵌公司提供的內核源碼包linux-2.6.30.4_20100531.tar.bz2,
tar xvfj linux-2.6.30.4_20100531.tar.bz2 –C /
-C是指定解壓目錄,後面的/代表在根目錄解壓歸檔文件。
之後內核樹會被解壓到/opt/EmbedSky/linux-2.6.30.4/
編譯內核:
cd /opt/EmbedSky/linux-2.6.30.4
cp config_EmbedSky_W35 .config
make zImage
在此,config_EmbdeSky_W35爲天嵌公司提供的內核配置文件,開始時可暫時拿來用。
至此,內核樹已經準備好了,這是編譯內核驅動模塊的前提工作,如果在自己的文件系統中沒有準備好內核樹,則無法構造可裝載的模塊。

2.      安裝交叉編譯器4.3.3
解壓天嵌公司提供的EABI-4.3.3_EmbedSky_20100610.tar.bz2,
tar xvfj EABI-4.3.3_EmbedSky_20100610.tar.bz2 –C /
之後交叉編譯器會被解壓到/opt/EmbedSky/4.3.3/,
修改環境變量配置文件/etc/environment,
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/EmbedSky/4.3.3/bin"
LANGUAGE="zh_CN:zh:en_US:en"
LANG="zh_CN.utf8"

使用命令
export PATH=$PATH:/opt/EmbedSky/4.3.3/bin
保存重啓即生效,若不想重啓可使用
source /etc/environment
但是此命令只對該終端生效,所以若沒其他問題,推薦重啓
 
3.編寫hello world 驅動模塊
cd /home/shanks/modules
mkdir hello
cd hello
驅動模塊不一定要放在內核樹裏,只要你的Makefile指定了內核樹的路徑就沒問題,所以我這裏在/home/shanks/裏建立了一個modules目錄專門用來開發驅動模塊

hello.c 源碼:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
   printk(KERN_ALERT "Hello, world\n");
   return 0;
}
 
static void hello_exit(void)
{
   printk(KERN_ALERT "Goodbye, cruel world\n");
   return 0;
}

module_init(hello_init);
module_exit(hello_exit);

Makefile:
KERNELDIR=/opt/EmbedSky/linux-2.6.30.4   
PWD:=$(shell pwd)   
INSTALLDIR=$(PWD)    
CC=arm-linux-gcc  
obj-m := hello.o   
modules:   
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules   
clean:   
    rm -rf *.o *.ko *.mod.c *.markers *.order *.symvers   
.PHONY:modules clean  
這裏有必要解釋一下驅動模塊的Makefile編寫方法,需要注意的是:
obj-m := hello.o   

擴展語法,說明有一個模塊需要從目標文件hello.o中構造,模塊名稱爲hello.ko

   $(MAKE) -C $(KERNELDIR) M=$(PWD) modules   

上述命令首先改變目錄到-C選項指定位置(即目錄源代碼目錄),其中保存有內核的頂層文件。M=選項讓內核頂層的Makefile在構造modules目標之前返回到模塊源代碼目錄。然後,開始第二次讀取PWD中的Makefile,modules目標指向obj-m變量中設定的模塊,而內核的Makefile負責真正構造模塊。

然後,
make
生成了幾個文件,其中hello.ko就是我們需要的用來加載的模塊文件。
這裏注意,make之前必須要先準備好內核樹,否則make會出錯。
連上開發板,這裏我把PC的根目錄掛載到板子的/mnt下,
cp /mnt/home/shanks/modules/hello/hello.ko/tmp
cd /tmp
好了,加載模塊!

[root@EmbedSky /tmp]# insmod hello.ko
Hello, world
[root@EmbedSky /tmp]# rmmod hello

Goodbye, cruel world

完成!


insmod時可能出現的錯誤:


I.

hello: version magic '2.6.30.4 mod_unload ARMv4 ' should be'2.6.30.4-EmbedSky mod_unload ARMv4 '
insmod: cannot insert 'hello.ko': invalid module format

出錯原因:模塊版本與內核版本不匹配!
解決辦法:導入預設配置信息,進入menuconfig 繼續配置General config ->( )Local version -> 括號中加入如下內容:“-EmbedSky”退出保存爲 .config ,重新編譯內核、驅動模塊,再來加載模塊

 

ii.

hello: Unknown symbol__aeabi_unwind_cpp_pr0
insmod: cannot insert 'hello.ko': unknown symbol in module, or unknown
parameter

出錯原因:模塊和內核鏡像不匹配

解決方法:儘量用和你同時用來編譯驅動而生成的內核鏡像zImage,zImage燒到板子上。Ldd3上有句話:儘管並不是必需的,但最好運行和模塊對應的內核。


剛開始學驅動,終於成功加載了hello world 模塊!
這是學習驅動的一小步,但是對我來說卻是一大步!












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章