前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【分享】在Petalinux编译多个源文件的Linux内核模块,以及扩展Makefile功能

【分享】在Petalinux编译多个源文件的Linux内核模块,以及扩展Makefile功能

作者头像
hankfu
发布2021-03-04 11:50:38
6.2K0
发布2021-03-04 11:50:38
举报
文章被收录于专栏:hank

作者:付汉杰

创建内核模块

Petalinux可以帮助工程师简化内核模块的创建工作。在petalinux工程目录下,使用命令“petalinux-create -t modules --name --enable”,能创建Linux内核模块,包括c源代码文件、Makefile、Yocto的bb文件。相关文件放在目录“project-spec/meta-user/recipes-modules”,目录结构如下。

代码语言:javascript
复制
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只支持一个源文件,内容如下:

代码语言:javascript
复制
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,支持模块在内核源码目录外编译。编译的命令是“(MAKE) -C (KERNEL_SRC) M=

Linux内核顶层Makefile关于M变量的代码:

代码语言:javascript
复制
# 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的代码:

代码语言:javascript
复制
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'] = ''
}

语句“obj-m := linux-test-module.o”指示Kbuild将模块编译成Linux内核模块文件linux-test-module.ko。

更多信息可以参考相关文档,比如深入理解 Linux 配置/构建系统是如何工作的,LINUX内核编译学习笔记, Linux 内核模块编译 MakefileLinux 2.6内核Makefile浅析

多源文件Makefile

如果有多个源文件,也可以学习Linux内核模块的Makefile写法,使Petalinux的内核模块也支持多个源文件。Linux内核通过(<module_name>-objs)包含多个目标文件,使Kbuild编译多个源文件。因此在支持新Makefile里,增加了objs语句。首先通过TEST_FILES列出所有C文件,再将C文件替换成Obj文件赋值给

代码语言:javascript
复制
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

内核源码目录内Makefile

有时内核模块也需要在Linux内核源码目录内编译,不需要指定编译命令。KERNELRELEASE是Linux内核源码的顶层Makefile定义的一个变量。如果在内核源码目录内编译,先执行Linux内核源码的顶层Makefile,会定义KERNELRELEASE的具体值。如果加上对KERNELRELEASE的检查,前面的Makefile可以改造成既可以在在内核源码目录内编译,也可以在在内核源码目录外编译。下面的Makefile,增加了检查KERNELRELEASE的语句“ifeq ($(KERNELRELEASE),)”。

代码语言:javascript
复制
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

实际测试中,不加KERNELRELEASE相关语句,也不影响在Linux内核源码目录内编译。据说旧版本Kbuild才需要的KERNELRELEASE相关语句。 上面的Makefile文件也可以作为一个模板。只需要更改TEST_MODULE_NAME的值“linux-test-module”,和更改TEST_FILES后的文件列表,可以用于编译其它模块。 如果既不在PetaLinux环境里编译,也不再Linux内核源码目录内编译,请再在上面的Makefile文件里定义内核源码目录。

Yocto recipe文件

Yocto recipe文件的扩展名是.bb,它定义recipe需要的文件。

原始bb文件

原始的recipe的bb文件的只含有一个C文件。

代码语言:javascript
复制
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文件

由于要支持多个源文件,需要在recipe的bb文件的添加所有C文件。修改其实也很简单。下面的bb文件添加了行“file://linux-test-module-internal.c”以为Yocto/PetaLinux增加文件linux-test-module-internal.c。

代码语言:javascript
复制
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.

测试环境

UBuntu 18.04 PetaLinux 2020.2

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-02-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建内核模块
  • Makefile
    • 原始Makefile
      • 多源文件Makefile
        • 内核源码目录内Makefile
        • Yocto recipe文件
          • 原始bb文件
            • 新bb文件
            • 测试环境
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档