0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在Petalinux创建Linux内核模块?

YCqV_FPGA_EETre 来源:赛灵思中文社区论坛 作者:付汉杰 2021-03-02 11:10 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

创建内核模块

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

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只支持一个源文件,内容如下:

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=$(SRC)”。其中-C选项将当前工作目录转移到指定的位置;KERNEL_SRC是Yocto/PetaLinux在文件components/yocto/layers/core/meta/classes/module.bbclass里定义的变量,指定了Linux内核源代码目录,一般是Petalinux工程目录下的子目录“build/tmp/work-shared/zynqmp-generic/kernel-source”。这样编译时先进入内核源代码目录,先执行其中的顶层Makefile。M是内核根目录下的Makefile中使用的变量,让make在构造modules目标之前返回到内核模块源的代码目录。

Linux内核顶层Makefile关于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'] = ''

}

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

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

多源文件Makefile

如果有多个源文件,也可以学习Linux内核模块的Makefile写法,使Petalinux的内核模块也支持多个源文件。Linux内核通过$(-objs)包含多个目标文件,使Kbuild编译多个源文件。因此在支持新Makefile里,增加了objs语句。首先通过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

内核源码目录内Makefile

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

实际测试中,不加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文件。

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。

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

原文标题:【工程师分享】在Petalinux编译多个源文件的Linux内核模块,以及扩展Makefile功能

文章出处:【微信公众号:FPGA开发圈】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    4

    文章

    1436

    浏览量

    42491
  • Linux
    +关注

    关注

    88

    文章

    11628

    浏览量

    217981

原文标题:【工程师分享】在Petalinux编译多个源文件的Linux内核模块,以及扩展Makefile功能

文章出处:【微信号:FPGA-EETrend,微信公众号:FPGA开发圈】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux-RT特点及简单应用

    上下文切换延迟和提供硬实时保证来确保任务的低延迟和确定性。 Linux-RT上创建和管理实时任务 在Linux实时内核Linux-
    发表于 12-05 07:37

    Linux驱动开发的必备知识

    内核基础知识: 1、熟悉 Linux 内核的架构、模块系统、进程管理、内存管理等。 了解内核的编译和加载过程。 2、C编程技能: 精
    发表于 12-04 07:58

    Linux内核模块的加载机制

    Linux内核模块通常是.ko文件,也就是Kernel Object的缩写。这些文件是ELF格式的,但和用户空间的程序不同,它们包含的是特定于内核的信息。比如,模块的元数据,像作者
    发表于 11-25 06:59

    【迅为工业RK3568稳定可靠】itop-3568开发板Linux驱动开发实战:RK3568内核模块符号导出详解

    【迅为工业RK3568稳定可靠】itop-3568开发板Linux驱动开发实战:RK3568内核模块符号导出详解
    的头像 发表于 11-21 13:25 659次阅读
    【迅为工业RK3568稳定可靠】itop-3568开发板<b class='flag-5'>Linux</b>驱动开发实战:RK3568<b class='flag-5'>内核模块</b>符号导出详解

    【OK3506-S12Mini试用评测】编译你的第一个内核模块

    OK3506 开发板内核模块编译与加载 一、前言 在嵌入式 Linux 系统开发中,内核模块(Kernel Module) 是一种可动态加载到内核中的驱动或功能扩展,不需要重新编译整个
    发表于 10-24 21:00

    何在裸机环境中运行KleidiAI微内核

    ,对 KleidiAI 进行了简要概述,并附有相关指南链接,其中详细说明了在 Linux 环境中运行 KleidiAI 矩阵乘法 (matmul) 微内核的分步操作,这份指南内容详实且极易上手。而本篇内容则将
    的头像 发表于 08-08 15:16 3627次阅读
    如<b class='flag-5'>何在</b>裸机环境中运行KleidiAI微<b class='flag-5'>内核</b>

    迅为RK3568开发板内核模块实现-查看模块信息

    在驱动模块加载之后,使用“modinfo helloworld.ko”命令可以获得模块的信息,包括模块作者,模块说明,模块支持的参数等等。
    发表于 05-16 11:18

    迅为RK3568开发板内核模块实现-模块加载与卸载

    有了内核模块以后,我们要如何使用呢?编译驱动有俩种方式,那 Linux 驱动的运行方式也肯定有俩种。一种就是将驱动编译进内核,这样 Linux 系统启动后会自动运行程序。第二种就是将驱
    发表于 05-14 10:56

    迅为RK3568开发板内核模块实现-编译模块

    有了 Makefile 以后,输入“make”命令就可以编译 helloworld 驱动模块,如下图(图 4-7)所示: 编译完生成 helloworld.ko 目标文件就是我们需要的内核模块
    发表于 05-12 11:09

    迅为RK3568开发板内核模块实现-编写 Makefile

    ;lt;文件>:将指定的文件(需要是以.o 结尾)设为编译时以模块形式编译 第 4 行是设备树内核的源码路径,请大家根据实际内核路径进行修改。 第 5 行是获取当前目录的变量 第 7 行
    发表于 04-24 13:36

    在任何平台上使用PetaLinux的先决条件

    本篇文章介绍了在任何平台上使用 PetaLinux 的先决条件。PetaLinux 是一种嵌入式 Linux 软件开发套件 (SDK),主要用于基于 FPGA 的系统级芯片 (SoC) 设计或 FPGA 设计。
    的头像 发表于 04-24 10:40 1206次阅读
    在任何平台上使用<b class='flag-5'>PetaLinux</b>的先决条件

    从零开始驯服Linux(一):ZYNQ-Linux启动文件构建全解析

    /atk-zynq-linux-xlnx),可看到Linux内核源码目录结构,如下图所示: 图 1.2.7 Linux内核源码目录结构 拷贝
    发表于 03-20 16:48

    Linux中的用户与创建

    Linux中的用户与创建 用户的类型 超级管理用户: 权限最高的用户(uid:0) #uid:是用户的身份证号,Linux系统只认uid 普通用户: 权限受限的用户(uid:1000-60000
    的头像 发表于 12-20 14:24 1202次阅读
    <b class='flag-5'>Linux</b>中的用户与<b class='flag-5'>创建</b>

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    所以每个模块都有对应的维护人员。维护人员的工作就是审核人们提交的代码是否正确,如果没有问题,就会合并到主分支上。这样就会使linux内核不断完善和更新。接下来就是芯片原厂例如恩智浦,开发人员会不定期在
    发表于 12-16 13:08

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    所以每个模块都有对应的维护人员。维护人员的工作就是审核人们提交的代码是否正确,如果没有问题,就会合并到主分支上。这样就会使linux内核不断完善和更新。接下来就是芯片原厂例如恩智浦,开发人员会不定期在
    发表于 12-13 09:03