Linux内核学习指南:从心智模型到设计哲学的系统方法
发布时间:2026/10/10 11:20:26 锦皓数字建站

1. 从内核恐惧症说起为什么大多数人学Linux内核的方式从一开始就错了很多人第一次翻开Linux内核相关的资料时都会经历一个相似的崩溃过程打开源码目录看到kernel/、mm/、fs/、net/、drivers/这些文件夹每个里面动辄几万行代码函数调用层层嵌套宏定义满天飞。看了三天脑子里只剩下一个念头——这玩意儿到底从哪儿下手我见过太多人卡在这一步。有人选择硬啃源码从init/main.c的start_kernel()一行行往下读读到setup_arch()就迷路了有人买了一大堆讲内核的书每本都从进程管理讲到内存管理再讲到文件系统看完之后知识点是记住了但问他内核到底是怎么运转的还是答不上来。问题出在哪儿出在大多数人把内核当成了一本字典来学而不是把它当成一个系统来理解。字典是按字母顺序排列的你查一个词就懂一个词但词与词之间没有逻辑关系。内核不是这样。内核是一个活的系统它的每一个子系统都在和其他子系统交互每一个设计决策背后都有明确的权衡和取舍。如果你不理解这些交互和权衡你记住的每一个知识点都是孤立的永远拼不成一张完整的图。这就是我写这一篇的出发点。我想先帮你建立Linux内核的心智模型——也就是说在你脑子里先搭起一个框架知道内核大概长什么样、各个部分之间是什么关系、遇到一个问题时应该往哪个方向去想。有了这个框架你再去看源码、看书、看文档就会有一种哦原来这个知识点是放在这个位置的的感觉而不是一堆散落的碎片。这篇文章适合谁如果你已经用过Linux会写基本的Shell命令对C语言不陌生但一提到内核就觉得头大那这篇就是写给你的。如果你已经有一些内核基础但总觉得知识是散的、串不起来这篇也能帮你把框架重新梳理一遍。我不会一上来就贴大段源码也不会用一堆术语把你砸晕而是用类比、用场景、用为什么这么设计的思路把内核的设计哲学讲清楚。关键词里提到了心智模型和设计哲学这两个词听起来有点虚但它们是理解内核的关键。心智模型是你脑子里对内核的印象设计哲学是内核开发者做决策时的原则。把这两个东西搞明白了后面学具体的子系统就是顺水推舟的事。2. 内核到底在忙什么把操作系统想象成一家公司的后勤部门2.1 从资源管理者这个角色说起要理解内核先要理解它存在的理由。计算机硬件是一堆资源CPU、内存、硬盘、网卡、键盘、显示器、显卡……这些资源是有限的但想用它们的人也就是应用程序是很多的。如果每个程序都直接去抢CPU、抢内存那整个系统就乱套了。内核的角色就是这些资源的管理者和仲裁者。你可以把内核想象成一家大公司的后勤部门。公司里有几百个员工应用程序每个人都想用会议室CPU、想领办公用品内存、想用打印机外设。后勤部门要做的事情就是谁先用、谁后用、用多久、用多少都得有个规矩。没有后勤部门大家一窝蜂去抢结果就是谁也干不成活。这个类比能帮你理解内核的几个核心职责进程管理决定哪个程序什么时候用CPU、用多久。就像后勤部门安排会议室的使用时间表。内存管理决定哪个程序能用哪块内存、用多少。就像后勤部门分配办公桌和储物柜。文件系统决定数据怎么存、怎么取。就像公司的档案室有固定的分类和检索规则。设备驱动让内核能和各种硬件打交道。就像后勤部门和各个供应商之间的对接人。网络协议栈让本机和其他机器通信。就像公司的收发室和外部邮件系统。这五个职责不是孤立的。比如一个程序要读文件它会先经过文件系统文件系统发现数据不在内存里就会调用设备驱动去硬盘上读读的过程中进程可能要等待进程管理就要把它挂起等数据读回来了再唤醒它。你看一个简单的读文件操作就串起了四个子系统。2.2 用户态和内核态那道看不见的墙理解内核的另一个关键是理解用户态和内核态的区分。这两个概念听起来很抽象但其实很好理解。想象你住在一个小区里。你的家用户态是你自己的地盘你想怎么布置就怎么布置别人管不着。但小区里有公共设施电梯、水泵、配电房内核态。这些设施你不能随便进去操作因为一旦你操作错了整栋楼都受影响。你要用电梯只能按按钮系统调用由物业内核来帮你操作。用户态和内核态的区别就在这儿。应用程序运行在用户态能访问的内存和指令是受限的内核运行在内核态能访问所有硬件和内存。应用程序想用硬件资源必须通过系统调用这个按钮来请求内核帮忙。为什么要这么设计两个原因。第一是安全如果每个程序都能直接操作硬件一个程序写错了就可能把整个系统搞崩。第二是抽象不同的硬盘、不同的网卡操作方式千差万别如果让每个应用程序都去适配那程序员就不用干别的了。内核把这些差异屏蔽掉给应用程序提供统一的接口。这道墙的存在是理解内核很多设计决策的前提。比如为什么内核里不能用浮点运算因为切换浮点运算的上下文开销大而且内核态下没必要用。为什么内核代码要特别小心并发因为内核态下多个CPU可能同时访问同一份数据一旦出错就是整个系统崩溃。这些后面都会展开讲。2.3 宏内核与微内核Linux为什么选了大块头路线操作系统内核在设计上有两条主要路线宏内核和微内核。宏内核的思路是所有核心功能都放在内核态里进程管理、内存管理、文件系统、设备驱动、网络协议栈全部打包在一起。Linux就是典型的宏内核。微内核的思路是内核态里只放最核心的东西比如进程调度和基本的IPC进程间通信其他功能都放到用户态去。文件系统、设备驱动这些都以用户态进程的形式运行。代表性的有QNX、L4系列。这两条路线各有优劣。宏内核的优点是性能好因为所有功能都在一个地址空间里函数调用就是普通的函数调用不需要跨态切换。缺点是稳定性差一个驱动出问题就可能把整个内核搞崩。微内核的优点是稳定性好驱动崩了重启驱动就行内核不受影响。缺点是性能差因为功能模块之间通信要跨态切换开销大。Linux选了宏内核但在宏内核的基础上做了很多改进。比如内核模块机制让驱动可以动态加载和卸载不用重新编译整个内核。比如各种内核态的隔离机制尽量把故障限制在局部。这些设计决策背后都是性能优先但尽量兼顾稳定的思路。理解这个选择很重要因为它解释了为什么Linux内核的代码量这么大、子系统之间的耦合这么深。如果你用微内核的思维去理解Linux会觉得很多设计不合理但如果你知道Linux是宏内核就会明白这些设计是在特定约束下的最优解。3. 内核的骨架五个子系统是怎么串起来的3.1 进程管理一切活动的载体进程管理是内核最核心的子系统因为其他所有子系统的工作最终都是为某个进程服务的。没有进程就没有谁在用资源这个问题。Linux的进程管理有几个关键概念。首先是task_struct这是内核对进程的抽象你可以把它理解成进程的身份证里面记录了进程的PID、状态、优先级、内存映射、打开的文件、信号处理方式等等。内核里所有和进程相关的操作都是围绕这个结构体展开的。其次是调度器。调度器决定哪个进程什么时候上CPU、跑多久。Linux的调度器经历过多次演进从早期的O(n)调度器到O(1)调度器再到CFS完全公平调度器现在又有了EEVDF。每次演进都是为了解决前一代的问题。比如CFS的核心思想是虚拟运行时间让每个进程感觉自己独占了CPU但实际上是在按权重分配时间。第三是进程状态。进程不是一直在跑的它有多种状态运行态、就绪态、睡眠态、停止态、僵尸态。理解这些状态的转换是理解进程管理的关键。比如一个进程调用read()读硬盘它会从运行态进入睡眠态等数据读回来了再被唤醒进入就绪态然后等调度器选中它再回到运行态。进程管理和其他子系统的交互非常频繁。内存管理要为进程分配地址空间文件系统要维护进程打开的文件表网络协议栈要处理进程的socket设备驱动要处理进程的IO请求。可以说进程管理是内核的中枢。3.2 内存管理从物理内存到虚拟地址空间内存管理是内核里最复杂的子系统之一因为它要解决一个根本矛盾物理内存是有限的但进程对内存的需求是无限的。Linux的解决方案是虚拟内存。每个进程都以为自己拥有一整块连续的地址空间在64位系统上通常是128TB但实际上这块空间是虚拟的只有真正用到的部分才映射到物理内存。这个映射关系由页表维护CPU里的MMU内存管理单元负责在每次内存访问时做地址转换。虚拟内存带来的好处是多方面的。第一是隔离进程A不能直接访问进程B的内存因为它们的虚拟地址空间是独立的。第二是简化编程程序员不用关心物理内存的布局只管用虚拟地址就行。第三是内存超售物理内存不够时可以把不常用的页换到硬盘上腾出空间给活跃的页用。内存管理的核心概念包括页page通常是4KB、页表page table、页框page frame、伙伴系统buddy system用于分配物理页、slab分配器用于分配小对象、页回收page reclaim、交换swap等等。这些概念之间关系紧密理解一个有助于理解其他。内存管理和进程管理的交互体现在地址空间的创建和销毁上。fork()创建新进程时内核要复制父进程的地址空间用写时复制技术优化exec()加载新程序时内核要重建地址空间进程退出时内核要释放地址空间。这些操作都涉及内存管理和进程管理的协同。3.3 文件系统数据的持久化与抽象文件系统解决的是数据怎么存、怎么取的问题。Linux的文件系统设计有一个核心理念一切皆文件。不仅是普通文件和目录设备、管道、socket、甚至内核状态都可以通过文件接口来访问。这个理念的好处是统一。应用程序不用关心它操作的是硬盘上的文件还是网卡上的数据都用open()、read()、write()、close()这套接口就行。内核在底层根据文件类型分派到不同的处理逻辑。Linux的文件系统层是分层的。最上层是VFS虚拟文件系统它定义了统一的文件操作接口比如open、read、write、llseek、mmap等。中间层是各种具体的文件系统实现比如ext4、XFS、Btrfs、F2FS等。最下层是块设备层负责和硬盘、SSD等存储设备打交道。VFS的核心概念包括inode索引节点代表一个文件、dentry目录项代表路径中的一个组成部分、file打开的文件实例、superblock文件系统超级块。这四个结构体之间的关系是理解VFS的关键。文件系统和内存管理的交互体现在页缓存上。读文件时内核先把数据读到页缓存里下次再读同一块数据就直接从内存返回不用再访问硬盘。写文件时数据先写到页缓存由内核在合适的时机回写到硬盘。这个机制大幅提升了IO性能但也带来了数据一致性的问题所以有了fsync()这样的接口来强制回写。3.4 设备驱动内核和硬件之间的翻译官设备驱动是内核里代码量最大的部分因为硬件种类太多了。网卡、显卡、声卡、键盘、鼠标、硬盘、USB设备、PCI设备……每一种硬件都需要对应的驱动来操作。驱动的核心任务是把内核的统一接口翻译成硬件能理解的指令。比如块设备驱动要把读第N个扇区翻译成硬盘控制器能理解的命令网卡驱动要把发送这个数据包翻译成网卡能理解的描述符。Linux的设备模型有几个关键概念。总线bus是设备和CPU之间的通道比如PCI、USB、I2C。设备device是挂在总线上的具体硬件。驱动driver是操作设备的代码。类class是一组功能相似的设备的抽象比如所有的输入设备都属于input类。设备驱动和文件系统的交互体现在设备文件上。在/dev目录下每个设备都有一个对应的文件节点应用程序通过读写这个文件来操作设备。字符设备如键盘按字节流处理块设备如硬盘按块处理。设备驱动和内存管理的交互体现在DMA上。很多设备支持DMA直接内存访问可以在不占用CPU的情况下把数据直接搬到内存里。这需要驱动和内存管理协同工作确保DMA缓冲区的物理地址是连续的、可访问的。3.5 网络协议栈从网卡到socket的完整链路网络协议栈解决的是本机和其他机器怎么通信的问题。Linux的网络协议栈实现了从链路层到应用层的完整协议族包括以太网、IP、TCP、UDP、ICMP、ARP等等。网络协议栈的分层结构很清晰。最底层是网络设备层负责和网卡驱动打交道。往上是链路层处理以太网帧。再往上是网络层处理IP包和路由。再往上是传输层处理TCP和UDP。最上面是socket层给应用程序提供编程接口。数据包在网络协议栈里的流转过程是理解网络子系统的关键。发送时数据从socket层往下走每层加上自己的头部最后交给网卡驱动发出去。接收时数据从网卡驱动往上走每层剥掉自己的头部最后交给对应的socket。网络协议栈和进程管理的交互体现在socket上。每个socket都关联到一个进程当数据到达时内核要唤醒等待这个socket的进程。网络协议栈和内存管理的交互体现在sk_buff上这是内核对网络数据包的抽象它的分配和释放都走内存管理的接口。4. 设计哲学那些看起来奇怪的决策背后的逻辑4.1 机制与策略分离为什么内核只提供工具不替你做决定Linux内核设计里有一条很重要的原则机制与策略分离。意思是内核只提供能做什么的机制至于该怎么做的策略交给用户态去决定。举个例子。内核提供了调度器这个机制能决定哪个进程上CPU。但哪个进程应该优先这个策略内核不硬编码而是通过nice值、调度类、cgroup等接口让用户态来配置。再比如内存管理内核提供了页回收机制但哪些页该回收的策略可以通过/proc/sys/vm/下的参数来调整。为什么要这么设计因为策略是随场景变化的硬编码在核心里会导致内核变得僵化。服务器和手机的调度策略不一样数据库和桌面应用的IO策略不一样如果内核把策略写死就没法适应这些差异。把策略放到用户态内核保持通用用户态根据场景调整灵活性就高多了。这个原则对学习内核的启示是看到内核里某个奇怪的行为时先想想这是机制还是策略。如果是策略那它大概率是可以通过参数调整的不要以为内核只能这样。4.2 不要重复造轮子内核里的复用艺术内核代码量巨大但你会发现很多地方在复用同一套基础设施。比如链表操作内核有一套通用的list_head实现几乎所有子系统都用它。比如引用计数内核有kref和refcount_t统一处理对象的生命周期。比如RCU读-拷贝-更新内核用它来解决读多写少场景下的并发问题网络协议栈、文件系统、内存管理都在用。这种复用不是偷懒而是深思熟虑的设计。复用意味着代码经过更多测试、更少bug、更好维护。而且复用让不同子系统的代码风格一致读起来更顺畅。但复用也有代价。通用的基础设施往往为了适应所有场景而做了妥协在特定场景下可能不是最优的。比如list_head是双向链表插入删除是O(1)但查找是O(n)。如果某个场景需要频繁查找就得用别的数据结构比如红黑树或哈希表。内核里这些数据结构都有通用实现选哪个取决于具体需求。4.3 性能优先但可配置内核的取舍之道内核的很多设计决策背后都是性能考量。比如为什么内核用宏内核而不是微内核性能。为什么内核里大量使用内联函数和宏性能。为什么内核的锁粒度要仔细设计性能。但性能不是唯一目标。内核也要考虑可维护性、可移植性、安全性。这些目标之间经常冲突内核开发者的工作就是在冲突中找到平衡点。一个典型的例子是自旋锁和互斥锁的选择。自旋锁在等待时不睡眠一直占用CPU适合临界区很短的场景。互斥锁在等待时睡眠让出CPU适合临界区较长的场景。选哪个取决于临界区的长度和上下文中断上下文不能用会睡眠的锁。这个选择没有标准答案要看具体情况。另一个例子是内存分配器的选择。内核里有伙伴系统、slab、vmalloc、kmalloc等多种分配器每种适合不同的场景。伙伴系统适合分配大块连续物理内存slab适合分配大量小对象vmalloc适合分配大块虚拟连续但物理不连续的内存。选哪个取决于需求。理解这些取舍比记住内核用了什么更重要。因为技术会演进今天的最优解明天可能就不是了但取舍的逻辑是相对稳定的。4.4 稳定压倒一切为什么内核开发这么保守如果你关注内核社区的邮件列表会发现一个现象一个补丁从提交到合并可能要经过几十轮review耗时几个月甚至几年。很多人觉得这太慢了但内核开发者认为这是必要的。原因是内核的特殊性。内核是操作系统的核心它出问题不是程序崩溃这么简单而是整个系统崩溃。而且内核一旦发布就会被成千上万的设备使用一个bug可能影响几百万用户。所以内核开发必须极其谨慎。这种保守体现在很多方面。比如内核的ABI应用二进制接口是稳定的不能随便改因为改了会破坏现有程序。比如内核的系统调用一旦加入就不能删除只能新增。比如内核的配置选项要尽量保持兼容不能随便改名字。对学习内核的人来说理解这种保守很重要。你在看内核代码时可能会觉得某些地方过时或绕弯但那可能是因为要兼容旧的行为。不要轻易觉得这代码写得不好先想想它为什么这么写。5. 建立心智模型的实操路径从看懂到看透5.1 从一个系统调用入手把链路走通光看概念容易忘最好的学习方式是找一个具体的系统调用把从用户态到内核态再到硬件的完整链路走一遍。我推荐从read()开始因为它涉及的子系统多链路清晰。当应用程序调用read(fd, buf, count)时发生了什么第一步用户态触发软中断在x86上是syscall指令CPU切换到内核态根据系统调用号找到对应的处理函数sys_read()。第二步sys_read()根据fd找到对应的struct file然后调用file-f_op-read()。这里就是VFS的入口f_op是文件操作函数表具体指向哪个函数取决于文件类型。第三步如果是普通文件会走到具体文件系统的读函数比如ext4的ext4_file_read_iter()。这个函数会检查要读的数据是否在页缓存里。第四步如果数据在页缓存里直接拷贝到用户缓冲区返回。如果不在就要发起IO请求调用块设备层的接口把请求发给硬盘驱动。第五步硬盘驱动把请求翻译成硬件指令发给硬盘。硬盘读完数据后发中断驱动处理中断把数据放到页缓存唤醒等待的进程。第六步进程被唤醒后把数据从页缓存拷贝到用户缓冲区read()返回。走完这一遍你就把系统调用、VFS、文件系统、页缓存、块设备层、驱动、中断处理、进程调度都串起来了。这比孤立地看每个子系统要有效得多。5.2 用分层和分派两个视角看内核内核代码虽然复杂但有两个视角能帮你快速理清结构分层和分派。分层是指内核的代码是分层的上层依赖下层下层不依赖上层。比如VFS依赖具体文件系统具体文件系统依赖块设备层块设备层依赖驱动。看代码时先确定你在哪一层然后往上看它给谁提供服务往下看它依赖谁。分派是指内核里大量使用函数指针来实现多态。比如struct file_operations里全是函数指针不同的文件系统填不同的实现。看代码时看到函数指针调用就要去找它实际指向哪个函数。这通常需要结合具体的结构体实例来分析。这两个视角结合起来你就能在复杂的代码里找到方向。比如看到一个函数指针调用先确定它在哪一层然后找这个指针是在哪里被赋值的就能找到实际的实现。5.3 动手实验用ftrace和perf观察内核行为光看代码不够还要动手观察。Linux提供了一些工具能让你看到内核实际在做什么。ftrace是内核自带的跟踪工具可以跟踪函数调用、中断、调度等事件。比如你想看read()系统调用到底调用了哪些内核函数可以这样操作# 挂载tracefs mount -t tracefs nodev /sys/kernel/tracing # 设置要跟踪的函数 echo sys_read /sys/kernel/tracing/set_ftrace_filter echo function /sys/kernel/tracing/current_tracer # 开启跟踪 echo 1 /sys/kernel/tracing/tracing_on # 执行你的程序 cat /etc/hostname # 关闭跟踪并查看结果 echo 0 /sys/kernel/tracing/tracing_on cat /sys/kernel/tracing/trace你会看到sys_read调用的完整函数链这比看代码直观多了。perf是性能分析工具可以看CPU在哪些函数上花了时间。比如# 采样10秒 perf record -a -g sleep 10 # 查看报告 perf report这会告诉你内核的热点在哪里哪些函数被调用得最频繁。这些工具的价值在于它们能把你从猜变成看。看代码时你不确定某个路径是否真的会走到用ftrace一跟踪就知道了。5.4 读源码的正确姿势从入口到出口不要迷路读内核源码最容易犯的错误是逐行读。看到一个函数就一行行往下看遇到函数调用就跳进去结果越跳越深最后忘了自己从哪儿来的。正确的姿势是抓大放小。先确定你要理解的入口和出口然后只看主路径遇到不重要的分支先跳过。比如读sys_read()主路径是找到file - 调用f_op-read - 返回至于错误处理、权限检查这些分支第一遍可以先不看。另外善用工具。cscope、ctags、LXRLinux Cross Reference这些工具能帮你快速跳转和查找。特别是LXR它能在网页上显示代码点击函数名就能跳到定义非常方便。还有一点不要试图一次理解所有细节。内核代码是几十年积累的结果很多细节是历史遗留或特定场景的优化。第一遍读不懂很正常先建立整体印象细节可以后面慢慢补。6. 几个容易踩的认知坑我当年也绕过的弯路6.1 内核是一个程序——错内核是一套协作机制刚开始学内核时我总把它想象成一个很大的程序有一个主函数从头到尾执行。后来才发现这个理解是错的。内核不是一个程序而是一套机制。它没有固定的执行流程而是被动地响应各种事件系统调用、中断、异常、定时器。每个事件触发一段内核代码处理完就返回。内核的主函数start_kernel()只在启动时执行一次之后就再也不会被调用了。理解这一点很重要因为它改变了你看内核代码的方式。不要找内核的主流程而是找某个事件的处理流程。比如系统调用read的处理流程、网卡中断的处理流程、定时器到期的处理流程。每个流程都是独立的串起来才是完整的内核。6.2 内核代码是顺序执行的——错并发无处不在另一个我踩过的坑是以为内核代码是顺序执行的。实际上内核里的并发非常复杂。首先多个CPU可能同时执行内核代码。一个CPU在处理系统调用另一个CPU在处理中断它们可能访问同一份数据。其次中断可能随时打断当前的执行流。你正在修改一个数据结构中断来了中断处理程序也修改这个数据结构就出问题了。第三内核里还有各种延迟执行机制比如软中断、tasklet、工作队列它们的执行时机是不确定的。所以内核里到处是锁、原子操作、内存屏障。看代码时看到spin_lock()、rcu_read_lock()、atomic_inc()这些就要意识到这里涉及并发保护。不理解并发就看不懂内核代码为什么这么写。6.3 内核版本越新越好——错稳定版才是学习首选很多人学内核时喜欢追最新的版本觉得新版本代码更先进。但实际上学习时应该选稳定版比如5.15、6.1这种LTS版本而不是最新的开发版。原因是稳定版的代码经过充分测试bug少文档全社区讨论多。开发版虽然新但代码变动频繁你今天看的东西明天可能就改了而且开发版里可能有一些实验性的代码不适合学习。另外不同版本的内核差异可能很大。比如调度器在5.15和6.6之间就有不少变化。如果你看的资料和你的内核版本对不上会很困惑。所以选定一个版本就专注看这个版本的代码和资料。6.4 看懂代码就等于懂了内核——错动手才是关键最后一个坑是以为看懂代码就等于懂了内核。实际上看懂和会用之间还有很大的距离。我建议你在学内核时一定要动手做实验。比如写一个最简单的内核模块加载和卸载它看dmesg的输出。用ftrace跟踪一个系统调用的完整链路看它调用了哪些函数。用perf分析一个程序的性能看时间花在哪里。修改一个内核参数观察系统行为的变化。读/proc和/sys下的文件理解内核暴露给用户态的信息。这些实验能帮你把纸上的知识变成手上的经验。而且实验过程中你会遇到各种问题解决问题的过程就是学习的过程。7. 从心智模型到实战接下来该往哪个方向深入建立了心智模型之后下一步就是选一个方向深入。内核的子系统很多不可能每个都精通选一个你感兴趣或工作相关的方向扎进去。如果你做服务器开发可以深入网络协议栈理解TCP的拥塞控制、epoll的实现、网络包的收发路径。如果你做存储相关可以深入文件系统和块设备层理解IO调度、页缓存、直接IO。如果你做嵌入式可以深入设备驱动和电源管理。如果你做性能优化可以深入调度器和内存管理。不管选哪个方向方法都是一样的先建立这个子系统的心智模型理解它的核心数据结构和主要流程然后找一个具体的场景把链路走通最后动手实验验证。还有一点内核是一个社区项目参与社区是提升自己的好方式。订阅内核邮件列表看别人怎么讨论问题、怎么review补丁你会学到很多代码之外的东西。如果有可能尝试提交一个小补丁哪怕只是修个拼写错误也能让你体验内核开发的完整流程。我个人在实际操作中的体会是学内核最忌讳贪多求快。内核太大了想一次学完是不可能的。正确的做法是小步快跑每次只学一个点学透了再学下一个。比如这周就搞明白read()的完整链路下周就搞明白fork()的完整链路。积累下来你会发现原本零散的知识点慢慢连成了网。最后再分享一个小技巧准备一个内核笔记记录你每次学到的知识点、遇到的问题、解决的方法。内核知识很杂不记下来很容易忘。而且写笔记的过程本身就是梳理思路的过程写着写着可能就发现之前没想明白的地方。这个习惯我坚持了好几年受益良多。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。