kconfig与Makefile运行机制

2023-10-29

前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方式——在一个独立的文件夹通过makefile配合内核源码路径完成
    那么如何将驱动直接编译进内核呢?

    在我们实际内核的移植配置过程中经常听说的内核裁剪又是怎么麽回事呢?

我们在进行linux内核配置的时候经常会执行make menuconfig这个命令,然后屏幕上会出现以下界面:

 


这个界面是怎么生成的呢?

跟我们经常说的内核配置与与编译又有什么关系呢?

下面我们借此来讲解一下linux内核的配置机制及其编译过程。

一、配置系统的基本结构

Linux内核的配置系统由三个部分组成,分别是:

   1、Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义 Linux 内核的编译规则;

    2、配置文件(config.in(2.4内核,2.6内核)):给用户提供配置选择的功能;

    3、配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。

   这些配置工具都是使用脚本语言,如 Tcl/TK、Perl 编写的(也包含一些用 C 编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,一般的内核开发者无须了解它们的原理,只需要知道如何编写 Makefile 和配置文件就可以。

二、makefile menuconfig过程讲解

当我们在执行make menuconfig这个命令时,系统到底帮我们做了哪些工作呢?

这里面一共涉及到了一下几个文件我们来一一讲解


Linux内核根目录下的scripts文件夹

arch/$ARCH/Kconfig文件、各层目录下的Kconfig文件

Linux内核根目录下的makefile文件、各层目录下的makefile文件


Linux内核根目录下的的.config文件、arm/$ARCH/下的config文件


Linux内核根目录下的 include/generated/autoconf.h文件

1)scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,我们作为使用者无需关心这个文件夹的内容

 


2)当我们执行make menuconfig命令出现上述蓝色配置界面以前,系统帮我们做了以下工作:

    首先系统会读取arch/$ARCH/目录下的Kconfig文件生成整个配置界面选项(Kconfig是整个linux配置机制的核心),那么ARCH环境变量的值等于多少呢?

它是由linux内核根目录下的makefile文件决定的,在makefile下有此环境变量的定义:

 


或者通过 make ARCH=arm menuconfig命令来生成配置界面,默认生成的界面是所有参数都是没有值的

    比如教务处进行考试,考试科数可能有外语、语文、数学等科,这里相当于我们选择了arm科可进行考试,系统就会读取arm/arm/kconfig文件生成配置选项(选择了arm科的卷子),系统还提供了x86科、milps科等10几门功课的考试题

 


3)假设教务处比较“仁慈”,为了怕某些同学做不错试题,还给我们准备了一份参考答案(默认配置选项),存放在arch/$ARCH/configs下,对于arm科来说就是arch/arm/configs文件夹:

 


    此文件夹中有许多选项,系统会读取哪个呢?内核默认会读取linux内核根目录下.config文件作为内核的默认选项(试题的参考答案),我们一般会根据开发板的类型从中选取一个与我们开发板最接近的系列到Linux内核根目录下(选择一个最接近的参考答案)

#cp arch/arm/configs/s3c2410_defconfig .config

4).config

    假设教务处留了一个心眼,他提供的参考答案并不完全正确(.config文件与我们的板子并不是完全匹配),这时我们可以选择直接修改.config文件然后执行make menuconfig命令读取新的选项

    但是一般我们不采取这个方案,我们选择在配置界面��通过空格、esc、回车选择某些选项选中或者不选中,最后保存退出的时候,Linux内核会把新的选项(正确的参考答案)更新到.config中,此时我们可以把.config重命名为其它文件保存起来(当你执行make distclean时系统会把.config文件删除),以后我们再配置内核时就不需要再去arch/arm/configs下考取相应的文件了,省去了重新配置的麻烦,直接将保存的.config文件复制为.config即可.

5)经过以上两步,我们可以正确的读取、配置我们需要的界面了

那么他们如何跟makefile文件建立编译关系呢?

当你保存make menuconfig选项时,系统会除了会自动更新.config外,还会将所有的选项以宏的形式保存在

Linux内核根目录下的 include/generated/autoconf.h文件下

 

 

内核中的源代码就都会包含以上.h文件,跟宏的定义情况进行条件编译。

当我们需要对一个文件整体选择如是否编译时,还需要修改对应的makefile文件,例如:

 


    我们选择是否要编译s3c2410_ts.c这个文件时,makefile会根据CONFIG_TOUCHSCREEN_S3C2410来决定是编译此文件,此宏是在Kconfig文件中定义,当我们配置完成后,会出现在.config及autconf中,至此,我们就完成了整个linux内核的编译过程。

    最后我们会发现,整个linux内核配置过程中,留给用户的接口其实只有各层Kconfig、makefile文件以及对应的源文件。

    比如我们如果想要给内核增加一个功能,并且通过make menuconfig控制其声称过程

    首先需要做的工作是:修改对应目录下的Kconfig文件,按照Kconfig语法增加对应的选项;

    其次执行make menuconfig选择编译进内核或者不编译进内核,或者编译为模块,.config文件和autoconf.h文件会自动生成;

    最后修改对应目录下的makefile文件完成编译选项的添加;

    最后的最后执行make zImage命令进行编译。

三、具体实例

下面我们以前面做过的模块实验为例,讲解如何通过make menuconfig机制将前面单独编译的模块编译进内核或编译为模块

假设我已经有了这么一个驱动:

modules.c

1.#include <linux/module.h>       /*module_init()*/  
2.#include <linux/kernel.h> /* printk() */  
3.#include <linux/init.h>       /* __init __exit */  
4. 
5.#define DEBUG   //open debug message  
6. 
7.#ifdef DEBUG  
8.#define PRINTK(fmt, arg...)     printk(KERN_WARNING fmt, ##arg)  
9.#else  
10.#define PRINTK(fmt, arg...)     printk(KERN_DEBUG fmt, ##arg)  
11.#endif  
12. 
13./* Module Init & Exit function */ 
14.static int __init myModule_init(void) 
15.{ 
16.    /* Module init code */ 
17.    PRINTK("myModule_init\n"); 
18.    return 0; 
19.} 
20. 
21.static void __exit myModule_exit(void) 
22.{ 
23.    /* Module exit code */ 
24.    PRINTK("myModule_exit\n"); 
25.    return; 
26.} 
27. 
28.module_init(myModule_init); 
29.module_exit(myModule_exit); 
30. 
31.MODULE_AUTHOR("dengwei");                          /*模块作者,可选*/ 
32.MODULE_LICENSE("GPL");                             /*模块许可证明,描述内核模块的许可权限,必须*/ 
33.MODULE_DESCRIPTION("A simple Hello World Module"); /*模块说明,可选*/ 

 

 

Step1:将modules.c拷到drivers/char/目录下(这个文件夹一般存放常见的字符驱动)

 


Step2: vi driver/char/Kconfig,在

    config DEVKMEM后添加以下信息

 


config MODULES
tristate "modules device support"
default y
help
 Say Y here,the modules will be build in kernel.
 Say M here,the modules willbe build to modules.
 Say N here,there will be nothing to be do.

 


Step3:make menuconfig

     Device driver-character devices

           [*]modules device suppor

 


Step4:vi driver/char/Makefile,在js-rtc后添加

obj-$(CONFIG_MODULES)+= modules.o

CONFIG_MODULES 必须跟上面的Kconfig中保持一致,系统会自动添加CONFIG_前缀


modules.o必须跟你加入的.c文件名一致

最后执行:make zImage modules就会被编译进内核中

 


第三步:

 

Step3:make menuconfig

     Device driver-character devices

           [M]modules device suppor
把星号在配置界面通过空格改为M,最后执行make modules,在driver/char/目录下会生成一个modules.ko文件
跟我们前面讲的单独编译模块效果一样,也会生成一个模块,将它考入开发板执行insmod moudles.ko,即可将生成的模块插入内核使用。

 

 

PS:自己的看法

Linux内核的make menuconfig实际上是执行了:

scripts/kconfig/mconf      arch/mips/Kconfig

mconf表示是menuconfig,如果是用基于QT的配置工具,则执行的将会是qconf,arch/mips/Kconfig是要读取的Kconfig文件,这个会因平台而异,这里因为针对的是MIPS平台,故读取的是arch/mips/目录下的Kconfig文件。

如果Linux源码树顶层目录下已有.config文件,make menuconfig则从.config文件取默认参数,如果没有.config则从各个Kconfig中取默认参数。

mconf会把用户的选择保存到Linux源码树顶层目录的.config文件中,然后解析该文件并将解析结果写入到include/linux/autoconf.h中。include/linux/autoconf.h将会被include/linux/config.h包含,因此,需要关心配置情况的内核源文件只需要#include <linux/config.h>即可。

mconf解析.config文件时所采用的规则具体要仔细分析mconf.c源代码。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kconfig与Makefile运行机制 的相关文章

  • 如何在 ubuntu 20 中安装旧版本的 gcc -3 或 gcc-4

    我正在尝试安装旧版本的 gcc 4enter code here对于我的ubuntu创建构建目录 mkdir gcc build cd gcc build 下载源文件 wgethttp www netgull com gcc release
  • 将文件夹中结构化的预构建文件集添加到 android out 文件夹

    我为arm编译了glibc 这与Android glibc或bionic C不同 因为我编译的glibc环境将有助于提供更多api 现在我可以在 Android 运行时将 glibc 环境复制到 system 文件夹中 并且在执行 chro
  • makefile 中的 $< 和 $@ 是什么意思?

    I have a csv b csv 在我的docs csv目录中 我需要将每个文件转换为 json 文件 我遵循这个question https stackoverflow com questions 2706064 compile al
  • mingw32-make 的目录更改错误

    我正在MinGW32下构建POCO库1 6 0 环境 Windows 7 Ultimate 32位 shell MSYS 执行成功 配置 configure Configured for MinGW config make的内容 POCO
  • 检查 makefile 中的文件大小,如果文件太短则停止

    有没有办法检查特定文件的大小是否小于某个常量 我在 makefile 中假设有关大小的事情 并希望确保如果不满足我的假设 我会收到错误 类似于断言 但在 makefile 中 if filesize file gt C then error
  • 是否可以将 CFLAGS 设置为 Linux 内核模块 Makefile?

    例如 常见设备模块的Makefile obj m jc o default MAKE C lib modules shell uname r build M shell pwd modules clean MAKE C lib module
  • /usr/sbin/install 到底有什么作用?

    我正在尝试安装discount https github com Orc discount on my VPS http no de它基于Solaris 设置一些环境变量后编译效果很好 但是安装失败 https gist github co
  • GNU Make 与 patsubst:需要两次替换

    我需要在变量替换的替换中引用词干两次 O23 OROOTS ODIR overx 2wk 3wk mlb 我需要使用相同的词干执行两次替换 但是替换使用patsubst这只做第一个 我们怎样才能同时实现这两点呢 事实上 杰克几乎猜对了 fo
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she
  • @:(符号冒号)在 Makefile 中意味着什么?

    Makefile 中的以下内容有何作用 rule deps 我在制作手册中似乎找不到这个 它的意思是 不要在输出中回显此命令 所以这条规则是说 执行 shell 命令 并且不回显输出 当然是shell命令 是一个空操作 所以这就是说 什么都
  • 如何在 Makefile 中获取 make 命令的 pid?

    我想使用此构建特有的临时目录 如何在 Makefile 中获取 make 命令的 pid I tried TEMPDIR tmp myprog 但这似乎存储TEMPDIR as tmp myprog 然后将 eval 作为每个引用此命令的新
  • Makefile 和 .Mak 文件 + CodeBlocks 和 VStudio

    我对整个 makefile 概念有点陌生 所以我对此有一些疑问 我正在 Linux 中使用 CodeBlocks 创建一个项目 我使用一个名为 cbp2mak 的工具从 CodeBlocks 项目创建一个 make 文件 如果有人知道更好的
  • 在 Mac 上更新 Make 版本

    我正在尝试更新 mac 上的 make 版本 但遇到了问题 最小项目依赖项是 4 1 但我的版本似乎是 3 81 我已将 Xcode 更新到最新版本并安装了命令行工具 但它似乎仍然是旧版本 有谁遇到过这个问题或知道解决方法吗 这是我所做的
  • 与 GNU Make 等 Python 相关的并行任务并发

    我正在寻找一种方法或者可能是一种哲学方法来如何在 python 中执行类似 GNU Make 的操作 目前 我们使用 makefile 来执行处理 因为 makefile 非常擅长通过更改单个选项 j x 进行并行运行 此外 gnu mak
  • 如果未设置,则从控制台读取 Makefile 变量

    我正在更新一个从外部源访问某些资源的 Makefile 即存在以下形式的规则 External cvs up 对于不受限制的资源 它可以按预期工作 现在 出现了功能漂移 外部资源需要更复杂的登录 因此规则已更改为与此没有太大不同的内容 Ex
  • 在 Ubuntu 16.04 上编译 PCL 1.7,CMake 生成的 Makefile 中出现错误

    我正在尝试让 PCL 1 7 点云库 而不是其他 pcl 在 Ubuntu 16 04 上运行 我最终希望用于 C 的东西 但现在我只是想让这些例子工作 我使用的是 Ubuntu GNU 5 3 1 附带的默认编译器和 Cmake 版本 3
  • 在赋值时计算 Makefile 变量

    在 Makefile 中 我尝试将 shell 命令的结果分配给变量 TMP mktemp d tmp XXXXX all echo TMP echo TMP but make Makefile all 正在回显 2 个不同的值 例如 tm
  • .ko 文件是如何构建的

    我正在尝试将我自己的驱动程序移植到Beagle 板 xm arm cortex A8 在移植时我试图弄清楚如何 ko文件实际构建 在我们的Makefile我们只有一个命令来构建 o file 怎样是一个 ko文件已建立 使用Linux 2
  • makefile 使用目标中定义的变量[重复]

    这个问题在这里已经有答案了 如何使用 make 目标中定义的变量 PHONY foo VAR GLOBAL shell cat tmp global foo echo local gt tmp local VAR LOCAL shell c
  • 从哪里获取 iostream.h

    我正在尝试在 Linux 中做一些事情 但它抱怨找不到 iostream h 我需要安装什么才能获取此文件 这个标准头的正确名称是iostream没有扩展名 如果您的编译器仍然找不到它 请尝试以下操作 find usr include na

随机推荐

  • CmakeList--gflags

    set GFLAGS LIBRARIES usr lib x86 64 linux gnu libgflags so
  • vue-cli3+electron出现白屏现象

    近期使用electron vue cli3 0开发了一个跨平台项目 进行登录后路由跳转出现白屏现象 原因在于路由使用了history模式 history模式在electron环境中会出现 路由跳转的白屏现象 因此 需要将histroy模式修
  • deepin自带wine使用方法_忘记Windows!国产深度v20正式版来袭,永久免费使用!

    最近win10系统更新出现各种bug 真是让人头痛 但是 就在我们在win10漩涡中晕头转向的时候 很多朋友都没有留意到 我们的国产操作系统 deepin 20正式版 在9月份已经正式发布 而直至10月份 距离deepin 20正式版发布一
  • Python实现邮箱自动发送代码(包含正文图片、附件文件)

    以下为源码 仅供大家学习 抄送实现是同一封邮件发送2次 如想实现发送人和抄送人显示中文名字 在list集合中添加中文名字即可 旭旭同学测试 lt 12341324 qq com gt 测试 lt 1341 qq com gt 不足之处请大家
  • Qt 多线程/多窗口 参数传递

    文章目录 注意 传递 Qt 支持的数据类型 主线程 gt 子线程 子线程 gt 主线程 主窗口 gt 子窗口 子窗口 gt 主窗口 传递自己定义的数据类型 第一步 定义数据类型 第二步 在 main 函数中注册该数据类型 第三步 开始传参数
  • 博客同时部署Github和Coding page

    前期 注册账号不讲了 现在都是以团队注册 注册完后 记得到团队设置里面 找到实名认证 在初次使用静态网站服务前 需要团队拥有者完成实名认证 然后需要在个人设置里绑定邮箱和设置密码 顺便把公钥添加下 创建一个项目 然后点进这个项目中 部署静态
  • phpstorm 配置apache路径

    初学php 如何自动将phpstorm中的文件部署到设定好的目录中 用了 我的路径是apache里面配置的路径ServerRoot
  • CentOS 7二进制文件安装nodejs

    根据自己的经验编写在linux系统CentOS下安装nodejs的过程 本篇介绍二进制文件直接解压安装的过程 方法 步骤 1 如图所示 在nodejs官网下载压缩包 根据自己的系统是32位还是64位选择压缩包 别选错类型哦 2 安装前要先安
  • sklearn——加载数据集

    1 通用数据集 API 根据所需数据集的类型 有三种主要类型的数据集API接口可用于获取数据集 方法一 loaders 可用来加载小的标准数据集 在玩具数据集中有介绍 方法二 fetchers 可用来下载并加载大的真实数据集 在真实世界中的
  • 无法生成“F:\system voiume information”下的常规文件夹列表拒绝访问

    1 产生问题 将桌面从属性 位置直接改到了F盘 F盘上的东西全显示在桌面上 2 解决问题 1 点击还原默认值后显示要下图 选择否 win10可以用 然后再次移动到你需要的位置即可 2 win7可以用 win10并没有用成 1 按win r
  • 图的创建和遍历

    图的定义 由顶点的有穷非空集合和顶点之间边的集合组成的数据类型 图的表示 G V E G表示一个图 V是图G的顶点集合 E为图G的边的集合 图的逻辑结构 多对多 图的存储结构 邻接矩阵 邻接表 十字链表 邻接多重表 图的一些无聊术语 顶点i
  • 多源bfs

    这是 LeetCode 上的 1162 地图分析 难度为 中等 与 单源最短路 不同 多源最短路 问题是求从 多个源点 到达 一个 多个汇点 的最短路径 在实现上 最核心的搜索部分 多源 BFS 与 单源 BFS 并无区别 并且通过建立 虚
  • 日常管理的五条小建议

    原文作者 Johanna Rothman著作 门后的秘密 卓越管理的故事 有时候 你需要为工作理一理头绪 你需要给自己一些喘息的机会 停下来 思考一会儿 这里有一些小建议 可以帮助你处理好日常管理工作 计划并安排一对一会谈 做管理意味着你要
  • 基于Hadoop的Knn算法实现

    Knn算法的核心思想是如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别 则该样本也属于这个类别 并具有这个类别上样本的特性 该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别 Knn方法在类
  • Qt配置设置,修改全文字体大小颜色,背景颜色

    这是完成时的demo 选择所需 点击确认修改 全局修改 效果第二张图 在没有点击确认修改时 字体等按钮的改变只会在文本框里面体现出来 点击确认才会修改全局的东西 点击恢复默认时 字体字号颜色控件全部恢复初始状态 当点击确认修改 全局才会改为
  • python大文件的上传

    python大文件的上传 下载是同样的套路 下面是简单的代码 server端代码 import socket import json import struct buffer 1024 这里使用1024在上传视频的时候不容易出错 如果选择更
  • MATLAB智能优化算法 - 粒子群算法及MATLAB实例仿真

    一 粒子群算法理论 粒子群算法来源于鸟类集体活动的规律性 进而利用群体智能建立简化模型 它模拟的是鸟类的觅食行为 将求解问题的空间比作鸟类飞行的时间 每只鸟抽象成没有体积和质量的粒子 来表征一个问题的可行解 1 1 粒子群算法建模 粒子群算
  • 信号槽的概念与使用

    下面对Qt所设计的信号槽机制进行解析 部分摘自网络 信号 当对象改变其状态时 信号就由该对象发射 emit 出去 而且对象只负责发送信号 它不知道另一端是谁在接收这个信号 这样就做到了真正的信息封装 能确保对象被当作一个真正的软件组件来使用
  • python之实现ts转MP4

    import subprocess import os def convert ts to mp4 input path output path ffmpeg cmd f ffmpeg i input path c copy output
  • kconfig与Makefile运行机制

    前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式 模块和直接编译进内核 并介绍了模块的一种编译方式 在一个独立的文件夹通过makefile配合内核源码路径完成 那么如何将驱动直接编译进内核呢 在我们实际内核的移植配置过程中经常听说的内