Linux驅動開發入門 demo

驅動開發時候,儘量選擇對應操作系統內核的Linux系統作爲上位機平臺

 

下載源碼與編譯

源碼的下載可以從網站:https://mirrors.edge.kernel.org/pub/linux/kernel/

找到對應的內核版本,然後下載,通過make menuconfig和make,進行編譯。

沒有編譯過的內核,驅動開發過程中進行編譯可能有錯誤,找不到文件等。

 

編寫一個最簡單的驅動

如下是hello.c文件的驅動程序。其中聲明瞭證書,和模塊加載後與退出時應該執行的函數。

#include<linux/module.h>
#include<linux/kernel.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,world\n");
}
module_init(hello_init);
module_exit(hello_exit);

  

編寫Makefile文件

Makefile文件的編寫如下,主要是KERNELDIR,爲linux源碼的位置

ifeq ($(KERNELRELEASE),)
        KERNELDIR ?= /usr/src/linux-source-5.4.0
        PWD := $(shell pwd)
modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
else
        obj-m := hello.o
endif

  

修改部分信息和執行

當編譯的內核爲系統本身的內核,但是make以後生成的ko文件無法加載,即通過insmod xxx.ko無法加載,格式不對

查看dmesg信息,參考解決:https://www.cnblogs.com/blfbuaa/p/6907027.html

正常執行後再dmesg中會有相應的加載和卸載模塊的message信息。卸載命令爲rmmod xxx

 

模塊之間的依賴通信

以下爲add_sub.c

#include<linux/kernel.h>
#include<linux/module.h>
#include"add_sub.h"
long add_integer(long a,long b)
{
        printk(KERN_ALERT "add init");
        return a+b;
}
long sub_integer(long a,long b)
{
        printk(KERN_ALERT "sub init");
        return a-b;
}
EXPORT_SYMBOL(add_integer);
EXPORT_SYMBOL(sub_integer);
MODULE_LICENSE("Dual BSD/GPL");

以下爲add_sub.h

#ifndef _ADD_SUB_H_
#define _ADD_SUB_H_
long add_integer(long a,long b);
long sub_integer(long a,long b);
#endif

以下爲Makefile,當執行完make後,則生成了符號表文件,其爲Module.symvers,該文件可以用於其他文件的函數引用

ifeq ($(KERNELRELEASE),)
        KERNELDIR ?= /usr/src/linux-source-5.4.0
        PWD := $(shell pwd)
        PRINT_INC =$(PWD)/../include
        EXTRA_CFLAGS += -I $(PRINT_INC)
modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
else
        obj-m := add_sub.o
endif

以下爲test.c

#include<linux/kernel.h>
#include<linux/module.h>
#include"../add_sub.h"
static long a = 1;
static long b = 1;
static int AddOrSub = 1;
static int test_init(void)
{
        long result = 0;
        printk(KERN_ALERT "test init\n");
        if (1 == AddOrSub)
        {
                result = add_integer(a,b);
        }
        else
        {
                result = sub_integer(a,b);
        }
        //printk(KERN_ALERT, "the %s result is %ld", AddOrSub==1?"Add":"Sub",result);
        return 0;
}
static void test_exit(void)
{
        printk(KERN_ALERT, "test_exit");
}
module_init(test_init);
module_exit(test_exit);
module_param(a,long,S_IRUGO);
module_param(b,long,S_IRUGO);
module_param(AddOrSub,int,S_IRUGO);
MODULE_LICENSE("Dual BSD/GPL");

以下爲test.c的Makefile

ifeq ($(KERNELRELEASE),)
        KERNELDIR ?= /usr/src/linux-source-5.4.0
        PWD := $(shell pwd)
KBUILD_EXTRA_SYMBOLS=$(obj)/../print/Module.symvers
modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
else
        obj-m := test.o
endif

編譯完後,需要先掛載add_sub模塊,然後再掛載test模塊。

未得到預期的效果,主要是在順次加載後,並在加載過程添加a,b等參數,無法從dmesg中獲得一個調用輸出

 

將模塊編譯到內核中

如在drivers下建立add_sub_Kconfig文件夾,然後放入對應的源碼文件,對應的Makefile和Kconfig文件。其中Kconfig文件用於make menuconfig的索引,其和上層的Kconfig關聯

 

 

 Makefile文件內容如下:

obj-$(CONFIG_ADD_SUB)+=add_sub.o
obj-$(CONFIG_TEST)+=test.o

Kconfig文件內容如下:

#
# add_sub configuration
#

menu "ADD_SUB"
        comment "ADD_SUB"
config CONFIG_ADD_SUB
        tristate "ADD_SUB support"
        default y

config CONFIG_TEST
        tristate "ADD_SUB test support"
        depends on CONFIG_ADD_SUB
        default y
endmenu

然後修改上層的Kconfig文件,添加如下內容:

Source "drivers/add_sub_Kconfig/Kconfig"

然後修改上層的Makefile文件,添加如下內容:

obj-$(ADD_SUB)                  += add_sub_Kconfig/

就可以在主目錄下執行make menuconfig後,在驅動下找到對應的驅動和編譯信息了

 

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