二、编译内核及内核开发的特点

news2024/11/25 3:03:14

在这里插入图片描述

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关注公粽号 《机器和智能》 回复关键词 “python项目实战” 即可获取美哆商城视频资源!


博主介绍:
CSDN博客专家,CSDN优质创作者,CSDN实力新星,CSDN内容合伙人;
阿里云社区专家博主;
华为云社区云享专家;
51CTO社区入驻博主,掘金社区入驻博主,支付宝社区入驻博主,博客园博主。


二、编译内核及内核开发的特点

      • 获取内核源码
      • 编译内核
      • 内核开发的特点
    • 图书推荐 - 点击购买:[链接1](https://item.jd.com/14065180.html) | [链接2](http://product.dangdang.com/29599092.html)


🎉🎉🎉🎉🎉 重磅福利 🎉🎉🎉🎉🎉
🎉本次送2套书 ,评论区抽2位小伙伴送书
🎉活动时间:截止到 2024-02-1610:00:00
🎉抽奖方式:评论区随机抽奖。
🎉参与方式:关注博主、点赞、收藏,评论。
❗注意:一定要关注博主,不然中奖后将无效!
🎉通知方式:通过私信联系中奖粉丝。
💡提示:有任何疑问请私信公粽号 《机器和智能》

在这里插入图片描述
《精通嵌入式Linux编程》本书的每一章都介绍嵌入式Linux的一个主要领域。它描述知识背景,以便你可以了解一般原则,它还包括详细的有效示例来说明这些领域中的操作。


专栏:《Linux内核设计思想与源码分析》


获取内核源码

在Linux内核官方网站即可下载最新Linux源码

点击跳转

我们一般应该下载最新的稳定版本Linux内核源码进行学习。

源码下载后,通过tar命令进行解压即可

tar xvzf linux-X.X.X.tar.gz

解压后源码会存在linux-X.X.X文件夹中。

内核源码一般都安装在 /usr/src/linux 目录下,但我们开发时不要直接对这个源码树进行开发,因为编译C库所用的内核版本就是该源码树。并且一般不要以root身份修改内核,我们应该自己另外建立一个目录,并以root身份在该目录安装新内核,/usr/src/linux 目录应原封不动的继续存在。

一般以补丁的形式发布对代码的修改,并以补丁的形式接收其他人发布的修改。

内核源码树由很多目录组成,其根目录及描述如下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在内核源码树根目录下还有一些文件,COPYING文件是内核许可证,CREDITS是开发者列表并包含了一些内核代码细节,MAINTAINERS是维护内核子系统和驱动程序的维护者列表,Makefile是编译内核的基础。

编译内核

内核源码在编译时可以进行配置和定制,我们可以把自己需要的功能和驱动程序编译进内核。可以配置的选项以CONFIG_FEATURE形式表示,比如,对称多处理器(SMP)的配置选项为CONFIG_SMP,如果设置了该选项,则SMP启用,否则SMP不起作用。配置选项可以用来决定那些文件编译进内核,选项有二选一和三选一,yes/no/module。在三选一的情况下多了一个 module 选项,如果选择 module 选项,表示该配置项已被选定,但编译的时候这部分功能的实现代码是以模块(一种可以动态安装的独立代码段)的形式生成,而 yes 选项表示把代码编译进主内核映像,而不是作为一个模块。

配置选项也可以是字符串或者整数,这些选项不用于控制编译过程,而是用于指定内核源码可以访问的值,一般以预处理宏的形式表示,比如我们可以通过配置选项指定静态分配数组的大小。

内核提供了很多工具来简化内核配置过程,最简单最耗时的是命令行工具,该工具会遍历所有选项并让你选择配置选项 yes/no/module

make config

还有其他更方便的图形工具可供使用

make menuconfig
make xconfig
make gconfig
make defconfig #创建默认配置

也可以查看并修改配置文件来修改这些配置选项,这些选项存放在内核源码树目录的 config 文件中。

通过如下命令验证并更新配置

make oldconfig

配置完成后,就可以编译内核了,使用命令

make

在编译时,往往会打印很多信息并刷屏,如果不想看到这些信息,可以执行下面命令来编译

make > /dev/null

编译好内核后,就到了安装步骤。安装内核与操作系统体系结构和启动引导工具(boot loader)相关,按照要求将内核映像拷贝到适当位置。这个过程可能需要把某个模块拷贝到指定目录,并且需要编译相应的配置文件,建立启动项等等。

我们可以通过命令来把编译好的模块安装到正确的主目录 /lib 下

make modules install

这个命令需要 root 权限。

编译时还会在内核代码树的根目录下创建一个 System.map 文件,这是一个符号对照表,用来将内核符号和它们的起始地址一一对应,调试时可以把内存地址翻译成函数名或变量名以便于理解。

内核开发的特点

内核编程时不能访问C库,即没有 libc 库。

在用户空间编程时,我们可以调用C库函数,但是在内核编程时,内核无法链接标准C函数库,实际上其他一些库也无法使用。但是大部分C库函数都已经在内核中实现了,只要包含相应头文件就可以调用,比如字符串操作函数库 lib/string.c,头文件为<linux/string.h>。

在内核编程时,所用的头文件都是源码树的内核头文件,内核源码文件不能包含外部头文件。

在内核中也有一些C库函数并没有实现,比如 printf() 函数,但是内核中实现了一个叫 printk() 的函数。printk() 函数负责把格式化好的字符串拷贝到内核日志缓冲区,syslog 程序通过读取该缓冲区来获取内核信息。并且 printk() 函数允许通过指定一个标志来设置优先级,syslog 程序根据这个优先级标志来决定在什么地方显示这条系统消息。

内核编程时必须使用 GNU C 。

我们知道,Linux 内核是使用C语言编写的,但是,内核代码并不完全符合 ANSI C 标准,它用到了 gcc 提供的许多语言扩展部分。gcc 是多种 GNU 编译器的集合,它包含的C编译器既可以编译内核,也可以编译 Linux 系统上的其它C源代码。总之,内核开发者使用的C语言包含 ISO C99 标准以及 GNU C 扩展特性。下面列举内核源码中使用到的一些C语言扩展:

① 内联函数(inline)

内联函数顾名思义,就是“在字里行间展开”的意思,内联函数会在它被调用的位置展开,这样做消除了函数调用和返回所带来的开销,比如寄存器的存储和恢复等。而且,编译器会把调用函数的代码和函数本身放在一起进行优化,这就有了代码进一步优化的可能。当然内联函数也有缺点,那就是会使代码变长,会占用更多的内存空间和指令缓存。

我们通常把一些对时间要求高,且本身代码长度较短的函数定义为内联函数。那些对时间要求不高且被反复调用的函数不要定义为内联函数。

再定义一个内联函数时,通常需要使用 static 关键字,并且需要使用 inline 进行限定。

static inline func(){
    ;
}

内联函数必须在使用之前就定义好,否则的话编译器无法进行函数展开。在编程时,通常在头文件中定义内联函数(如果内联函数仅在某个源文件中使用,也可以在该文件头部定义内联函数)。由于使用了 static 关键字,编译时不会为内联函数单独建一个函数体。在内核编程时,考虑到类型安全因素,应优先使用内联函数而不是宏。

② 内联汇编

gcc 编译器支持在C函数中嵌入汇编指令,Linux 内核就是用了C和汇编混合编程,在偏近体系结构的底层或对执行时间要求严格的地方,一般都是使用汇编语言编写的。

③ 分支声明

对于条件选择语句,gcc 内建了一条指令用于优化,如果一个条件经常出现或者很少出现,编译器就可以根据这条指令对条件分支进行优化。在内核中,这条指令被封装成了宏,比如 likely() 和 unlikely()。例如下面一个条件选择语句

if(flag){
    ;
}

如果 flag 为0的概率远远大于它为真的概率,也就是说 flag 这条分支大概率不会发生,我们可以标记为

/* 我们认为flag大概率为0 */
if(unlikely(flag)){
    ;
}

反之

/* 我们认为flag大概率为1 */
if(likely(flag)){
    ;
}

这种标记大幅提升性能的前提是你的判断是正确的,如果判断错了可能反而会大幅度降低性能。

内核编程时没有像用户空间那样的内存保护机制。

如果是一个用户程序对内存进行非法访问,那么内核会报错,发送 SIGSEGV 并结束进程。但是,如果是内核自身非法访问内存,那么可能它会直接死掉并且不会报错。内核中的内存错误会导致 oops,这也是内核中出现较多的一类错误,并且内核中的内存不会分页,每用掉一个字节,物理内存就减少一个字节。

内核编程时不要轻易使用浮点数。

如果我们在用户空间进行浮点操作,内核会完成从整数操作到浮点操作的转换。但是在内核中使用浮点数会非常麻烦,这需要你人工保存和恢复浮点寄存器,以及其他一些操作都要人工完成,所以在内核编程时不要使用浮点数。

内核只有一个很小且固定的堆栈。

用户空间栈是非常大的,并且可以动态增长,因此我们可以在用户空间编程时分配大量栈内存。但是内核栈的大小是固定的,它和体系结构有关,在 x86 上,栈的大小在编译时配置,可以是4KB或8KB,一般来说,内核栈的大小是两页,在32位机器内核栈大小为8KB,在64位机器内核栈大小为16KB,这是固定的,每个处理器都有自己的栈。

由于内核支持异步中断、抢占和SMP,所以必须时刻注意同步和并发。

内核是很容易产生竞争条件的,内核的许多特性都要求能够并发的访问共享数据,这就要求有同步机制保证不出现竞争条件。

  • Linux是抢占多任务操作系统,内核的进程调度程序即兴对进程进行调度和重新调度,内核必须对这些任务同步。
  • Linux内核支持多处理器系统,如果没有保护,在多个处理器上运行的代码很可能会同时访问共享的同一资源。
  • 中断是异步到来的,不会考虑正在执行的代码,如果不加保护,中断有可能会在代码访问共享资源时到来,而中断处理程序也有可能会访问该共享资源。
  • Linux内核可以抢占,如果不加保护,内核中正在执行的代码可能会被另一段代码抢占,并且这几段代码可能同时访问相同资源。

通常使用自旋锁和信号量来解决竞争问题。

需要考虑可移植性。

Linux是一个可移植的操作系统,也就是说大部分C代码应该与体系结构无关,在各种不同体系结构的计算机上都能编译和执行,这就意味着,必须把体系结构相关的代码从内核代码树的特定目录中分离出来。

图书推荐 - 点击购买:链接1 | 链接2

多年来,Linux一直是嵌入式计算的中流砥柱。然而,涵盖该领域所有主题的书籍非常少,本书旨在填补这一空白。“嵌入式Linux”一词的定义并不明确,它可以应用于从恒温器到Wi-Fi路由器,再到工业控制单元的各种设备内的操作系统。但是,它们都建立在相同的基本开源软件之上。这些正是我们在本书中要描述的技术,本书的写作基于我们作为工程师的经验和为培训课程开发的资料。

书名:《精通嵌入式Linux编程》
作者:弗兰克·瓦斯奎兹
出版社:清华大学出版社
在这里插入图片描述

内容简介:《精通嵌入式Linux编程》详细阐述了与嵌入式Linux开发相关的基本解决方案,主要包括初识嵌入式Linux开发、关于工具链、引导加载程序详解、配置和构建内核、构建根文件系统、选择构建系统、使用Yocto进行开发、Yocto技术内幕、创建存储策略、现场更新软件、连接设备驱动程序、使用分线板进行原型设计、init程序、使用BusyBox runit启动、管理电源、打包Python程序、了解进程和线程、管理内存、使用GDB进行调试、性能分析和跟踪、实时编程等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。 本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册。

在这里插入图片描述
在这里插入图片描述

多年来,Linux一直是嵌入式计算的中流砥柱。然而,涵盖该领域所有主题的书籍非常少,本书旨在填补这一空白。“嵌入式Linux”一词的定义并不明确,它可以应用于从恒温器到Wi-Fi路由器,再到工业控制单元的各种设备内的操作系统。但是,它们都建立在相同的基本开源软件之上。这些正是我们在本书中要描述的技术,本书的写作基于我们作为工程师的经验和为培训课程开发的资料。
技术不会停滞不前。基于嵌入式计算的行业与主流计算一样容易受到摩尔定律的影响。这种指数级的增长意味着自本书第一版出版以来发生了惊人的大量变化。你现在正在阅读的第三版经过全面修订,使用最新版本的主要开源组件,包括Linux 5.4、Yocto Project 3.1 Dunfell和Buildroot 2020.02 LTS。除了Autotools,本书还包含CMake,这是一种新构建系统,近年来得到了越来越多的采用。
本书大致按照你在实际项目中遇到的顺序来涵盖这些主题。第1篇包括第1~8章,涉及项目的早期阶段。本篇涵盖选择工具链、引导加载程序和内核等基础知识。我们以Buildroot和Yocto项目为例介绍嵌入式构建系统的概念。本篇以对Yocto Project的新深入研究结束。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

在这里插入图片描述


❗❗❗重要❗❗❗☞关注下方公粽号 《机器和智能》 回复关键词 “python项目实战” 即可获取美哆商城视频资源!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1433913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

istio 限流

#详细参数看官网&#xff0c;我参数就不解释https://istio.io/latest/docs/reference/config/networking/destination-rule/cat << EOF > dr.yaml apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata:name: my-testnamespace: demon spec:hos…

【优先级队列(大顶堆 小顶堆)】【遍历哈希表键值对】Leetcode 347 前K个高频元素

【优先级队列&#xff08;大顶堆 小顶堆&#xff09;】【排序】Leetcode 347 前K个高频元素 1.不同排序法归纳2.大顶堆和小顶堆3.PriorityQueue操作4.PriorityQueue的升序&#xff08;默认&#xff09;与降序5.问题解决&#xff1a;找前K个最大的元素 &#xff1a;踢走最小的&…

【JavaSE篇】——抽象类和接口

目录 &#x1f393;抽象类 &#x1f388;抽象类语法 &#x1f388;抽象类特性 &#x1f388;抽象类的作用 &#x1f393;接口 &#x1f388;语法规则 &#x1f388;接口特性 &#x1f388;接口使用(实现USB接口&#xff09; &#x1f388;实现多个接口 &#x1f388;…

深度学习系列57: 清华大模型MiniCPM上手

MiniCPM 是面壁智能与清华大学自然语言处理实验室共同开源的系列端侧大模型&#xff0c;主体语言模型 MiniCPM-2B 仅有 24亿&#xff08;2.4B&#xff09;的非词嵌入参数量 1. 上手对比测试 mps比cpu大概快了9倍左右。 也可以在modelspore上测试&#xff1a;

【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题

目录 1、题目介绍 2、解题思路 2.1、暴力破解法 2.2、经典Next Greater Number问题解法 1、题目介绍 原题链接&#xff1a;496. 下一个更大元素 I - 力扣&#xff08;LeetCode&#xff09; 示例1&#xff1a; 输入&#xff1a;nums1 [4,1,2], nums2 [1,3,4,2].输出&…

AMH面板如何安装与公网远程访问本地面板界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

html2Canvas截取百度地图问题整理及解决方案

目录 一、截图地图打点出不来二、截图报错Uncaught (in promise)html2Canvas属性大全 一、截图地图打点出不来 1.开启foreignObjectRendering 原因是地图打点中含有svg var canvas await html2canvas(obj, {useCORS: true, foreignObjectRendering: true})2.页面图片转base6…

Multi ElasticSearch Head插件基本操作

Multi ElasticSearch Head插件安装好之后我们可以进行一些基本的操作。 1、复合查询 因为ES提供了一些Restful风格的接口&#xff0c;可以让任何语言去调用&#xff0c;因此我们可以将之前的请求地址粘贴到Multi ElasticSearch Head插件里面&#xff0c;选择GET请求方式&#x…

WordPress主题YIA如何将首页的置顶小工具改为站长推荐小工具?

YIA主题有“置顶推荐”小工具&#xff0c;首页文章列表页有置顶功能&#xff0c;可在YIA主题设置 >> 列表 >> 首页-最新发布 >> 显示置顶文章中开启或关闭。如果将“置顶推荐”小工具添加到“首页顶栏”&#xff0c;同时也开启首页最新发布的“显示置顶文章”…

Java使用规范

1.关键字 定义&#xff1a;被Java语言赋予了特殊含义&#xff0c;用做专门用途的字符串(单词) 特点&#xff1a;关键字中的所有字母都是小写 2.保留字 java保留字&#xff1a;现有Java版本尚未使用&#xff0c;但以后的版本可能会作为关键字使用。命名标识符时要避免使用这些…

C# wpf 字体图标预览,html字符与unicode转换

在进行wpf 开发工作过程中遇到字体图标无法预览的问题&#xff0c;特此记录。 1、把需要预览的字体文件上传到网站上进行转换 Create Your Own font-face Kits Font Squirrel2、下载文件后进行解压。 3、找到 Glyph Chart 查看字体html字符编码4、在wpf中直接使用即可 <…

C#,河豚算法(Blowfish Algorithm)的加密、解密源代码

Bruce Schneier 1 河豚算法&#xff08;Blowfish Algorithm&#xff09; 河豚算法&#xff08;Blowfish Algorithm&#xff09;是1993年11月由Bruce Schneier设计的一个完全开源的算法。 Blowfish算法是一个分组长度为64位、密钥长度可变的对称分组密码算法。 Blowfish算法具…

Redis 持久化对性能有何影响?

Redis 持久化对性能的影响 Redis 是一个高性能的内存数据存储系统&#xff0c;通常被用于缓存、消息队列和数据存储等方面。由于 Redis 是基于内存的&#xff0c;因此它的读写速度非常快&#xff0c;可以满足高并发、低延迟的应用需求。但是&#xff0c;当 Redis 需要持久化数…

Git的一些基本操作

初始git 我们给出下面的一个场景&#xff0c;在大学里&#xff0c;一些老师在我们做完实验之后喜欢让我们交实验报告&#xff0c;假设我们有一个比较追求完美的老师和一个勤奋的学生&#xff0c;这个学生叫做小帅&#xff0c;那天小帅桑勤奋的完成实验报告&#xff0c;在第二天…

L1-016 查验身份证-java

输入样例1&#xff1a; 4 320124198808240056 12010X198901011234 110108196711301866 37070419881216001X输出样例1&#xff1a; 12010X198901011234 110108196711301866 37070419881216001X输入样例2&#xff1a; 2 320124198808240056 110108196711301862输出样例2&#…

银行数据仓库体系实践(18)--数据应用之信用风险建模

信用风险 银行的经营风险的机构&#xff0c;那在第15节也提到了巴塞尔新资本协议对于银行风险的计量和监管要求&#xff0c;其中信用风险是银行经营的主要风险之一&#xff0c;它的管理好坏直接影响到银行的经营利润和稳定经营。信用风险是指交易对手未能履行约定契约中的义务而…

【AIGC核心技术剖析】DreamCraft3D一种层次化的3D内容生成方法

DreamCraft3D是一种用于生成高保真、连贯3D对象的层次化3D内容生成方法。它利用2D参考图像引导几何塑造和纹理增强阶段&#xff0c;通过视角相关扩散模型执行得分蒸馏采样&#xff0c;解决了现有方法中存在的一致性问题。使用Bootstrapped Score Distillation来提高纹理&#x…

Backtrader 文档学习- Observers

Backtrader 文档学习- Observers 1.概述 在backtrader中运行的策略主要处理数据源和指标。 数据源被加载到Cerebro实例中&#xff0c;并最终成为策略的一部分&#xff08;解析和提供实例的属性&#xff09;&#xff0c;而指标则由策略本身声明和管理。 到目前为止&#xff0c…

python文字识别

Tesseract 文字识别是ORC的一部分内容&#xff0c;ORC的意思是光学字符识别&#xff0c;通俗讲就是文字识别。Tesseract是一个用于文字识别的工具。 Tesseract的安装及配置 https://digi.bib.uni-mannheim.de/tesseract/ 在上述链接下载自己需要的版本。下载后安装&#xff…

chisel之scala 语法

Chisel新手教程之Scala语言&#xff08;1&#xff09; Value & variable Value是immutable的&#xff0c;当它被分配一个数据后&#xff0c;无法进行重新分配。用 val 表示。 Variable是mutable的&#xff0c;可以重复赋值。用 var 表示。示例如下&#xff1a; val a …