Linux内核的配置和编译

2023-11-01

前言

以下内容基于2.6.35.7版本内核,文件资源:
https://download.csdn.net/download/weixin_44705391/15629906


uboot文章连载

Linux文章连载:
2.Linux内核的配置和编译原理
3.Linux内核的启动过程分析
4.Linux内核的移植实验-三星官方内核(了解)
5.根文件系统的原理
6.Linux根文件系统构建实验&busybox的移植


1.内核介绍

1.内核和发行版的区别
操作系统核心功能:内存管理、进程调度、文件系统
操作系统扩展功能:协议栈、有用的应用程序包。
(1)内核只有一个。www.kernel.org
(2)发行版有很多。譬如ubuntu、redhat、suse、centos······

2.内核和驱动的关联
(1)驱动属于内核的一部分。
(2)驱动是内核中的硬件设备管理模块。
(3)工作在内核态,对硬件有最高的使用权限。
(4)驱动程序故障可能导致整个内核崩溃。驱动程序漏洞会使内核不安全

3.内核和根文件系统的关联
(1)根文件系统提供根目录。其他文件系统挂载在根文件系统的节点下。
(2)进程1(用户态和内核态的交界处,可以理解为第一个应用程序,解释从内核态到用户态的细节)存放在根文件系统中
(3)内核启动最后会去装载根文件系统。
(4)总结:根文件系统为操作系统启动提供了很多必备的资源:根目录、进程1

4.linux内核的模块化设计
(1)linux内核很庞大,代码量很大,需要模块化设计
(2)模块化设计就是内核中各个功能模块在代码上是彼此独立的,譬如说调度系统和内存管理系统之间并没有全局变量的互相引用,甚至函数互相调用也很少,就算有也是遵循一个接口规范的。模块化设计的目的就是实现功能模块的松耦合。
(3)配置时可裁剪。linux内核在编译之前可以进行配置。
(4)模块化编译和安装。为了操作方便,逐渐从静态的升级变成了动态的升级(不需要重启系统,更不需要重新烧录系统)。这种动态的升级也是由模块化来支持的。
(5)源码中使用条件编译。这种在uboot中已经见过了。

2.linux内核源码目录结构

解压开源码文件 可看到:(绿色文件夹/文件对我们很重要)
(1)arch。架构。arch目录下是好多个不同架构的CPU的子目录,譬如arm这种cpu的所有文件都在arch/arm目录下,X86的CPU的所有文件都在arch/x86目录下。
(2)block。譬如说SD卡、iNand、Nand、硬盘等都是块设备。可以认为块设备就是存储设备。
(3)drivers。驱动
(4)firmware。固件
(5)fs。file system,文件系统
(6)include。公共的(各种CPU架构共用的)头文件都在这里。每种CPU架构特有的一些头文件在arch/arm/include目录及其子目录下。
(7)init。linux内核启动时初始化内核的代码。
(8)ipc。inter process commuication,进程间通信
(9)kernel
(10)lib。库,和c标准库类似,是内核重新实现供内核使用的,比如在内核中printf变成printk。
(11)mm。memory management,内存管理
(12)net。网络相关的代码,TCP/IP协议栈等
(13)scripts。辅助对linux内核进行配置编译生产的脚本。

(14)Kbuild,kernel build。linux内核特有的内核编译体系(重点,下面会讲)需要用到的文件。
(15)Makefile

简单讲一下linux内核的配置体系
(1)linux内核本身配置项有上千个,所以内核发明了一种体系用来配置:menuconfig方式:kernel文件夹下的Kbuild + 每个子文件夹下的Kconfig + menuconfig = 编译后生成.config文件,也就是linux内核特有的内核编译体系

3.内核配置和编译实验

先确认Makefile
(1)主要是检查交叉编译工具链有没有设置对。CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
(2)确认ARCH = arm。为了编译时能找到arch/arm目录。
make x210ii_qt_defconfig
(1)最后只要出现:configuration written to .config,就证明操作是正确的。
make menuconfig
(1)可能出现的错误1:ncurses库没装
解决方案: apt-get install libncurses5-dev(参考了:http://blog.csdn.net/yao_qinwei/article/details/8805101
(2)可能出现的错误2:屏幕太小
解决方案:全屏,或者是把字体调小。
进入图形化界面,用来配置内核,EXIT按回车退出。
make
(1)可能出现的错误1:莫名其妙的错误,可以试试先make distclean
(2)代码本身的错误:具体问题具体分析
make之后出现

Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.

删掉kernel/timeconst.pl 文件中 373行的if (!defined(@val)) { 改为if (!@val) {
(3)编译完成后得到的内核镜像不在源码树的根目录下,在arch/arm/boot这个目录下。得到的镜像名是zImage

4.内核的配置原理

烧写测试:得到的镜像文件在kernel/arch/arm/boot/文件夹下
配置的关键是得到.config文件
和uboot配置时自动生成的autoconf.mk很像
make xx_defconfig和make menuconfig相配合
(1)第一步:make xxx_defconfig解决的问题是大部分的配置项(这一步结束后99%的配置项就已经正确了),之后就是针对开发板进行细节调整,通过make menuconfig来完成。
(2)make menuconfig其实就是读取第一步得到的.config,然后给我们一个图形化的界面,让我们可以更加容易的找到自己想要修改的配置项,然后更改配置他。
make menuconfig用来模块化编译,也就是剪裁一些需要的模块。
make xx_defconfig到底做了什么?
(1)make x210ii_qt_defconfig其实相当于:cp arch/arm/configs/x210ii_qt_defconfig .config
(2)arch/arm/configs目录下的这么多个xxx_defconfig哪里来的?其实这些文件都是别人手工配置好适合一定的开发板的.config文件后自己把.config文件保存过去的。

5.menuconfig

用法翻译:
(1)箭头按键导航整个菜单,回车按键选择子菜单(注意选项后面有 —>的选项才是有子菜单的,没有这个标识的没有子菜单),高亮的字母是热键(快捷键),键盘按键Y、N、M三个按键的作用分别是将选中模块编入、去除、模块化。双击ESC表示退出,按下?按键可以显示帮助信息,按下/按键可以输入搜索内容来全局搜索信息(类似于vi中的搜索),[]不可以模块化,<>的才可以模块化。
(2)注:linux内核中一个功能模块有三种编译方法:一种是编入、一种去去除、一种是模块化。所谓编入就是将这个模块的代码直接编译连接到zImage中去,去除就是将这个模块不编译链接到zImage中,模块化是将这个模块仍然编译,但是不会将其链接到zImage中,会将这个模块单独链接成一个内核模块.ko文件,将来linux系统内核启动起来后可以动态的加载或卸载这个模块。
(3)在menuconfig中选项前面的括号里,*表示编入,空白表示去除,M表示模块化

menuconfig本身由一套软件支持
(1)linux为了实现图形化界面的配置,专门提供了一套配置工具menuconfig。
(2)ncurses库是linux中用来实现文字式的图形界面,linux内核中使用了ncurses库来提供menuconfig
(3)scripts\kconfig\lxdialog目录下的一些c文件就是用来提供menuconfig的那些程序源代码。

menuconfig读取Kconfig文件
(1)menuconfig本身的软件只负责提供menuconfig工作的这一套逻辑(譬如在menuconfig中通过上下左右箭头按键来调整光标,Enter ESC键等按键按下的响应),而并不负责提供内容(菜单里的项目)。
(2)menuconfig显示的菜单内容(一方面是菜单的目录结构,另一方面是每一个菜单项目的细节)是由 内核源码树各个目录下的Kconfig文件来支持的 。Kconfig文件中按照一定的格式包含了一个又一个的配置项,每一个配置项在make menuconfig中都会成为一个菜单项目。而且menuconfig中显示的菜单目录结构和源码目录中的Kconfig的目录结构是一样的。
menuconfig读取/写入.config文件
(1)刚才已经知道menuconfig的菜单内容来自于Kconfig文件,但是每一个菜单的选择结果(Y、N、M)却不是保存在Kconfig文件中的。Kconfig文件是不变的,Kconfig文件只是决定有没有这个菜单项,并不管这个菜单项的选择结果。
(2)menuconfig工作时在我们make menuconfig打开时,他会读取.config文件,并且用.config文件中的配置选择结果来初始化menuconfig中各个菜单项的选择值。
总结:菜单项的项目内容从Kconfig文件来,菜单项的选择值从.config文件来

6.Kconfig文件详解

Kconfig的格式
例子:

config OPROFILE
	tristate "OProfile system profiling"
	depends on PROFILING
	depends on HAVE_OPROFILE
	select RING_BUFFER
	select RING_BUFFER_ALLOW_SWAP
	help
	  OProfile is a profiling system capable of profiling the
	  whole system, include the kernel, kernel modules, libraries,
	  and applications.

	  If unsure, say N.

(1)#开头的行是注释行
(2)menuconfig表示菜单(本身属于一个菜单中的项目,但是他又有子菜单项目)、config表示菜单中的一个配置项(本身并没有子菜单下的项目)。
(3)menuconfig或者config后面空格隔开的大写字母表示的类似于 NETDEVICES 的就是这个配置项的配置项名字,这个字符串前面 添加CONFIG_ 后就构成了.config中的配置项名字。
(4)一个menuconfig后面跟着的所有config项就是这个menuconfig的子菜单。这就是Kconfig中表示的目录关系。
(5)内核源码目录树中每一个Kconfig都会source引入其所有子目录下的Kconfig,从而保证了所有的Kconfig项目都被包含进menuconfig中。这个也告诉我们:如果你自己在linux内核中添加了一个文件夹,一定要在这个文件夹下创建一个Kconfig文件,然后在这个文件夹的上一层目录的Kconfig中source引入这个文件夹下的Kconfig文件。

tristate和bool的含义
(1)tristate意思是三态(3种状态,对应Y、N、M三种选择方式),bool是要么真要么假(对应Y和N)。
depends的含义
(1)depends中文意思是“取决于”或者“依赖于”,所以depends在这里的意思是:本配置项依赖于另一个配置项。如果那个依赖的配置项为Y或者M,则本配置项才有意义;如果依赖的哪个配置项本身被设置为N,则本配置项根本没有意义。
(2)depends项目会导致make menuconfig的时候找不到一些配置项。所以在menuconfig中如果找不到一个选项,但是这个选项在Kconfig中却是有的,则可能的原因就是这个配置项依赖的一个配置项是不成立的(被配置为N)。
(3)depends并不要求依赖的配置项一定是一个,可以是多个,而且还可以有逻辑运算。这种时候只要依赖项目运算式子的逻辑结果为真则依赖就成立。
select
A
select B
则在A被选中的情况下,B自动被选中
help
(1)帮助信息,告诉我们这个配置项的含义,以及如何去配置他。

Kconfig和.config文件和Makefile三者的关联
(1)配置项被配置成Y、N、M会影响.config文件中的CONFIG_XXX变量的配置值。
(2)这个.config中的配置值(=y、=m、没有)会影响最终的编译链接过程。如果=y则会被编入(built-in),如果=m会被单独连接成一个ko模块,如果没有则对应的代码不会被编译。那么这是怎么实现的?都是通过makefile实现的。
(3)obj-$(CONFIG_DM9000) += dm9000.o
如果CONFIG_DM9000变量值为y,则obj += dm9000.o,因此dm9000.c会被编译;如果CONFIG_DM9000变量未定义,则dm9000.c不会被编译。如果CONFIG_DM9000变量的值为m则会被连接成ko模块(这个是在linux内核的Makefile中定义的规则)

7.menuconfig的实验

验证menuconfig和.config的关系
(1)make menuconfig时,会读取.config中的配置值来初始化menuconfig中的配置项。
验证:如果理论正确的,那么我自己手工修改了.config的配置后,再次make menuconfig时看到的初始值就应该是我手工修改的。
(2)menuconfig中修改了(按Y、N、M)配置项的值,然后退出时保存,则这个保存结果会修改.config文件中的相应行。
验证:如果结论是正确的,那么在menucofig中修改了配置后保存退出,再次去手工打开.config文件则可以看到相应配置的一行内容被修改了。

7.2、验证menuconfig和Kconfig的关系
(1)menuconfig读取Kconfig的内容作为菜单项目内容。
验证1:在Kconfig中删除一个config项,则再次make menuconfig时就看不到这个项目了。
验证2:在Kconfig中自己添加创建一个config项,则再次make menuconfig时就能看到多了一个项目。

7.3、验证menuconfig和Makefile的关系
(1)我找一个模块,把他配制成y,然后去make编译连接,最后得到的zImage中这个模块就应该被编译连接进去到zImage中了。
验证:
方法一:去这个模块对应的源代码目录看一下这个源码有没有被编译
方法二:去zImage对应的elf格式的vmlinux中查看符号
方法三:将vmlinux反编译(objdump)后得到的文件中找模块对应的符号
方法四:将zImage下载到开发板中启动,启动后看你的模块能不能工作

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

Linux内核的配置和编译 的相关文章

  • 如何从 Linux 内核模块获取使用计数?

    我对正在开发的内核模块的使用计数有疑问 我想打印它以进行调试 如何从模块代码中获取它 有问题的内核版本 Linux 2 6 32 module refcount http lxr linux no linux v2 6 34 1 inclu
  • 如何在 Linux 中重新添加 unicode 字节顺序标记?

    我有一个相当大的 SQL 文件 它以 FFFE 的字节顺序标记开头 我使用 unicode 感知的 linux 分割工具将此文件分割成 100 000 行块 但是当将这些传递回窗口时 它确实not与第一个部分以外的任何部分一样 只是它具有
  • 无需 root 访问权限即可安装 zsh? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有可能 以及如何 我确实需要在几台具有 ssh 访问权限 但没有 root 访问权限 的远程计算机上使用此功能 下载 zsh wget O zsh t
  • 如何从远程 ssh 连接上运行的 tmux(复制模式)复制到本地剪贴板

    我通过 OS X 上的 VirtualBox 运行 Linux 我通过在无头状态下运行虚拟机 然后使用端口转发 sshing 到 Linux 机器来实现这一点 现在 无论复制到我的虚拟机上的剪贴板 我都可以粘贴到我的远程 ssh 会话上 但
  • 在 debian wheezy amd64 上安装 ia32-libs

    我正在使用 Debian 7 喘息 amd64 uname a Linux tzwm debian 3 2 0 4 amd64 1 SMP Debian 3 2 51 1 x86 64 GNU Linux 我想安装ia32 libs在我的
  • 如何在 Linux/OS X 上温和地终止 Firefox 进程

    我正在使用 Firefox 进行一些自动化操作 尽管我可以从 shell 打开 Firefox 窗口 但我无法正确终止它 如果我kill火狐进程与kill 3 or kill 2当我下次打开新的 Firefox 窗口时 命令会询问我是否要在
  • 裸机交叉编译器输入

    裸机交叉编译器的输入限制是什么 比如它不编译带有指针或 malloc 的程序 或者任何需要比底层硬件更多的东西 以及如何才能找到这些限制 我还想问 我为目标 mips 构建了一个交叉编译器 我需要使用这个交叉编译器创建一个 mips 可执行
  • 如何列出 nginx 中的所有虚拟主机

    有没有一个命令可以列出 CentOS 上 nginx 下运行的所有虚拟主机或服务器 我想将结果通过管道传输到文本文件以用于报告目的 我正在寻找与我用于 Apache 的命令类似的命令 apachectl S 2 gt 1 grep 端口 8
  • 在非实时操作系统/内核上执行接近实时任务的最佳方法是什么?

    在一台 GNU Linux 机器上 如果想要执行 实时 亚毫秒级时间关键 任务 您几乎总是必须经历漫长 复杂且容易出现问题的内核补丁过程 以提供足够的支持 1 http en wikipedia org wiki RTLinux Backg
  • OpenSSL 未签名证书静默

    遇到了麻烦 还有其他一些相关的帖子 但没有那么具体 我正在尝试为开发机器默默地生成证书 这些是我最初运行的命令 但被要求输入密码 openssl genrsa des3 out server key 1024 openssl req new
  • 如何在特定的Java版本上运行应用程序?

    如何运行具有特定 Java 版本的应用程序 我安装了三个 Java 版本 myuser mysystem sudo update alternatives config java There are 3 choices for the al
  • 套接字发送调用被阻塞很长时间

    我每 10 秒在套接字上发送 2 个字节的应用程序数据 阻塞 但发送调用在下面的最后一个实例中被阻塞超过 40 秒 2012 06 13 12 02 46 653417 信息 发送前 2012 06 13 12 02 46 653457 信
  • Ctrl-p 和 Ctrl-n 在 Docker 下表现异常

    For the life of me I can t seem to figure out why ctrl p and ctrl n don t work like they re supposed to under the Docker
  • Nginx 作为负载均衡器,具有 75% 和 25% 加权路由

    我是 Nginx 新手 我有两台服务器 serverA 和 serverB 我希望 75 的请求发送到 serverA 其余 25 的请求发送到 serverB 这可能吗 使用nginx加权路由 stream upstream stream
  • 在用户程序中使用 或在驱动程序模块代码中使用 ...这有关系吗?

    我正在开发一个设备驱动程序模块和关联的用户库来处理ioctl 来电 该库获取相关信息并将其放入一个结构中 该结构被传递到驱动程序模块中并在那里解压 然后进行处理 我省略了很多步骤 但这就是总体思路 一些数据通过结构体传递ioctl is u
  • 亚马逊 Linux - 安装 openjdk-debuginfo?

    我试图使用jstack在 ec2 实例上amazon linux 所以我安装了openjdk devel包裹 sudo yum install java 1 7 0 openjdk devel x86 64 但是 jstack 引发了异常j
  • 从哪里获取 iostream.h

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

    据我所知 隐式声明 通常意味着该函数必须在调用之前放置在程序的顶部 或者我需要声明原型 然而 gets应该在stdio h文件 我已包含 有没有什么办法解决这一问题 include
  • 如何通过不同的接口路由 TCP/IP 响应?

    我有两台机器 每台机器都有两个有效的网络接口 一个以太网接口eth0和 tun tap 接口gr0 目标是使用接口在机器 A 上启动 TCP 连接gr0但然后让机器 B 的响应 ACK 等 通过以太网接口返回 eth0 因此 机器 A 发出
  • Java时区混乱

    我正在运行 Tomcat 应用程序 并且需要显示一些时间值 不幸的是 时间快到了 还有一个小时的休息时间 我调查了一下 发现我的默认时区被设置为 sun util calendar ZoneInfo id GMT 08 00 offset

随机推荐

  • Android常用正则

    1 匹配以特定字符开头 特定字符结尾 private const val AT s S 匹配以 打头 空格结尾的字符 2 匹配手机号 const val REG PHONE 1 0 9 10 3 匹配判断是否汉字字母数字和 const va
  • Centos 7 freeradius 搭建企业wifi认证服务

    Centos 7 搭建Wpa认证服务 关键字 freeradius wpa eap 参考 http www racksam com 2017 03 02 centos7 install freeradius 路由器设置为WPA WPA2企业
  • 阿里Sentinel控制台源码修改-对接Apollo规则持久化

    改造背景 前面我们讲解了如何对接Apollo来持久化限流的规则 对接后可以直接通过Apollo的后台进行规则的修改 推送到各个客户端实时生效 但还有一个问题就是Sentinel控制台没有对接Apollo Sentinel控制台本来就可以修改
  • C++ inline用法

    1 引入 inline 关键字的原因 在 c c 中 为了解决一些频繁调用的小函数大量消耗栈空间 栈内存 的问题 特别的引入了 inline 修饰符 表示为内联函数 栈空间就是指放置程序的局部数据 也就是函数内数据 的内存空间 在系统下 栈
  • (fastjson)对象转JSON字符串 接收json字符串返回对象

  • 视频86免费影院-视频电影网聚平台

    这两年在互联网来讲 视频行业是比较火热的 各大视频分享网站 融资 风投 欢乐声一片 这表明中国的互联网用户随着网络带宽的加大对在线视频 电影还是比较喜欢的 正好在网上看到一个不错的网站程序 修改过后自己也来做一个视频网站 不过内容都是采集的
  • 建立Tahi IPv6测试环境

    首先说一下TAHI测试的相关术语 Tester Node TN 测试平台 A tester node for the conformance tests Node Under Test NUT 待测试机 A testee node for
  • oracle查看服务器名字,查看oracle数据库服务器的名字

    查看oracle数据库服务器的名字 windows 中 1 select name from v database 直接运行就可以查看了 2 查看tnsnames ora 的连接 有个SID SID就是服务名了 1 查看oracle的安装目
  • java 面向对象编程——简介

    目录 第一章 对象和类 一 面向对象的程序设计 1 抽象的数据类型 2 什么是类 3 总结 二 定义一个类 1 定义类的成员变量 2 定义类的成员的方法 3 类的成员变量和方法总结 4 创建并使用对象 第二章 方法 一 方法的重载 1 方法
  • Spring Cloud Alibaba版本选型

    Spring Cloud Alibaba版本选型 版本说明 https github com alibaba spring cloud alibaba wiki E7 89 88 E6 9C AC E8 AF B4 E6 98 8E
  • javac不是内部命令或外部命令

    JAVAC 不是内部或外部命令 也不是可运行的程序或批处理文件 今天在运行JAVA的时候突然出了这个错误 这可怎么办 刚接触JAVA的新手可能就不知道怎么解决 JAVAC 不是内部命令或外部命令 下面我就来说说 解决 JAVAC 不是内部命
  • Sed 介绍和教程

    Sed 介绍和教程 作者 Bruce Barnett 译者 Koala 原文地址 http www grymoire com Unix Sed html 注 译者不懂sed Sed 介绍 如果你想写一个程序对一个文件做一些改动 那就sed就
  • B站狂神说--ElasticSearch笔记

    课程 免费 网址 https www bilibili com video BV17a4y1x7zq spm id from 333 999 0 0 笔记来源 https www kuangstudy com bbs 14427364812
  • 知识图谱在金融领域的分析与应用

    本文首发于个人博客 www bobinsun cn 前言 知识图谱因其自身的图展示 图挖掘 图模型计算优势 可帮助金融从业人员进行业务场景的分析与决策 有利于建立客户画像 进行精准营销获客 发现信用卡套现 资金挪用等行为 更好的表达 分析金
  • 车规级MCU知识介绍

    一辆传统燃油车需要大约500到600颗芯片 轻混汽车大约需要1000颗 插电混动和纯电动汽车则需要至少2000颗芯片 这就意味着在智能电动汽车快速发展的过程中 不仅对先进制程芯片需求不断增加 而且对传统芯片需求也会持续增加 MCU就是这样
  • PXE装机报错汇总

    报错1 PXE E53 No boot filename received CLIENT MAC ADDR 88 0C 29 0D 88 3C GUID 564D6429 2E4A 0B83 6161 AE0A050D803C PXE MB
  • 【持续集成CI/持续部署CD】二、Docker安装Maven私服Nexus

    本文是关于通过 Docker 进行安装部署 Nexus3 私服的快速入门和简单使用案例 一 安装 1 通过 docker 获取最新版本的 nexus3 镜像 docker pull sonatype nexus3创建 docker 镜像到宿
  • Pytorch中交叉熵损失函数 nn.CrossEntropyLoss()计算过程

    pytorch的交叉熵损失函数是如何计算outputs和 labels之间的损失的 对于一个分类问题的CNN模型 最后一层的代码一般如下 nn Linear 2048 num classes 然后计算一次迭代损失的代码一般如下 loss f
  • 国教 2019级 算法设计与分析 作业集锦(期末作业)

    7 1 寻找第k小的数 20 分 给定若干整数 请设计一个高效的算法 确定第k小的数 输入格式 测试数据有多组 处理到文件尾 每组测试数据的第1行输入2个整数n k 1 k n 1000000 第2行输入n个整数 每个数据的取值范围在0到1
  • Linux内核的配置和编译

    文章目录 前言 1 内核介绍 2 linux内核源码目录结构 3 内核配置和编译实验 4 内核的配置原理 5 menuconfig 6 Kconfig文件详解 7 menuconfig的实验 前言 以下内容基于2 6 35 7版本内核 文件