這些天在學習linux內核編程,就在這裏小小的show以下。

首先編寫如下的linux代碼。並命名為hello.c

這裏你應該註意亮點:

第一、linux內核編程,不同於普通的用戶態下的編程;有一個入口的main函數;這裏的“main”函數是module_init();同時還有一個善後處理的函數:module_exit()。

第二、linux內核編程在編譯的時候,不同於用戶態下的編程;可以直接使用gcc編譯器編譯鏈接,就能夠成為可執行的;而是需要編寫一個Makefile文件,不是makefile!!這裏牽扯到很多的內核態下的東西,具體的我也沒弄清楚!詳細的會在後面和大家分享。


hello.c  文件

1 #include <linux/module.h>

2 #include <linux/kernel.h>

3 #include <linux/init.h>

4 static int __init lkp_init(void);

5 static int __exit lkp_exit(void);

6

7

8 static int __init lkp_init(void)

9 {

10 printk("<1>Hello ,Word!\n");

11 return 0;

12 }

13

14 static int __exit lkp_exit(void)

15 {

16 printk("<2>Hello,Word exit\n");

17 }

18 module_init(lkp_init);

19 module_exit(lkp_exit);


並在hello.c的同一目錄下建立Makefile文件。

Makefile文件:

1 ifneq ($(KERNELRELEASE),)

2 mymodule-objs:= hello.c

3 obj-m += hello.o

4

5 else

6 PWD :=$(shell pwd)

7 KVER := $(shell uname -r)

8 KDIR :=/lib/modules/$(KVER)/build

9

10 all:

11 $(MAKE) -C $(KDIR) M=$(PWD)

12 clean:

13 rm -rf *.o *.mod.c *.ko *.symvers *order *.markers *-

14 endif

說明:

當命令在執行make時,將調用Makefile文件。KERNELRELEASE 是在內核源代碼的頂層/usr/src/linux-headers-2.6.32-33/Makefile 文件中定義的一個變量。讀者如果下載的是linux-3.0的內核的話在**/linux-3.0/Makefile。當中的380行。如下:


379 # Read KERNELRELEASE from include/config/kernel.release (if it exists)

380 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)

381 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL) ,.$(SUBLEVEL)))$(EXTRAVERSION)

在第一次讀取執行此Makefile時,變量$(KERNELRELEASE) 並沒有被設置,因此第一行ifneq的條件失敗,從else後面的開始執行,設置PWD、KVER、KDIR等變量。

當make遇到標號all時,-C$(KDIR)指名跳轉到內核源碼目錄下讀取那裏的Makefile。M=$(PWD),表明返回到當前的目錄進行繼續讀入,執行當前的Makefile,也就是第二次調用make。這時的變量$(KERNELRELEASE) 已經被定義,因此ifneq成功,make將繼續讀取緊接在ifneq後面的內容。ifneq的內容為kbuild語句,指名模塊源碼中個文件之間的依賴關系和要生成的目標模塊

語句  2 mymodule-objs:= hello.c  表是mymodule.o 由hello.c生成。 語句3 obj-m += hello.o表是鏈接後將生成mymodule.ko模塊,這個文件就是要插入內核的模塊文件。

如果make的目標是clean,直接執行clean標號之後的操作,刪除 一大堆的東西!執行文clean後面的rm命令之後,make整個工作就結束了!


執行效果:

[#35#caopeng@laptop:~]$cd kernel/

[#36#caopeng@laptop:~/kernel]$ls

hello.c Makefile

[#37#caopeng@laptop:~/kernel]$make

make -C /lib/modules/2.6.32-33-generic/build M=/home/caopeng/kernel

make[1]: 正在進入目錄 `/usr/src/linux-headers-2.6.32-33-generic'

LD /home/caopeng/kernel/built-in.o

CC [M] /home/caopeng/kernel/hello.o

/home/caopeng/kernel/hello.c: In function ‘lkp_exit’:

/home/caopeng/kernel/hello.c:17: warning: no return statement in function returning non-void

/home/caopeng/kernel/hello.c: In function ‘__exittest’:

/home/caopeng/kernel/hello.c:19: warning: return from incompatible pointer type

Building modules, stage 2.

MODPOST 1 modules

CC /home/caopeng/kernel/hello.mod.o

LD [M] /home/caopeng/kernel/hello.ko

make[1]:正在離開目錄 `/usr/src/linux-headers-2.6.32-33-generic'

[#38#caopeng@laptop:~/kernel]$

編譯成功!!

查看當前目錄下的文件,會發現多了很多東西!如下:

[#38#caopeng@laptop:~/kernel]$ls

built-in.o hello.ko hello.mod.o Makefile Module.symvers

hello.c hello.mod.c hello.o modules.order

[#39#caopeng@laptop:~/kernel]$

這裏不知道為什麽生成的文件都沒有x權限!這裏要用到的就是hello.ko給其加上可執行權限。並使用insmod將其插入!然後用命令查看結果!

[#47#caopeng@laptop:~/kernel]$sudo rmmod hello.ko

[#48#caopeng@laptop:~/kernel]$sudo insmod hello.ko

[#49#caopeng@laptop:~/kernel]$dmesg -c

klogctl: 不允許的操作

[#50#caopeng@laptop:~/kernel]$sudo dmesg -c

[14651.331364] Hello,Word exit

[14658.553284] Hello ,

[#51#caopeng@laptop:~/kernel]$

最後要記得rmmod!!!


原文:http://blog.udn.com/q16964/37051143

文章標籤
全站熱搜
創作者介紹
創作者 成功运行 的頭像
成功运行

成功运行的部落格

成功运行 發表在 痞客邦 留言(0) 人氣(101)