「转」Linux 内核精通

本文由 简悦 SimpRead 转码, 原文地址 zhuanlan.zhihu.com

一、为什么要学习 Linux 内核

大部分程序员可能永远没有机会开发 Linux 内核或者驱动 Linux,那么我们为什么还需要学习 Linux 内核呢?Linux 的源代码和架构都是开放的,我们可以学到很多操作系统的概念和实现原理。Linux 的设计哲学体系继承了 UNIX,现在整个设计体系相当稳定和简化,这是大部分服务器使用 Linux 的重要原因。

那学习 Linux 内核的原因就在于此。

进一步了解内核的原理,有助于你更好地使用命令和程序设计,让你的面试和开发更上一层楼。但是不建议直接看源代码,因为 Linux 代码太大,容易丢失。

而最好的办法是,先了解一下 Linux 内核机制,知道基本的原理与流程。

不过,Linux 内核机制也非常复杂,而且其中互相关联。

比如说,进程运行要分配内存,内存映射涉及文件的关联,文件的读写需要经过块设备,从文件中加载代码才能运行起来进程。这些知识点要反复对照,才能理清。

但是一旦攻克!你会发现 Linux 这个复杂的系统开始透明起来。

二、如何学习 Linux 内核?

内核的知识就像下面的绳结一样,一环扣一环,我们要解开它们,就必须要先找到线头也就是内核中的函数接口。初学阶段,我们一般不深入的研究内核代码,会使用内核的接口函数就不错了。

下面提供了如何学习这些内核函数的方法,就像解绳子一样

在我们学习 Linux 内核之前,我们首先需要掌握以下几点:

(1) 如何学习内核,先了解 Linux 内核由哪些组成?

(2) 须知 Linux 内核源码(下载的链接 )组织结构?

(3) 重点需要学习地知识点有哪些?

(4) 最后依据我为大家提供的的学习资料,开启我们的 Linux 内核学习之旅。

(5) 全网最牛 Linux 内核 Makefile 系统文件详解 (纯文字代码)

(6) 全网最详细的 Intel CPU 体系结构分析 (内核源码)

(7) 深入理解 Linux Kernel 内核整体架构 (图文详解)

(8)QEMU 调试 Linux 内核环境搭建

(9) 网友说 Linux 驱动讲不彻底,原来这才是 Linux 驱动

(10) 一文让你深度了解 Linux 内核架构和工作原理

(11) 从 Linux 内核看 socket 底层的本质 (IO)

(12)Linux 用户空间与内核空间通信 (Netlink 通信机制)

二,学习资料

2.1 操作系统原理

【 强烈推荐阅读】一文带你彻底了解,零拷贝 Zero-Copy 技术 (图解)

Linux 操作系统学习——启动

Linux 操作系统学习——内核运行

Linux 操作系统学习——内核初始化

操作系统原理 (一):操作系统原理与概述 (流程图)

操作系统原理 (二):Linux 操作系统基础的常用命令

操作系统原理 (三):Linux 操作系统 I/O 机制原理 (流程图详解)

操作系统原理 (四):内存管理 RAID 磁盘阵列与配置

操作系统原理 (五):内存管理之磁盘高速缓存机制原理

操作系统原理 (六):存储管理之页式、段式、段页式存储

系统操作原理 (七):进程的状态和转换 (五态模型)

操作系统原理 (八):进程同步的几种方式及基本原理

操作系统原理 (九):处理器调度基本准则和实现原理

系统操作原理 (十):多进程,多线程,并发执行中的死锁问题

系统操作原理 (十一):操作系统原理:进程同步的几种方式及基本原理

系统操作原理 (十二):趣谈操作系统原理,存储管理之页式、段式、段页式存储

系统操作原理 (十三):操作系统:通过实战理解 CPU 上下文切换

汇编语言基础 (十一):汇编语言基础知识 (图文代码)

汇编语言入门 (十二):汇编指令入门级整理,这些你必须要知道

汇编语言指令 (十三):汇编语言的所有指令总结,一篇就够了

汇编语言进阶 (十四):ARM 体系结构处理器机制原理与实现

汇编语言进阶 (十五): ARM 指令集与汇编语言程序设计

2.2 内存管理专题

【 强烈推荐阅读】尽情阅读,技术进阶,详解 mmap 原理

内存是什么?一文让你了解内存是怎么实现的

嵌入式开发必备技能,Linux 内核源码组织结构

一文了解 Linux 内存管理,malloc、free 实现原理

内存管理系列 (一):Linux 操作系统内存管理 (思维导图详解)

内存管理系列 (二):Linux 内存管理原理知识大总结

内存管理系列 (三):学完操作系统内存管理,能回答这 8 个问题吗?

内存管理系列 (四):理解 Memory barrier(内存屏障)

内存管理系列 (五):内存回收之 LRU 链表机制原理

内存管理系列 (六):虚拟内存和物理内存机制原理

内存管理系列 (七):Malloc 缺页中断不同情况处理总结及反向映射 RMAP

内存管理系列 (八):C/C++ 开发中的 Malloc 函数的实现原理

内存管理系列 (九):深入理解 glibc malloc:内存分配器实现原理

内存管理系列 (十):操作系统是如何对内存进行管理的,内存与 CPU 之间的关系

内存管理系列 (十一):为什么 Linux 需要虚拟内存,虚拟内存对操作系统有哪些作用

内存管理系列 (十二):用户态内存内存映射函数 Mmap 的好处

内存管理系列 (十三):内存管理:详解虚拟地址空间 - MMU

内存管理系列 (十四):C 语言中的 Malloc/free 是如何分配内存的

内存管理系列 (十五):从虚拟寻址到开源项目,Linux 下的内存管理详解

内存管理系列 (十六):一文带你了解,虚拟内存、内存分页、分段、段页式内存管理

内存管理系列 (十七):Linux 应用程序究竟消耗了多少内存

内存管理系列 (十八):虚拟地址到物理地址,是什么时候开始映射

内存管理系列 (十九):浅析 Linux 内存管理中 SLAB 分配器 (源码分析)

内存管理系列 (二十):基于 Linux 内存管理的内存分配 (伙伴算法和 slab 算法)

内存管理系列 (二十一):探索内存原理的内存映射文件 (图文详解)

内存管理系列 (二十二):吊打字节面试官,CPU 缓存一致性协议 MESI

内存管理系列 (二十三):深入理解 Linux 内核页表映射分页机制原理

内存管理系列 (二十四):谈谈物理内存与虚拟内存之间的映射 (超详细~)

内存管理系列 (二十五):内存管理:C/C++ 开发中的 malloc 函数的实现原理

内存管理系列 (二十六):熬夜肝翻 Linux 内存管理所有知识点 (图解)

2.3 进程管理专题

进程管理系列 (一):Linux 进程管理原理详解 (代码演示)

进程管理系列 (二):十分钟让你像大佬一样快速了解进程状态 (二种模型)

进程管理系列 (三):作为互联网程序员,应该了解 Linux 进程六种状态吗?

进程管理系列 (四):五分钟让你快速了解 Linux 进程管理实时调度与 SMP

进程管理系列 (六):浅析 Linux 的进程优先级 (代码演示)

进程管理系列 (七):进程管理 | 浅析 C 语言中并发同步与原子操作,锁三者是什么关系

进程管理系列 (八):进程管理 | 深入理解 Linux 进程述符和进程状态

进程管理系列 (九):一文读懂 Linux 内核中的任务间调度策略

进程管理系列 (十):Linux 内核之进程和线程的创建和派生

进程管理系列 (十一):基于 Linux 有几种进程状态

进程管理系列 (十二):操作系统的几种 CPU 调度策略

进程管理系列 (十二):Linux 进程管理之调度和进程切换

进程管理系列 (十三):一文搞懂六大进程通信机制原理 (全网最详细)

进程管理系列 (十四):超详细的 Socket 通信原理和实例讲解 (白嫖走起~)

进程管理系列 (十五):这是一份很全很全的 IO 基础知识与概念

进程管理系列 (十六):深入理解 Linux 内核进程的管理与调度 (全知乎最详细)

2.4 网络协议栈专题

【 强烈推荐阅读】嵌入式必备:如何学习 Linux 内核网络协议栈

趣谈网络协议栈 (一):套接字缓冲区原理

趣谈网络协议栈 (二):数据包是如何处理的过程

趣谈网络协议栈 (三):七层模型下三层数据通信

趣谈网络协议栈 (四):传输的 Arp 报文结构

趣谈网络协议栈 (五):Socket 编程常用函数的原理及代码实现

趣谈网络协议栈 (六):学习 select 和 poll 函数的内核实现

趣谈网络协议栈 (七):Epoll 从用户态到内核态过程分析

趣谈网络协议栈 (八):套接字发送网络数据的过程

2.5 设备驱动专题

浅谈设备驱动 (一):操作系统 I/O 流程详解

浅谈设备驱动 (二):Linux 操作系统学习之字符设备

浅谈设备驱动 (三):结合设备信息集合,探究设备和驱动是如何绑定的

2.6 文件系统

详谈文件系统 (一):一文让你彻底了解 Linux 内核文件系统 (大总结)

2.7 面试题 / 经验

【 强烈推荐阅读】从事十年嵌入式转内核开发 (23K 到 45K), 给兄弟们的一些建议

谈谈 Linux 内核的学习路线,具体要怎么学?

2022 年嵌入式开发想进互联网大厂,你技术过硬吗?

嵌入式 Linux 内核学习经验总结,一篇让你掌握方法

盘点 Linux 内核 (驱动开发,嵌入式,内核人群) 必问的面试题

2022 春招大厂 - 嵌入式开发经典笔试面试题目大整理

2.8 内核书籍

  • 《深入了解 Linux 内核》
  • 《Linux 就该这么学》
  • 《Linux 内核完全注释 V3.0 书签版》
  • 《Linux 命令行大全 - 绍茨 (william E.shotts)》
  • 《Linux 命令速查手册》
  • 《Linux 性能优化大师》
  • 《Linux 环境编程:从应用到内核》
  • 《Linux 集群和自动化运维 余洪春》
  • 《Linux 驱动程序开发实例 (第 2 版)》
  • 《Linux 高级程序设计 (第 3 版)》
  • 《构建高可用 Linux 服务器 (第 4 版)》

书籍免费领取地址:https://docs.qq.com/doc/DTkZRWXRFcWx1bWVx

三,内核学习路线

很多同学对 Linux 接触很少,对 Linux 平台的开发一无所知。现在,趋势越来越表明,作为一个优秀的软件开发者或者计算机 IT 从业者,掌握 Linux 是一个非常重要的谋生资源和手段。接下来我将结合我个人几年的开发经验,谈谈 Linux 的学习方法和学习中应该注意的一些事情,特别是关于 Linux,类 UNIX 系统和开源软件文化。

就像我刚才说的,很多同学之前可能连 Linux 是什么都不知道,更别说 UNIX 了。所以我们从最基础的一点开始,Linux 和 UNIX 的历史我们就不多说了,直接进入入门学习。

Linux 入门非常简单。问题是你有没有耐心,有没有爱折腾,有没有不排除重装之类的大修。可以说不折腾是学不好 Linux 的。鸟哥说你要真正了解 Linux 的分区机制,并且对 LVM 的使用相当熟练。不超过 20 次是无法积累 Linux 安装经验的,所以不要怕折腾。

既然之前大家都用 Windows,我也尽量照顾这些 “菜鸟”。我的推荐,如果你是第一次接触 Linux,那就先在虚拟机里试试。我推荐虚拟机用的 Virtual Box。我不提倡使用 VM,因为 VM 是开源的,是收费的。我不想推广盗版。当然,如果你有足够的钱,你可以试试 VM,但我想说的是,即使是 VM 也不一定好。付费软件不一定好。首先,虚拟盒子很小。Windows 平台下安装包 80MB 左右,而 VM 每转 600MB。虽然很强大,但是消耗了很多资源。更何况虚拟盒子完全可以满足你的需求。所以,还是自己选比较好。如何使用虚拟机是你的事。这个就不教你了,因为很简单。如果不能,可以用谷歌或者百度。如果你英语好,可以直接看官方文件。

现在介绍 Linux 发行版的知识。正如你所见,Linux 发行版并非 Linux,Linux 仅是指操作系统的内核,作为科班出生的你不要让我解释,我也没时间。

我推荐的发行版如下:

  1. UBUNTU 适合纯新手,追求稳定的官方支持,对系统稳定性要求弱,喜欢最新的应用,相对不喜欢折腾开发者。
  2. 比 UBUNTU 难很多的发行版 Debian,特点是稳定易用的包管理系统,缺点是缺乏企业支持,以社区开发为驱动。
  3. Arch,追逐时尚的开发者首选,优点是包更新相当快,升级无缝。基本上一次安装就可以一直工作,没有 UBUNTU 那样的版本概念。专业点叫滚动升级,让你的系统保持最新。缺点很明显,不稳定。同时安装配置也比 Debian 麻烦。
  4. 比 Arch 更难的 Gentoo,考验用户的综合水平。从系统安装到微调,内核编译都是手把手。是高手和黑客展示自己技术手段,按需配置符合自己要求的系统的首选。

Slackware 与 Gentoo 类似:

社区维护的 RedHat 的副本 CentOS,完全是用 RedHat 的源代码重新编译的,理论上和 RedHat 的兼容性是最好的。如果你专注于 Linux 服务器,比如网络管理和网站建设,那么 CentOS 就是你的选择。

LFS,终极黑客炫耀工具,完全从源代码安装编译系统。在安装之前,您只能获得一个文档。您所要做的就是按照文档中的说明,一步一步,一个订单一个订单地,一个一个地构建您的 Linux 包。完全在你的掌控之中,你想要什么就有什么。如果你制作了 LFS,那就证明你的 Linux 技术相当不错。如果你能借鉴 LFS 文档,把 Linux 从源代码移植到嵌入式系统,我敢说你能在中国企业做得很好。

你得挑一个适合自己的系统,然后装在虚拟机里开始用。如果你想快速学习 Linux,我有一个建议,你应该忘记图形界面。不要去想图形界面能不能为你的问题提供答案,而是去世界各地寻找,询问如何用命令行解决你的问题。在这个过程中,你最好掌握好 Linux 的命令,至少要知道常用的命令,同时要建立自己的知识库,里面包含了你积累的知识。

下一阶段需要学习 Linux 平台的 C++/C++ 开发,以及 Bash 脚本编程,如果对 Java 有很深的兴趣,还需要学习 Java。同样,我建议你抛弃图形界面的 IDE,从 VIM 开始。为什么是 VIM 而不是 Emacs?我无意挑起编辑器大战,但我认为 VIM 适合新手和手笨脑慢的开发者。Emacs 的按键太多,太复杂,我很害怕。然后是 GCC,Make,Eclipse(Java,C++ 或者)。虽然 Eclipse 中列出了 C++,但是我不建议用 IDE 开发 C++,因为这不是 Linux 的文化,你很容易忽略一些应该注意的问题。IDE 让你懒的跟猪一样懒。如果你对程序调试和测试感兴趣,你必须学好 GDB。如果不是 GDB,这也是一门必修课。这是发展的第一步。注意,我没有提到任何关于 Linux API 的东西,现阶段也不关心这个。你要做的就是积累经验,Linux 平台开发的经验。我推荐的书如下:《C 语言编程》,或者谭浩强的。c,白皮书当然更好。++C++ Primer Plus 是 C 推荐的,我不喜欢 Java,所以不推荐。工具推荐 VIM 的官方手册,GCC 中文文档,GDB 中文文档,GNU 开源软件开发指南 (电子书),汇编语言编程 (让你对库,链接,嵌入式汇编,编译器优化选项有个初步的了解,不深入)。

如果过不了这个阶段,就不用做了。这是底线,也是最基本的基础。否则,离开,不要开发 Linux。不专业的 Linux 开发者做出来的程序与 Linux 文化或者 UNIX 文化相悖,程序走不了多远,也不可能像 Bash、VIM 这样神奇的产品。所以做不好就走人。

接下来进入 Linux 系统编程,唯一的选择,APUE,UNIX 环境下的高级编程。反复读,10 遍太少。如果你在大学能把这本书砸了,里面的内容都练过了,有作品,口语表达能力足够强,面试的时候就能说服所有考官。(可能有点夸张,但 APUE 绝对是圣经读物,连 Windows 程序员都从中汲取养分。谷歌创始人的案头书,扎伯克的床头读物。)

看完这本书,你会对 Linux 系统编程有很好的了解。Linux 和 Windows 平台有什么区别?它们的优缺点是什么?我的总结如下: Windows 平台开发难。微软的系统 API 一直在扩展。如果你想使用最新最高效的功能,你必须时刻学习最适合当前流行系统的功能。不,Linux 有大约 100 个核心 API,所以你可以用很好的记忆力记住它们。而且会长期不变。为什么不呢?因为它兼容 UNIX,符合 POSIX 标准。因此,Linux 平台的开发大多集中在底层或服务器编程上。这是它的优势。当然图形是 Linux 的软肋,但从一个开发者的角度来说,我不在乎,因为我也能适应命令行。如果有更好的图形界面,我会把它作为礼物。另外,Windows 是关闭的,你甚至不知道系统做了什么。你将永远被微软牵着鼻子走。想想吧。如果微软说 Win8 不支持 QQ,腾讯也不会哭死。而且 Linux 是完全开源的。如果不喜欢,可以自己改,只要足够熟练。另外,虽然 Windows 使用的人很多,但是使用的场合比较单一,以桌面为主。Linux 各方面都有发展,尤其是云计算、服务器软件、嵌入式领域、企业应用,兼容性一流。由于 POSIX 可以在 UNIX 系统上无缝运行,因此 Apple Mac 和 IBM AS400 系列都完全支持它。另外,Linux 的开发环境支持绝对一流,无论是 C/C++,Java,Bash,Python,PHP,Javascript,。。。。。。连 C# 都支持。而且微软除了 Visual Stdio 套件都不太友好吧?

如果你看了 APUE 后有很多感触,想验证你的一些想法或经验,推荐 UNIX 编程艺术,世界顶尖黑客将与你分享他们的观点。现在是时候转移注意力了。总的来说,我分为四个方向: 网络、图形、嵌入式、设备驱动。

如果选择网络,细分的话,其他的不太熟悉,只说服务器软件编写和高性能并发程序编写。相对来说,这是网络编程中技术含量最高的,也是最底层的。需要很多经验,看很多书,做很多项目。

我的看法是以下面的顺序来看书:

  1. APUE 的深度阅读——尤其是进程、线程、IPC、套接字
  2. 多核编程——Pthread 一定要吃透,你是 NB
  3. UNIX 网络编程–第 1 卷,第 2 卷
  4. TCP/IP 网络详解——是时候再看一遍以上两本书了。
  5. TCP/IP 网络的详细说明–第 2 卷。我觉得看第二卷就差不多了。当然,最好还是看第三卷。尽力去看吧。
  6. Lighttpd 源代码——这个服务器也很有名。
  7. NGX 源代码——与 Apache 相比,Nginx 的源代码更少。如果能大致看一下,就是 NB 了。看源码主要是学习里面的 socket 编程和并发控制,想想就激动。如果你有这些技能,你可以试试给暴雪发简历,给他们写服务器后台,以为全世界的魔兽都运行在你的服务器软件上。
  8. Linux 内核 TCP/IP 协议栈——深入了解 TCP/IP 实现
  9. 如果还是喜欢驱动设计,可以看看底层协议,比如链路层。给路由器,网卡,网络设备,嵌入式系统软件写驱动应该不是问题。当然,一般的网络公司,哪怕是百度级别的,都应该毫不犹豫的录用你。看后面的书只需要时间和经验,所以 35 岁之前就做吧!跳槽到给你未来的地方!

图形方向,我觉得图形方向也是很有前途的,以下几个方面:

Opengl 的工业和游戏开发在国外已经比较成熟。

动画特效,比如皮克斯,在国外也比较成熟。

GPU 计算技术可以应用于浏览器网页渲染和 GPU 计算资源利用。因为开源,所以有很多文档程序可以参考。如果能进入火狐开发,或者谷歌做浏览器开发,应该很不错。

嵌入式方向:嵌入式方向没说的,Linux 很重要

掌握多种架构,不仅仅是 X86,ARM,MCU 等。必须理解。如果你不懂硬件,我预见你会死在路上,我也想往嵌入式方向走,但是我觉得就算是学电子的学生也比不过学校教嵌入式的方式。我劝你,做之前一定要了解硬件。如果你去做嵌入式应用开发,只能祝你好运了。不要碰上诺基亚、惠普这样的公司,否则你会很惨。

驱动设计: 软件开发周期很长,硬件不一样,很快。每个月都有这么多新硬件诞生,如何让它们在 Linux 上工作是你的工作。因为 Linux 兼容性好,如果不是太低级的驱动,基本的 C 语言就可以了,系统架构影响不大。由于系统支持,您可能可以在 ARM 上使用 PC 硬件,但需要做一些更改。所以硬件驱动开发不像嵌入式,对硬件知识要求很高。可能的方向很多,比如家电,特别是像索尼、日立、希捷、富士康这样的工厂,比较稀缺。

四,学习 Linux 内核

学习 linux 内核不像学习语言。一个月或者三月就能掌握 C 或者 java。学习 linux 内核需要循序渐进,掌握正确的 linux 内核学习路线非常重要。本文将分享一些学习 linux 内核的建议。

  1. 了解操作系统的基本概念。如果没有,可以学习《操作系统: 设计与实现》,Andrew S.Tanenbaum 写的那本,以 MINIX 为例解释操作系统的概念。非常推荐。

  2. 有了操作系统的基本概念,你就可以理解 Linux 的机制了。推荐罗伯特 · 拉芙写的 Linux 内核设计与实现。这本书从概念上解释了 Linux 有什么以及它是如何工作的。这本书应该反复仔细阅读。

  3. 有了 Linux 内核的知识,我们还需要具体学习 Linux 内核源代码。经典的是丹尼尔 ·p· 博韦特写的《深入理解 Linux 内核》。学习这本书的时候,要看看内核代码。这本书学起来挺费劲的,所以有很多代码要研究。但是,如果这本书很好理解,那么恭喜你,你已经对 Linux 内核很熟悉了。

  4. 如果你想开发设备驱动,可以向 O 'Reilly Press 学习 Linux 设备驱动。这本书是驾驶入门的好材料。还有一本很好的教材,精通 Linux 驱动开发,可以参考一下。开车,难免要学习一些硬件协议和资料。如果你研究的是哪一种,可以找相应的硬件文档,了解硬件的工作原理。这些我就不细说了。

  5. 网络部分,学习一些 Linux 网络部分学习《深入了解 LINUX 网络技术内幕》。这本书把 Linux 的网络部分讲得非常清楚透彻。不过我们一般不做这方面的研究,也不需要做那么多研究。毕竟现在相关岗位很少。

  6. 现在 Linux 相关的工作大多集中在一些嵌入式开发领域,如 arm、mips 等。你要学习以下关于架构的信息,了解 CPU 的设计和工作模式。看看 ARM 对应的芯片手册就知道了,很详细的。mips 随便看看 MIPS 运行,有一两个版本。两个版本有些区别,建议全看。

  7. 补充一点经验。不要以为 Linux 庞大复杂,就很难学。认真学习,什么都可以学。就看你的毅力和恒心了。另外,不要走弯路,不要看市面上那些讲 Linux0.11 的书,学你想学的就好。就像学 C 语言看谭浩强一样,走弯路,费力气,严重影响学习效果。

关于 linux 内核学习路线,再多说几句应用编程,有时候经常会需要的:

  1. 学习 Linux 应用编程,建议看《unix 环境高级编程》,把里面的例子都做一遍,会对整个 Linux 编程有系统都认识。

  2. 针对 Linux,有本 《Linux 系统编程》,学完上一本,这本很快看一遍就懂了。主要是针对 Linux 具体懂一些内容,讲的挺全了,很实用。

  3. Linux 网络编程,系统的学习一下《unix 网络编程。卷 1,套接字联网 api》,基本上网络应用相关的程序就都没问题了。

这些内容,分几年时间,分步计划学习,就会成为 Linux 高手了。个人建议参加零声教育的培训,学习效率会高很多,有目的性的参加培训,缩短周期,快速成型才是时代所需。

官方地址:Linux 内核源码 / 内存调优 / 文件系统 / 进程管理 / 设备驱动 / 网络协议栈 - 学习视频教程 - 腾讯课堂

以上就是 Linux 内核学习路线,关于学习 Linux 内核的建议,希望对小伙伴们有帮助。

0%