最新版 DeepSeek-V3 ,太牛逼了。

核心内容摘要

【期货量化进阶】期货量化交易策略信号强度评估(Python量化)
ChatTTS流式处理实战:高并发场景下的语音合成优化方案

无锡黑锋 HF4230 24V/3A 同步降压转换器技术解析

目录

内核模块的编译方式in-tree vs out-of-tree

内核树外编译out-of-tree特点典型做法适用场景

内核树内编译in-tree参考资料

内核模块的编译方式in-tree vs out-of-tree通常而言内核模块代码有两种常见的构建形态内核树内编译in-tree把模块源码放进或集成进内核源码树由内核顶层构建系统统一编译。

内核树外编译out-of-tree外部模块模块源码独立放在内核树之外通过make -C kernel_dir Mmodule_dir modules借用内核 Kbuild 来编译。

内核树外编译out-of-tree特点模块源码独立不需要进入内核源码树。

仍然使用内核的 Kbuild 规则来编译关键命令是make -C KERNEL_DIR MMODULE_DIR modules典型做法模块目录里只放一个“外部模块 Makefile”obj-m : hellomodule.omake -C $(KERNEL_DIR) M$(CURDIR) modules适用场景驱动/模块开发调试迭代快第三方闭源或单独交付不改内核树同一内核版本下给多个项目复用在内核树外编译的方式在我们之前的文章中其实已经实现了可以参考【内核驱动基础】超详细一文详解Linux驱动模块这一文章主要实现就是Makefile文件的编写

内核树内编译in-tree在内核源码的文件目录下我们可以看到有很多的驱动程序我们通过drivers/char中的Makefile文件进一步举例说明其位置如下:Makefile文件的内容如下# SPDX-License-Identifier: GPL-

0 # # Makefile for the kernel character device drivers. # obj-y mem.o random.o obj-$(CONFIG_TTY_PRINTK) ttyprintk.o obj-y misc.o obj-$(CONFIG_ATARI_DSP56K) dsp56k.o obj-$(CONFIG_VIRTIO_CONSOLE) virtio_console.o obj-$(CONFIG_RAW_DRIVER) raw.o obj-$(CONFIG_MSPEC) mspec.o obj-$(CONFIG_UV_MMTIMER) uv_mmtimer.o obj-$(CONFIG_IBM_BSR) bsr.o obj-$(CONFIG_PRINTER) lp.o obj-$(CONFIG_APM_EMULATION) apm-emulation.o obj-$(CONFIG_DTLK) dtlk.o obj-$(CONFIG_APPLICOM) applicom.o obj-$(CONFIG_SONYPI) sonypi.o obj-$(CONFIG_HPET) hpet.o obj-$(CONFIG_XILINX_HWICAP) xilinx_hwicap/ obj-$(CONFIG_NVRAM) nvram.o obj-$(CONFIG_TOSHIBA) toshiba.o obj-$(CONFIG_DS

ds

o obj-$(CONFIG_HW_RANDOM) hw_random/ obj-$(CONFIG_PPDEV) ppdev.o obj-$(CONFIG_NWBUTTON) nwbutton.o obj-$(CONFIG_NWFLASH) nwflash.o obj-$(CONFIG_SCx200_GPIO) scx200_gpio.o obj-$(CONFIG_PC8736x_GPIO) pc8736x_gpio.o obj-$(CONFIG_NSC_GPIO) nsc_gpio.o obj-$(CONFIG_GPIO_TB

tb

o obj-$(CONFIG_TELCLOCK) tlclk.o obj-$(CONFIG_MWAVE) mwave/ obj-y agp/ obj-$(CONFIG_PCMCIA) pcmcia/ obj-$(CONFIG_HANGCHECK_TIMER) hangcheck-timer.o obj-$(CONFIG_TCG_TPM) tpm/ obj-$(CONFIG_PS3_FLASH) ps3flash.o obj-$(CONFIG_XILLYBUS) xillybus/ obj-$(CONFIG_POWERNV_OP_PANEL) powernv-op-panel.o obj-$(CONFIG_ADI) adi.o这个文件的主要作用就是告诉内核的构建系统Kbuild在“字符设备驱动”这个目录下需要编译哪些源文件/子目录以及它们是编进内核built-in还是编成模块.ko。

典型写法是这种obj-$(CONFIG_FOO) foo.o含义CONFIG_FOOy→foo.o编进内核镜像built-inCONFIG_FOOm→foo.o会被链接成foo.ko模块CONFIG_FOOn→ 不编译那么问题来了这些变量在哪里被设置呢—答在内核根目录.config文件中进行配置在我们make板卡厂家给的默认配置时会默认配置.config文件截取部分.config文件如下我们继续提问这个.config又如何去修改里面的配置参数呢当然如果你要手动编写也是无可厚非的但问题是内核有成千上万个配置选项CONFIG_*所以内核引入了menuconfig。

这个.config文件是由各个驱动目录下的Kconfig文件汇总得到的只需要修改驱动目录下对应的Kconfig文件使用make menuconfig可以快速配置.config文件的参数内容。

menuconfig 是 Linux 内核 Kconfig 配置系统提供的一个交互式终端界面配置工具。

它的核心目的很简单让你用“菜单”的方式生成/修改内核的 .config从而决定内核和各类驱动/子系统到底编译进内核y、编译成模块m还是不编译n。

其界面如下在执行make menuconfig指令的时候一定要确定好自己的编译平台和交叉编译链工具是否正确否则在部署到板卡上后很有可能会产生错误。

例如在rk3588上是如下配置的make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- menuconfigmenuconfig常用的快捷键如下/搜索配置项强烈推荐输入关键字或CONFIG_名称能直接定位选项所在菜单?查看当前选项帮助信息helpy / n / m直接把当前项设为 y/n/mSpace循环切换状态n → m → yEsc返回/退出技巧找不到某个驱动选项时先按 / 搜它再根据搜索结果跳转到对应菜单。

下面我们使用一个实例进行强化我们当前完成了一个简单驱动程序模块#include linux/module.h #include linux/init.h #include linux/kernel.h static int __init hello_init(void) { printk(KERN_EMERG [ KERN_EMERG ] Hello Module Init\\n); printk( [ default ] Hello Module Init\\n); return 0; } static void __exit hello_exit(void) { printk([ default ] Hello Module Exit\\n); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE(GPL

; MODULE_AUTHOR(cc ); MODULE_DESCRIPTION(hello world module); MODULE_ALIAS(test_module);我们将程序放入内核drivers/char目录下在当前目录下的Makefile文件中我们配置模块参数在当前目录的Kconfig文件中编写模块的Kconfig信息此处的状态可以设置为booly或n或者tristate三态y、n、m,m表示为一个模块然后在内核根目录执行make menuconfig,使用/搜索HELLO_MODULE可以看到如下在.config文件中搜索HELLO_MODULE可以看到参数已经配置成y如果想要配置成默认为n也可以在menuconfig中配置至此介绍完了两种编译方式大家可以自行尝试加深理解。

参考资料Linux下menuconfig与Kconfig基础知识概要韦东山Linux驱动课程内核参考文档

91直接观看IOS版最新下载-91直接观看IOS版最新下载应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123