本文原创是freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/9304991

从大二开始学习Linux内核,到现在已经4年了。在大学的时候,学习Linux内核仅仅是作为一种爱好,因为国内罕有人能在本科毕业之后直接从事Linux内核研发工作,而哦也从未打算读研。

学习内核是一件很有趣的事情。仅仅是出于兴趣。当很想知道命令是如何从键盘输入到计算机并且关联到进程的时候,我翻出了Linux内核的源代码。然而,面对的问题越来越多,好像一个潘多拉盒子,一旦打开了,就一发不可收拾。当很想知道什么是进程的时候,会去翻阅内核关于进程的结构体。然而,更复杂的问题是,内核的作者是怎么在一个裸机上相处要把“进程”这个概念意淫出来的呢?这一系列的问题对我的吸引好似毒瘾。

操作系统本质的任务是为了是计算机工作更有效率,各种资源压榨更彻底。所以,内核hacker本质上是最优秀的吸血鬼。

正因为操作系统需要压榨硬件的资源,所以需要对硬件比较熟悉——当然,并不是说每个内核工程师都是驱动工程师。有的可能只是对算法比较有研究,优化了某一个数据结构或者算法。然而,所有的优化都是为了使硬件干活儿更有效率,所以,对硬件的熟悉是最基础的——如果不熟悉硬件的特性,那么,即便做了很多的优化,也是为了优化而优化。

与操作系统关系最密切的硬件莫过于CPU。关于CPU,最核心的莫过于多任务管理、内存管理。前者是操作系统的两大核心之一,后者是前者的基础。

关于CPU的任务,有三个概念必须要搞清楚。任务的定义、上下文切换、内存的分段segment(注意与汇编里的代码段、数据段、堆栈段区分,这三个概念一般是在同一个物理内存的segment内的)。其中,任务基本上是意淫出来的(个人观点)。对于CPU而言,需要做的就是去查IP指向了内存的哪里,然后去执行,至于是否是一个任务,它本身不在意。而当intel人为地定义出一个任务概念之后,关于任务这个对象的属性就出来了,intel用一个专用tr寄存器用于存储指向当前任务的任务描述符地址。当tr指向哪一条任务描述符了,哪一个任务就被意淫为正在执行。当tr指向另外一个任务描述符的时候,另外一个任务就是正在执行了。Linux内核有专门的switch_to()这样一个宏定义(实际上是汇编指令)来做这个事儿。这个过程被称为上下文切换。当然,上下文切换有很多复杂的工作要做,最基本的就是要把当前的任务的执行情况保存起来。

如何保存呢?

当然要用到栈了。(栈并非是C语言专用的数据结构,而是一种通用的数学概念,一种通用的机制,只不过天朝的叫兽很喜欢把C和栈捏到一起意淫)。

早期的Linux内核为一个进程分配了一个page减去task_struct大小的内核栈,用于存储内核态的上下文信息。

说远了,回到上下文切换的概念。

大家都知道上下文切换是一个很耗费资源的工作。应该尽量避免。

有一个很傻很天真的问题摆在这里。

既然上下文切换是应该避免的问题,为什么内核还要提供上下文切换的功能呢?那不是在自己打嘴巴吗?

准确的说,这是一个关于人性本自私的话题的探讨——觉得穿越了吧?

说上下文切换不好,是站在应用(说话者所支持的应用)的立场来说话的。比如说,一个Linux企业系统出现了大量的上下文切换,DBA抱怨说,这个系统太fuck了,Oracle还怎么跑嘛?他是站在Oracle的角度来说话的。

而在操作系统的角度,它觉得自己已经协调好了各个任务的资源配置,尽最大的努力让各个任务都能均衡执行。至于各个任务性能还是不能让人满意,关键问题是应用太多了——老子就那么两个核,丢过来几万个任务,上下文切换能不多吗?我日。

至于在CPU的角度,内存里有多少代码,老子就跑多久,一个任务是跑,一万个任务也是跑。老子跑就是了,你应用设计的合不合理,应用跑得爽不爽,关老子鸟事。

好吧,再回到内存分段的概念。

现代操作系统用的其实是分页管理。至于分段管理,那是30年前过时的技术了——可笑的是,直到2013年,天朝很多高校的汇编课程讲解的重点就是80x86的分段管理(还是实模式那种)。

80x86系列的分页管理核心在于逻辑地址、虚拟地址、线性地址、物理地址之间的转换。页目录、页表实现的机制。

CPU的三个概念就占了很大的篇幅了。说了这么多,不是想在这里讲解很多知识。主要是想说明,Linux内核学习是一个很复杂的问题,是一个真正的兴趣驱动的过程。相对而言,如果你选择一个商业产品,无论你多么自信地说自己爱Oracle数据库,恨不能天天与它做爱,但是,参加一个月培训后,就能正常干活了——对你而言实在是太容易了。

你需要持续的动力,持续的热情。需要能在一个夜晚读内核源代码读到黑夜变白天。

有这种战斗的精神,无论是Linux内核,还是你喜欢的女孩子,还是事业,都是你的。

Linux内核学习趣谈的更多相关文章

  1. Linux 内核学习的经典书籍及途径

    from:http://www.zhihu.com/question/19606660 知乎 Linux 内核学习的经典书籍及途径?修改 修改 写补充说明 举报   添加评论 分享 • 邀请回答   ...

  2. 关于Linux内核学习的误区以及相关书籍介绍

    http://www.hzlitai.com.cn/article/ARM9-article/system/1605.html 写给Linux内核新手-关于Linux内核学习的误区 先说句正经的:其实 ...

  3. linux内核学习之二:编译内核

    在linux内核学习系列的第一课中讲述了搭建学习环境的过程(http://www.cnblogs.com/xiongyuanxiong/p/3523306.html),环境搭好后,马上就进入到下一环节 ...

  4. linux内核学习之一:环境搭建--安装Debian7.3

    本系列文章假设读者已对linux有一定的了解,其实学习linux内核不需要有很深的关于linux的知识,只需要了解以下内容:linux基础知识及基本shell命令:现代操作系统的基本概念:C语言和gc ...

  5. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  6. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  7. Linux 内核学习经验总结

    Linux 内核学习经验总结 学习内核,每个人都有自己的学习方法,仁者见仁智者见智.以下是我在学习过程中总结出来的东西,对自身来说,我认为比较有效率,拿出来跟大家交流一下. 内核学习,一偏之见:疏漏难 ...

  8. Linux内核分析——Linux内核学习总结

    马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核学习总结 一 ...

  9. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

随机推荐

  1. C# 实现 Hyper-V 虚拟机 管理

    原文:C# 实现 Hyper-V 虚拟机 管理 Hyper-V WMI Provider 工具类如下: "; break; } return status; } } /// <summ ...

  2. thrift js javascript C# Csharp webservice

    http://www.cnblogs.com/xxxteam/archive/2013/04/15/3023159.html 利用thrift实现js与C#通讯的例子 关键字:thrift js ja ...

  3. Java之IO流基础流对象

    输入流和输出流是相对于内存设备而言 即将外设中的数据读取到内存中就是输入    将内存中的数据写入到外设中就是输出   字符流的由来:     其实就是:字节流读取文字字节数据后,不直接操作而是先查指 ...

  4. ubuntu eclipse android搭建

    1.eclipse加入android adt: 终端:sudo gedit /etc/hosts 加入: #for android 173.194.72.93 dl.google.com 173.19 ...

  5. 还在等待漫长的iOS构建过程?来试试通过命令行的方式进行iOS应用快速构建和运行吧

    不必多言,Xcode慢得很是众所周知的了.更甚者是,我有时发觉自己太依赖于Cocoa Touch的自动完成功能了,这可是个天使和魔鬼的结合体! 故此我开始去寻觅一个替代的流程来通过命令行来实现我需要的 ...

  6. 【UVA】10285-Longest Run on a Snowboard(动态规划)

    这是一个简单的问题.你并不需要打印路径. 状态方程dp[i][j] = max(dp[i-1][j],dp[i][j-1],dp[i+1][j],dp[i][j+1]); 14003395 10285 ...

  7. jquery validate remote验证唯一性

    jquery.validate.js 的 remote 后台验证 之前已经有一篇关于jquery.validate.js验证的文章,还不太理解的可以先看看:jQuery Validate 表单验证(这 ...

  8. 开发者需要了解的WebKit

    2013-3-22 22:37| 发布者: sxwgf| 查看: 575| 评论: 0|来自: infoq 摘要: Paul Irish是著名的前端开发工程师,同时他也是Chrome开发者关系团队成员 ...

  9. [译]Java 设计模式之命令

    (文章翻译自Java Design Pattern: Command) 命令设计模式在进行执行和记录的时候需要一个操作及其参数和封装在一个对象里面.在下面的例子中,命令是一个操作,它的参数是一个Com ...

  10. javaproject积累——java 反射 invoke

    铅: 在java工程,我们已经听到很多ORM的概念,我一直耿耿于怀,如何从上rs转换成了对象呢?难道要写非常多的推断吗?答案肯定是否定.我们就要探索怎么解决问题,刚好在研究我们系统底层架构的时候,挖掘 ...