創(chuàng)建內(nèi)核模塊
Petalinux可以幫助工程師簡(jiǎn)化內(nèi)核模塊的創(chuàng)建工作。在petalinux工程目錄下,使用命令“ petalinux-create -t modules --name --enable”,能創(chuàng)建Linux內(nèi)核模塊,包括c源代碼文件,Makefile,Yocto的bb文件。相關(guān)文件放在目錄“ project-spec / meta-user / recipes-modules”中,目錄結(jié)構(gòu)如下。
hankf@XSZGS4:~/proj/vcu-trd-2020.2-peta-qt/project-spec/meta-user/recipes-modules$ tree
.
└── linux-test-module
├── files
│ ├── COPYING
│ ├── linux-test-module.c
│ └── Makefile
├── linux-test-module.bb
└── README
2 directories, 5 files
Makefile
原始Makefile
原始的Makefile只支持一個(gè)源文件,內(nèi)容如下:
obj-m := linux-module-module.o
MY_CFLAGS += -g -DDEBUG
ccflags-y += ${MY_CFLAGS}
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
原始的Makefile,支持模塊在內(nèi)核源碼目錄外編譯。編譯的命令是“$(MAKE) -C $(KERNEL_SRC) M=$(SRC)”。其中-C選項(xiàng)將當(dāng)前工作目錄轉(zhuǎn)移到指定的位置;KERNEL_SRC是Yocto/PetaLinux在文件components/yocto/layers/core/meta/classes/module.bbclass里定義的變量,指定了Linux內(nèi)核源代碼目錄,一般是Petalinux工程目錄下的子目錄“build/tmp/work-shared/zynqmp-generic/kernel-source”。這樣編譯時(shí)先進(jìn)入內(nèi)核源代碼目錄,先執(zhí)行其中的頂層Makefile。M是內(nèi)核根目錄下的Makefile中使用的變量,讓make在構(gòu)造modules目標(biāo)之前返回到內(nèi)核模塊源的代碼目錄。
Linux內(nèi)核頂層Makefile關(guān)于M變量的代碼:
# Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the
# directory of external module to build. Setting M= takes precedence.
ifeq ("$(origin M)", "command line")
KBUILD_EXTMOD := $(M)
endif
module.bbclass里定義的變量KERNEL_SRC的代碼:
python do_devshell_prepend () {
os.environ['CFLAGS'] = ''
os.environ['CPPFLAGS'] = ''
os.environ['CXXFLAGS'] = ''
os.environ['LDFLAGS'] = ''
os.environ['KERNEL_PATH'] = d.getVar('STAGING_KERNEL_DIR')
os.environ['KERNEL_SRC'] = d.getVar('STAGING_KERNEL_DIR')
os.environ['KERNEL_VERSION'] = d.getVar('KERNEL_VERSION')
os.environ['CC'] = d.getVar('KERNEL_CC')
os.environ['LD'] = d.getVar('KERNEL_LD')
os.environ['AR'] = d.getVar('KERNEL_AR')
os.environ['O'] = d.getVar('STAGING_KERNEL_BUILDDIR')
kbuild_extra_symbols = d.getVar('KBUILD_EXTRA_SYMBOLS')
if kbuild_extra_symbols:
os.environ['KBUILD_EXTRA_SYMBOLS'] = kbuild_extra_symbols
else:
os.environ['KBUILD_EXTRA_SYMBOLS'] = ''
}
語(yǔ)句“obj-m := linux-test-module.o”指示Kbuild將模塊編譯成Linux內(nèi)核模塊文件linux-test-module.ko。
更多信息可以參考相關(guān)文檔,比如深入理解 Linux 配置/構(gòu)建系統(tǒng)是如何工作的,LINUX內(nèi)核編譯學(xué)習(xí)筆記, Linux 內(nèi)核模塊編譯 Makefile, Linux 2.6內(nèi)核Makefile淺析。
多源文件Makefile
如果有多個(gè)源文件,也可以學(xué)習(xí)Linux內(nèi)核模塊的Makefile寫(xiě)法,使Petalinux的內(nèi)核模塊也支持多個(gè)源文件。Linux內(nèi)核通過(guò)$(-objs)包含多個(gè)目標(biāo)文件,使Kbuild編譯多個(gè)源文件。因此在支持新Makefile里,增加了objs語(yǔ)句。首先通過(guò)TEST_FILES列出所有C文件,再將C文件替換成Obj文件賦值給$(TEST_MODULE_NAME)-objs 。
export TEST_MODULE_NAME = linux-test-module
export TEST_FILES = linux-test-module.c linux-test-module-internal.c
$(TEST_MODULE_NAME)-objs = $(patsubst %.c,%.o,$(filter %.c,$(TEST_FILES)))
obj-m += $(TEST_MODULE_NAME).o
MY_CFLAGS += -g -DDEBUG
ccflags-y += ${MY_CFLAGS}
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
內(nèi)核源碼目錄內(nèi)Makefile
有時(shí)內(nèi)核模塊也需要在Linux內(nèi)核源碼目錄內(nèi)編譯,不需要指定編譯命令。KERNELRELEASE是Linux內(nèi)核源碼的頂層Makefile定義的一個(gè)變量。如果在內(nèi)核源碼目錄內(nèi)編譯,先執(zhí)行Linux內(nèi)核源碼的頂層Makefile,會(huì)定義KERNELRELEASE的具體值。如果加上對(duì)KERNELRELEASE的檢查,前面的Makefile可以改造成既可以在在內(nèi)核源碼目錄內(nèi)編譯,也可以在在內(nèi)核源碼目錄外編譯。下面的Makefile,增加了檢查KERNELRELEASE的語(yǔ)句“ifeq ($(KERNELRELEASE),)”。
export TEST_MODULE_NAME = linux-test-module
export TEST_FILES = linux-test-module.c linux-test-module-internal.c
$(TEST_MODULE_NAME)-objs = $(patsubst %.c,%.o,$(filter %.c,$(TEST_FILES)))
obj-m += $(TEST_MODULE_NAME).o
MY_CFLAGS += -g -DDEBUG
ccflags-y += ${MY_CFLAGS}
ifeq ($(KERNELRELEASE),)
SRC := $(shell pwd)
# KERNEL_src=/proj/hankf/zcu106/rdf0428-zcu106-vcu-trd-2020.2/source/linux-kernel
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
endif
實(shí)際測(cè)試中,不加KERNELRELEASE相關(guān)語(yǔ)句,也不影響在Linux內(nèi)核源碼目錄內(nèi)編譯。據(jù)說(shuō)舊版本Kbuild才需要的KERNELRELEASE相關(guān)語(yǔ)句。
上面的Makefile文件也可以作為一個(gè)模板。只需要更改TEST_MODULE_NAME的值“l(fā)inux-test-module”,和更改TEST_FILES后的文件列表,可以用于編譯其它模塊。
如果既不在PetaLinux環(huán)境里編譯,也不再Linux內(nèi)核源碼目錄內(nèi)編譯,請(qǐng)?jiān)僭谏厦娴腗akefile文件里定義內(nèi)核源碼目錄。
Yocto recipe文件
Yocto recipe文件的擴(kuò)展名是.bb,它定義recipe需要的文件。
原始bb文件
原始的recipe的bb文件的只含有一個(gè)C文件。
SUMMARY = "Recipe for build an external linux-test-module Linux kernel module"
SECTION = "PETALINUX/modules"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e"
inherit module
INHIBIT_PACKAGE_STRIP = "1"
SRC_URI = "file://Makefile
file://linux-test-module.c
file://COPYING
"
S = "${WORKDIR}"
# The inherit of module.bbclass will automatically name module packages with
# "kernel-module-" prefix as required by the oe-core build environment.
新bb文件
由于要支持多個(gè)源文件,需要在recipe的bb文件的添加所有C文件。修改其實(shí)也很簡(jiǎn)單。下面的bb文件添加了行“file://linux-test-module-internal.c”以為Yocto/PetaLinux增加文件linux-test-module-internal.c。
SUMMARY = "Recipe for build an external linux-test-module Linux kernel module"
SECTION = "PETALINUX/modules"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e"
inherit module
INHIBIT_PACKAGE_STRIP = "1"
SRC_URI = "file://Makefile
file://linux-test-module.c
file://linux-test-module-internal.c
file://COPYING
"
S = "${WORKDIR}"
# The inherit of module.bbclass will automatically name module packages with
# "kernel-module-" prefix as required by the oe-core build environment.
測(cè)試環(huán)境UBuntu 18.04
PetaLinux 2020.2
原文標(biāo)題:【工程師分享】在Petalinux編譯多個(gè)源文件的Linux內(nèi)核模塊,以及擴(kuò)展Makefile功能
文章出處:【微信公眾號(hào):FPGA開(kāi)發(fā)圈】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
責(zé)任編輯:haq
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1378瀏覽量
40343 -
Linux
+關(guān)注
關(guān)注
87文章
11327瀏覽量
209966
原文標(biāo)題:【工程師分享】在Petalinux編譯多個(gè)源文件的Linux內(nèi)核模塊,以及擴(kuò)展Makefile功能
文章出處:【微信號(hào):FPGA-EETrend,微信公眾號(hào):FPGA開(kāi)發(fā)圈】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論