02.驅動模塊編譯+驅動編譯到內核


第一種方法:

把驅動編譯成模塊,然后使用命令把驅動加載到內核里面

第二種方法:

直接把驅動編譯到內核

 

 

編譯成模塊

第一步:先寫一個Makefile

obj-m +=helloworld.o #obj-m表示把驅動編譯成模塊,生成的中間文件名字為helloworld.o

KDIR:=/home/topeet/topeet/imx6ull/linux-imx-rel_imx_4.1.15_2.1.0_ga #指定內核路徑

PWD?=$(shell pwd) #獲取當前目錄變量

all:
    make -C $(KDIR) M=$(PWD) modules #make進入到內核源碼路徑因為編譯需要這個環境,把當前路徑代碼編譯成模塊

第二步:編譯驅動

編譯驅動之前需要注意的問題:

1、內核源碼一定要先編譯通過

2、我們編譯驅動模塊用的內核源碼一定要和我們開發板上運行的內核鏡像是同一套

3、看一下我們Ubuntu的環境是不是arm。 

 

 

打開ubuntu內核源碼路徑下輸入

make menuconfig

 

 此處查看到ubuntu是x86,需要改成arm

輸入

export ARCH=arm

再查看

make menuconfig

 此時變為arm。

上述過程也可直接通過下面指令查看

echo $ARCH

 

 

對於3的總結:編譯的終端窗口要設置ARCH和CROSS_COMPILE

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-

 

 然后把helloworld.c拷貝到Makefile路徑下執行make即可編譯。

helloworld.ko文件就是編譯的驅動模塊。

 

接下來在開發板上測試編譯好的驅動模塊:

在開發板上加載驅動模塊在開發板上輸入以下命令

insmod helloworld.ko

 在開發板上也可以查看我們加載的模塊

lsmod

卸載驅動模塊,使用rmmod命令,注意沒有ko的后綴

rmmod helloworld

再使用lsmod也可以看到卸載成功。

以上幾步現象如下圖:

 

 可以看到現象,加載和卸載模塊時打印出了上一小節中的hello world 和byebye語句。

 

編譯到內核

Kconfig講解

Kconfig截取一段代碼作為例子

 

 

 1、source "drivers/redled/Kconfig"

  它會包含drivers/redled/路徑下的驅動文件,方便我們對菜單進行管理

2、config LED_4412

  配置選項的名稱,CONFIG_LED_4412 (大寫的CONFIG省略了)

3、tristate表示驅動的狀態,把驅動編譯成模塊,把驅動編譯到內核,不編譯

  與之對應的還有bool分別是編譯到內核,不編譯

  "Led Support for GPIO Led" make menuconfig顯示的名字

  A depends on B

  表示只有在選擇B的時候才可以選擇A

4、比如我想直接去掉LED相關的驅動,我們直接改.config文件可以嗎?

  可以,但是不推薦。如果有依賴的話,直接修改.config是不成功的。

5、select

  反向依賴,該選項被選中時,后面的定義也會被選中。

6、help

  This option enable support for led

  幫助信息

 

實驗:把01小節中helloworld.c驅動編譯到內核

以下操作目錄都基於內核根目錄的相對路徑

1、在/drivers/char/路徑建立一個hello文件夾

  hello文件夾中需要有Makefile、Kconfig、helloworld.c

  helloworld.c是01小節的驅動。

  

#include <linux/init.h>   //包含宏定義的頭文件
#include <linux/module.h> //包含初始化加載模塊的頭文件    

static int hello_init(void)
{
    printk("hello world\n"); 
    return 0;
}


static int hello_exit(void)
{
    printk("bye bye\n"); 
    return 0;
}  

module_init(hello_init);//模塊入口
module_exit(hello_exit);//模塊出口

MODULE_LICENSE("GPL");

 

  Makefile內容如下

  

 

   obj-$(CONFIG_HELLO)表示可以在make menuconfig界面通過空格選擇是編譯到內核或者編譯成模塊或者不編譯。

  如果選擇*就是obj-y,編譯到內核,如果選擇M就是obj-m,編譯成模塊。

  CONFIG_HELLO是根據Kconfig中的 第一行config HELLO來的,Kconfig中省略了CONFIG_

  Kconfig內容如下:

  

 

2、要讓hello上一級/drivers/char/Makefile包含這個hello文件夾,以便編譯

 

 此處注意hello是文件夾,所以后面要加"/",否則編譯出錯。

3、要讓上一級文件夾的/drivers/char/Kconfig文件包含hello文件夾的Kconfig

 

 

 4、到內核根目錄執行make menuconfig,將hello world設置為編譯到內核,然后保存

 

 保存后可以查看.config文件,發現CONFIG_HELLO已經配置進去了

 CONFIG_HELLO=y 即剛剛設置的編譯到內核,如果選擇的是編譯成模塊則顯示 CONFIG_HELLO=m

 5、重新編譯內核

   重新編譯內核之前可以通過以下命令清除之前編譯的所有內容

make distclean

   之后編譯內核即可。

   編譯后發現arch/arm/boot下面生成了zImage。編譯成功。

6、燒錄到開發板觀察現象

  發現開機啟動信息中打印了驅動程序中的hello world,說明成功編譯到內核。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM