日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 驱动开发之内核模块开发 (二)—— 内核模块编译 Makefile 入门

發(fā)布時(shí)間:2023/12/9 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 驱动开发之内核模块开发 (二)—— 内核模块编译 Makefile 入门 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、模塊的編譯

? ? ???我們?cè)谇懊鎯?nèi)核編譯中驅(qū)動(dòng)移植那塊,講到驅(qū)動(dòng)編譯分為靜態(tài)編譯動(dòng)態(tài)編譯靜態(tài)編譯即為將驅(qū)動(dòng)直接編譯進(jìn)內(nèi)核,動(dòng)態(tài)編譯即為將驅(qū)動(dòng)編譯成模塊

而動(dòng)態(tài)編譯又分為兩種:

a -- 內(nèi)部編譯

? ? ? ?在內(nèi)核源碼目錄內(nèi)編譯

b -- 外部編譯

? ? ? ?在內(nèi)核源碼的目錄外編譯


二、具體編譯過程分析 ??

? ? ? ??注:本次編譯是外部編譯,使用的內(nèi)核源碼是Ubuntu 的源代碼,而非開發(fā)板所用linux 3.14內(nèi)核源碼,運(yùn)行平臺(tái)為X86。

? ? ? ? 對(duì)于一個(gè)普通的linux設(shè)備驅(qū)動(dòng)模塊,以下是一個(gè)經(jīng)典的makefile代碼,使用下面這個(gè)makefile可以完成大部分驅(qū)動(dòng)的編譯,使用時(shí)只需要修改一下要編譯生成的驅(qū)動(dòng)名稱即可。只需修改obj-m的值。

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、makefile 中的變量

? ? 先說明以下makefile中一些變量意義:

(1)KERNELRELEASE? ? ? ? ???在linux內(nèi)核源代碼中的頂層makefile中有定義

(2)shell pwd ? ? ? ? ? ? ? ? ? ? ? ? ? ??取得當(dāng)前工作路徑

(3)shell uname -r ? ? ? ? ? ? ? ? ? ?取得當(dāng)前內(nèi)核的版本號(hào)

(4)KDIR? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?當(dāng)前內(nèi)核的源代碼目錄。

關(guān)于linux源碼的目錄有兩個(gè),分別為

?"/lib/modules/$(shell uname -r)/build"

"/usr/src/linux-header-$(shell uname -r)/"

? ? ? ?但如果編譯過內(nèi)核就會(huì)知道,usr目錄下那個(gè)源代碼一般是我們自己下載后解壓的,而lib目錄下的則是在編譯時(shí)自動(dòng)copy過去的,兩者的文件結(jié)構(gòu)完全一樣,因此有時(shí)也將內(nèi)核源碼目錄設(shè)置成/usr/src/linux-header-$(shell uname -r)/。關(guān)于內(nèi)核源碼目錄可以根據(jù)自己的存放位置進(jìn)行修改。

(5)make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules

這就是編譯模塊了:

a -- 首先改變目錄到-C選項(xiàng)指定的位置(即內(nèi)核源代碼目錄),其中保存有內(nèi)核的頂層makefile;

b -- M=選項(xiàng)讓該makefile在構(gòu)造modules目標(biāo)之前返回到模塊源代碼目錄;然后,modueles目標(biāo)指向obj-m變量中設(shè)定的模塊;在上面的例子中,我們將該變量設(shè)置成了hello.o。


2、make 的的執(zhí)行步驟

a --?第一次進(jìn)來的時(shí)候,宏“KERNELRELEASE”未定義,因此進(jìn)入 else;

b -- 記錄內(nèi)核路徑,記錄當(dāng)前路徑;

? ? ? ?由于make 后面沒有目標(biāo),所以make會(huì)在Makefile中的第一個(gè)不是以.開頭的目標(biāo)作為默認(rèn)的目標(biāo)執(zhí)行。默認(rèn)執(zhí)行all這個(gè)規(guī)則

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

??? ?-C 進(jìn)入到內(nèi)核的目錄執(zhí)行Makefile ,在執(zhí)行的時(shí)候KERNELRELEASE就會(huì)被賦值,M=$(PWD)表示返回當(dāng)前目錄,再次執(zhí)行makefile,modules 編譯成模塊的意思

? ? ?所以這里實(shí)際運(yùn)行的是

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

d -- 再次執(zhí)行該makefile,KERNELRELEASE就有值了,就會(huì)執(zhí)行obj-m:=hello.o

? ? ?obj-m:表示把hello.o 和其他的目標(biāo)文件鏈接成hello.ko模塊文件,編譯的時(shí)候還要先把hello.c編譯成hello.o文件


可以看出make在這里一共調(diào)用了3次

???1)-- make
???2)-- linux內(nèi)核源碼樹的頂層makedile調(diào)用,產(chǎn)生。o文件
???3)-- linux內(nèi)核源碼樹makefile調(diào)用,把.o文件鏈接成ko文件


3、編譯多文件

若有多個(gè)源文件,則采用如下方法:

obj-m := hello.o

hello-objs := file1.o file2.o file3.o


三、內(nèi)部編譯簡(jiǎn)單說明

? ? ? ? 如果把hello模塊移動(dòng)到內(nèi)核源代碼中。例如放到/usr/src/linux/driver/中, KERNELRELEASE就有定義了。

? ? ?在/usr/src/linux/Makefile中有KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)。

這時(shí)候,hello模塊也不再是單獨(dú)用make編譯,而是在內(nèi)核中用make modules進(jìn)行編譯,此時(shí)驅(qū)動(dòng)模塊便和內(nèi)核編譯在一起。

總結(jié)

以上是生活随笔為你收集整理的Linux 驱动开发之内核模块开发 (二)—— 内核模块编译 Makefile 入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。