linux驅動 第一個驅動

首先引用一篇文章 http://blog.csdn.net/zqixiao_09/article/details/50838043linux

1.我先寫好一個驅動hello.cshell

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
/* 加載模塊時調用的函數 */
static int hello_init(void)
{
    printk(KERN_ALERT "world\n");//KERN_ALERT 0 報告消息,表示必須當即採起措施
    return 0;
}
/* 卸載模塊時調用的函數 */
static void hello_exit(void)
{
    printk(KERN_ALERT "goodbye\n");
}

/* 註冊模塊入口和出口 */
module_init(hello_init);
module_exit(hello_exit);


MODULE_AUTHOR("ZQH");
MODULE_DESCRIPTION("a simple module");
MODULE_ALIAS("first module");

 

2.編寫Makefile函數

ifneq  ($(KERNELRELEASE),)
obj-m:=hello.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.symvers *.cmd *.cmd.o
endif

(1)KERNELRELEASE           在linux內核源代碼中的頂層makefile中有定義ui

(2)shell pwd                             取得當前工做路徑spa

(3)shell uname -r                    取得當前內核的版本號.net

(4)KDIR                                     當前內核的源代碼目錄。code

 

make 的的執行步驟blog

a -- 第一次進來的時候,宏「KERNELRELEASE」未定義,所以進入 else;ci

b -- 記錄內核路徑,記錄當前路徑;開發

       因爲make 後面沒有目標,因此make會在Makefile中的第一個不是以.開頭的目標做爲默認的目標執行。默認執行all這個規則

c -- make -C $(KDIR) M=$(PWD) modules

     -C 進入到內核的目錄執行Makefile ,在執行的時候KERNELRELEASE就會被賦值,M=$(PWD)表示返回當前目錄,再次執行makefile,modules 編譯成模塊的意思

     因此這裏實際運行的是

     make -C /lib/modules/2.6.13-study/build M=/home/fs/code/1/module/hello/ modules

d -- 再次執行該makefile,KERNELRELEASE就有值了,就會執行obj-m:=hello.o

     obj-m:表示把hello.o 和其餘的目標文件連接成hello.ko模塊文件,編譯的時候還要先把hello.c編譯成hello.o文件

 

能夠看出make在這裏一共調用了3次

3.編譯 

zqh@linux:~/Desktop/hello$ make
make -C /lib/modules/4.13.0-36-generic/build M=/home/zqh/Desktop/hello modules
make[1]: Entering directory '/usr/src/linux-headers-4.13.0-36-generic'
  CC [M]  /home/zqh/Desktop/hello/hello.o
/home/zqh/Desktop/hello/hello.c:4:12: warning: ‘hello_init’ defined but not used [-Wunused-function]
 static int hello_init(void)
            ^
/home/zqh/Desktop/hello/hello.c:10:13: warning: ‘hello_exit’ defined but not used [-Wunused-function]
 static void hello_exit(void)
             ^
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/zqh/Desktop/hello/hello.mod.o
  LD [M]  /home/zqh/Desktop/hello/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.13.0-36-generic'

4.加載模塊 卸載模塊

zqh@linux:~/Desktop/hello$ su
root@linux:/home/zqh/Desktop/hello# insmod hello.ko 
root@linux:/home/zqh/Desktop/hello# rmmod hello
root@linux:/home/zqh/Desktop/hello# dmesg | tail
[  396.867685] pcieport 0000:00:1c.0: BAR 15: assigned [mem 0xf2400000-0xf25fffff 64bit pref]
[  396.867702] pcieport 0000:00:1c.1: BAR 15: assigned [mem 0xf2600000-0xf27fffff 64bit pref]
[  396.867708] pcieport 0000:00:1c.0: BAR 13: assigned [io  0x2000-0x2fff]
[  396.867713] pcieport 0000:00:1c.1: BAR 13: assigned [io  0x3000-0x3fff]
[ 2964.543768] hello: loading out-of-tree module taints kernel.
[ 2964.543814] hello: module verification failed: signature and/or required key missing - tainting kernel
[ 3980.513820] world
[ 4000.782155] goodbye

 5.交叉編譯到嵌入式開發板

#General Purpose Makefile for cross compile Linux Kernel module
ifneq ($(KERNELRELEASE),)
obj-m := hello.o  #+=是鏈接字符串
else

ARCH := arm    
CROSS_COMPILE := arm-linux-gnueabihf-
KERN_DIR := /home/zqh/lichee/linux-zero-4.14.y  #選擇內核路徑
PWD :=$(shell pwd)   #當前路徑

all:
        make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) modules    

clean:                                   
        make -C $(KERN_DIR) M=$(shell pwd) modules clean
        rm -rf modules.order
endif

相似這個makefile的配置便可

相關文章
相關標籤/搜索