開發平台:
Ubuntu 10.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/
編譯內核:
在此,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 驅動模塊
驅動模塊不一定要放在內核樹裡,只要你的Makefile指定了內核樹的路徑就沒問題,所以我這裡在/home/shanks/裡建立了一個modules目錄專門用來開發驅動模塊
hello.c 源碼:
Makefile:
然後,
make
生成了幾個文件,其中hello.ko就是我們需要的用來加載的模塊文件。
這裡注意,make之前必須要先准備好內核樹,否則make會出錯。
連上開發板,這裡我把PC的根目錄掛載到板子的/mnt下,
好了,加載模塊!
[[email protected] /tmp]# insmod hello.ko
Hello, world
[[email protected] /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 模塊!
這是學習驅動的一小步,但是對我來說卻是一大步!