你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

如何学习嵌入式Linux内核?

[复制链接]
gaosmile 发布时间:2020-6-30 12:42
对于如何学习嵌入式Linux内核,临时想起来一些个人见解和领悟。学习Linux内核,每个人都有一套自己的方法,算是见仁见智吧。一般从事嵌入式Linux驱动和内核开发工作,工程师主要分为两种:一种是做产品研发的,另外一种是做开源社区。作为从事FAE多年的我,认为学习Linux内核比较有效率的,拿出自己的一些个人学习经验给大家做分享。
内核学习

Linux 内核功能越来越完善,如果没有充裕的时间,深入内核并不是很现实。所以建议先读一本内核的书,第一遍是读,会读的很迷糊;之后反省一下,然后再浏览一下;可以想象一个 OS 是如何运行的,这样可以不陷入 Linux 内核的细节;最后可以深入自己感兴趣或者需要的那一子系统。

微信图片_20200630124045.png
推荐学习Linux内核设计与实现
(Linux Kernel Development)
即便是子系统,也是很庞大的。一个省力的方式是网上搜一些相关的文章,便于快速了解这个子系统的运作;然后结合代码,形成自己的认知,最后做一下总结。如果仅仅是快速了解某一子系统的运作,可以参考一些早期代码的注解书籍,再深入的时候看看最新的代码实现。
对内核的认知是一个反复的过程,一开始并不完善,可能需要反复纠正。不要陷入这种纠错中;而是以后继续使用和学习过程中,发现了没有弄清楚的地方再深入,毕竟 Linux 内核是不断变化的。
还有一个很好的方式是,从系统调用入手,现在这方面的数据不少,而且对系统调用的语义都有讲解,这样可以间接了解 Linux 系统的一些概念。对系统调用熟悉了,可以根据系统调用的执行过程,来大体了解内核的一个运作过程;但是跟踪系统调用的时候要注意抓主线,现在内核系统很复杂,一些 code path 上可能会涉及多个子系统,可以从名字上猜测它们是干什么的,不需要深入,否则会发现精力完全被分散掉了。
即便是子系统,也是很庞大的。一个省力的方式是网上搜一些相关的文章,便于快速了解这个子系统的运作;然后结合代码,形成自己的认知,最后做一下总结。如果仅仅是快速了解某一子系统的运作,可以参考一些早期代码的注解书籍,再深入的时候看看最新的代码实现。
对内核的认知是一个反复的过程,一开始并不完善,可能需要反复纠正。不要陷入这种纠错中;而是以后继续使用和学习过程中,发现了没有弄清楚的地方再深入,毕竟 Linux 内核是不断变化的。
还有一个很好的方式是,从系统调用入手,现在这方面的数据不少,而且对系统调用的语义都有讲解,这样可以间接了解 Linux 系统的一些概念。对系统调用熟悉了,可以根据系统调用的执行过程,来大体了解内核的一个运作过程;但是跟踪系统调用的时候要注意抓主线,现在内核系统很复杂,一些 code path 上可能会涉及多个子系统,可以从名字上猜测它们是干什么的,不需要深入,否则会发现精力完全被分散掉了。

学习 Linux 内核,一个很重要的是抽象的能力,所谓的抽象这里仅仅是指分清接口和接口的实现。因为 Linux内核子系统很多,有很多子系统相互渗透,这样 code path 看上去很复杂。阅读代码的时候,为了排除干扰,需要分清哪些是自己需要看的,哪些是其它子系统的接口,对于其它子系统的接口,先当作它们功能完善不会出问题好了,这样可以关注重点;打个比方,一个应用程序的代码可能量很大,比如一个 apache 项目,它包含很多组件,有时候阅读代码的时候会看到不同组件的 API,深入看相关组件实现并不现实,这时候分清主次对于代码的阅读就很有帮助了,总不能看到了 malloc 就要先把它的实现弄清楚吧,系统调用多者呢。

微信图片_20200630124053.png
推荐学习Robert Love的Linux系统编程(第2版)

微信图片_20200630124056.png
Linux编程接口:Linux与Unix系统编程手册

驱动开发

一直围绕服务器做,接触的比较多的是网卡驱动。最开始想着从上到下,好好学习协议栈,后来发现内容太多,进展太慢。后来参考一些驱动开发方面的书籍,把驱动独立开,使用内核提供的接口,就类似写应用的时候很多情况下只需要了解系统接口和库函数的原型描述而不需要继续深入一样。这样把自己从内核复杂的实现细节中解放出来,可以重点看网卡的特性部分;之后可以再深入了解设备的运作过程,比如网卡的收发包在协议栈中的位置和运作。

个人感觉如果工作中能接触驱动开发最好,否则很多情况下,有的设备并不常见,比如 Infiniband 卡。

现在民用设备越来越广泛,可以选择自己感兴趣而手头又容易有的设备进行研究,比如无线网卡、wifi 等驱动开发,一定要先专注一个设备,从头到尾熟悉一遍,然后总结驱动开发是怎样的、驱动是如何关联到系统中的、Linux 采用什么样的分层模式来提供对多种多样设备的支持,如类似 VFS 一样的抽象分层。

微信图片_20200630124100.png
推荐学习Linux设备驱动程序(第3版)

Linux内核子系统要怎么学?

Linux内核有上百个驱动子系统,你是否都研究过内核各种驱动子系统的共性,层次结构设计?对于Linux内核子系统的经验,例如USB、I2C、HID等driver的设计经验,你是否都已经具备了。

从我的学习理解,每一个子系统都巨大无比,而且涉及各种硬件规范,很难去搞明白所有。只能是遇到问题的时候,能对某一部分深入下去。之前了解过 SCSI 的架构,最上层的抽象,中间层的桥梁,最底层的设备驱动控制;如果仅仅是做 driver 的工作,可以把精力放在设备特性上,Linux 内核部分只需要了解驱动
接口和同步、内存管理等基本功能即可。

Linux内核驱动的设计思想

Linux 设备驱动模型是从分类的角度来看待设备,分类是多维的,所以 /sys 下也是多个目录。另外,设备驱动模型给出了系统中设备布局信息,比如:根据总线地址,可以定位对应的设备目录等。

Linux 内核驱动可以都是遵循一个逐层抽象的架构:最上层的抽象层便于系统软件的访问,中间层的实现硬件协议细节,同时提供上下两层连接的接口,对于最下层的 driver 来说,就是要定义底层驱动要实现的接口和实际的设备控制。

由于 Linux 内核各类驱动的框架支持,driver 可以更加关注设备本身的特性。

在Linux嵌入式开发的过程中,我们经常会遇到很多棘手的问题,比如内存泄漏,内核栈溢出,网络丢包等等问题,在定位这类问题时如果没有有效的方法往往会消耗大量的时间去定位排查。
收藏 评论0 发布时间:2020-6-30 12:42

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版