雕刻在LINUX内核中的LINUS故事
快,关注“Linux宝库”,一起涨姿势~
因为Linux操作系统的流行,Linus 已经成为地球人都知道的名人。虽然大家可能都听过钱钟书先生的名言:“假如你吃个鸡蛋觉得味道不错,又何必认识那个下蛋的母鸡呢?” 但是如果真是遇到一个“特别显赫”的鸡蛋,很多人还是想看看能生出这颗神蛋的母鸡的,或者想听听这只母鸡的故事。
其实,在Linux内核的代码里,就隐藏着关于Linus大神的一个美妙故事。
启动Linux系统,Ctrl + Alt + T打开一个终端窗口,执行如下命令,唤出GDB,并打开描述内核空间的kcore虚拟文件。
$ sudo gdb --core /proc/kcore
然后在GDB中执行如下命令加载内核的符号信息:
(gdb) file /home/ge/work/linux-3.12.2/vmlinux
再切换为INTEL风格的反汇编:
(gdb) set disassembly-flavor intel
接下来反汇编用于系统重启的SYSC_reboot内核函数:
(gdb) disassemble SYSC_reboot
结果类似下图所示:
对于看到汇编就晕的看官勿要急(^_^),其实x86汇编是非常简单易懂的,特别是这个函数很好理解,里面充满着故事。另外,这可是地地道道Linus大神所写的代码啊。
在这个函数里有一串比较指令,有理且有趣。不妨先看这一句:
cmp DWORD PTR [ebp-0x114],0xfee1dead
这个常量很酷吧?Feel Dead。Linus大神是著名的语言大师,常常语出惊人,用非常简短的语言说出人间真善美,说出他人所不敢说。因为这个函数是用来重启的,如果不feel dead,干嘛要重启呢?
再往下看,会看到这样一条比较指令:
cmp edi,0x28121969
这个常量是不也很特别,0x28121969,是不很像是日期,对的,这就是Linus大神的出生年月日,1969年12月28日。明年,Linus大神50岁了,时光如流水啊,当年的毛头小伙,就要50岁了。三十而立,四十不惑,五十而知天命。Linus大神显然提前完成了“知天命”的目标。他就是上天派下来革Windows的命的。(^_^)
再往下看,还有一个日期:
cmp edi,0x5121996
1996年12月5日,这个日期是什么呢?是Linus大女儿的生日。
把时光倒退回1993年,那时Linus还是24岁的棒小伙,应该是大学毕业不久吧,当时知道Linux的还不多。有一天,Linus亲自授课,宣传Linux的用法。课程结束时,Linus留了一个课后测验,要求参加者做好了以邮件形式交卷。结果,有一位上课的美女在交测验结果的同时向Linus发出了一个约会的邀请,于是一场培训成就了一段美妙的姻缘,这个女生(Tove)成了Linus的太太。值得一提的是,Linus太太武功高强,曾经6次夺得芬兰国家级别的跆拳道比赛冠军。
1997年6月,第二届亚特兰大Linux展示会(Atalanta Linux Showcase,简称ALS)在美国举行,这是Linux发展早期的一个年度盛会。在周五晚上的感谢晚宴上,Linus全家出席,在会议的相册中,可以看到幸福的一家人。
(照片来自http://linuxshowcase.org)
照片中,Tove深情地看着Linus。Linus抱着的就是他们的大女儿,名叫Patricia Torvalds。Linus把她称作Linus v2.0。在位于母校网站的一个人主页上( https://www.cs.helsinki.fi/u/torvalds/),Linus放了几张Patricia婴儿时的照片,至今仍在,好久没有更新了。从网页上的信箱(torvalds@transmeta.com)来看,当时Linus还没有全职做Linux,还在Transmeta公司工作。
2015年8月,opensource.com特别采访了已经在读大学的Patricia。
https://opensource.com/life/15/8/patricia-torvalds-interview
报道提到,Patricia热爱计算机科学,已经在多个IT公司实习,技术方面小有成就,大有子承父业的雄心壮志。
(照片来自opensource.com)
照片中站在中间便是Patricia,她旁边的另两个年轻女生是她的两个妹妹,她们的生日也可以在上面的汇编代码里找到:
cmp edi,0x16041998
cmp edi,0x20112000
一位是98年生人,一位是00后。
那么这些神秘的常量是如何用的呢?这要看一下reboot API的函数原型。
int reboot(int magic, int magic2, int cmd, void *arg);
在这个API的文档中(man reboot(2)),可以看到关于上述常量的说明:
This system call will fail (with EINVAL) unless magic equals LINUX_REBOOT_MAGIC1 (that is, 0xfee1dead) and magic2 equals LINUX_REBOOT_MAGIC2 (that is, 672274793). However, since 2.1.17 also LINUX_REBOOT_MAGIC2A (that is, 85072278) and since 2.1.97 also
LINUX_REBOOT_MAGIC2B (that is, 369367448) and since 2.5.71 also LINUX_REBOOT_MAGIC2C (that is, 537993216) are permitted as value for magic2. (The hexadecimal values of these constants are meaningful.)
括号里的一句说这些常量的十六进制是富有含义的,诚然。
换句话来说,要想成功调用reboot API,那么前两个参数必须严格按如下规则填写:
第一个参数必须是0xfee1dead。
在Linus大神的大女儿Patricia出生之前,第二个参数能且只能是0x28121969,也就是大神的生日。
当Linus有了大女儿Patricia后,第二个参数也可以是Patricia的生日0x5121996。这样说有点不精确,精确的说法是从Linux内核2.1.17版本开始,第二个参数也可以是0x5121996。查阅kernel.org上的内核发布历史,2.1.17应该发布于1996年12月22日。可以想见,Linus大神在喜得爱女的几天内就修改了内核代码,然后在女儿满月之前把把这个代码发布给世界了。
当Linus有二女儿后,第二个参数也可以是二女儿的生日。
当Linus有了小女儿后,第二个参数也可以是小女儿的生日。
在内核代码中,上述规则是在reboot.c中强制的,代码如下:
/* For safety, we require "magic" arguments. */
if (magic1 != LINUX_REBOOT_MAGIC1 ||
(magic2 != LINUX_REBOOT_MAGIC2 &&
magic2 != LINUX_REBOOT_MAGIC2A &&
magic2 != LINUX_REBOOT_MAGIC2B &&
magic2 != LINUX_REBOOT_MAGIC2C))
return -EINVAL;
这个for safety,有点含糊啊!哈哈。
因为应用程序调用这个系统服务的时候必须使用这一系列常量,因为它们的定义写在uapi目录下的reboot.h,即:
/*
* Magic values required to use _reboot() system call.
*/
#define LINUX_REBOOT_MAGIC1 0xfee1dead
#define LINUX_REBOOT_MAGIC2 672274793
#define LINUX_REBOOT_MAGIC2A 85072278
#define LINUX_REBOOT_MAGIC2B 369367448
#define LINUX_REBOOT_MAGIC2C 537993216
注意啊,在这个文件和文档中,代表生日的四个常量都是以十进制表达的,应该是为了隐藏一下秘密吧。
0:000> .formats 0n85072278
Evaluate expression:
Hex: 00000000`05121996
如此看来,Linus大神不仅把这些常量写在Linux内核代码中,而且使它们成为Linux API的一部分。这意味着,这将成为永远。只要Linux系统还在,那么这些常量就将永远使用,因为API意味着用户态和内核态的法定接口。为了保障应用程序的兼容性,不可轻易变化。
无论哪种文化,家庭都有着极其重要的地位。修身齐家治国平天下,欲治其国者,先齐其家。从上面的故事来看,Linus大神是个很爱家的男人。他把自己心爱的家庭成员生日铭记(雕刻)在了他的伟大作品之中。
那么,Linus大神为什么选择reboot系统调用呢?reboot代表着新的开始,代表不拘泥于现状,从新出发,从头再来。这是很多人都喜欢的人生哲学。在古老的易经中,第63卦是既济,字面意思是渡河成功,代表成就了一个目标。但这并不是终结,最后一卦(第64卦)是未济,代表还有新的目标没有达到,需要继续努力。
某种程度上来说,人生应该在实现一个个“既济”的成果之后,不断地向着“未济”的目标进军。这也意味着人生要不断学习,用《荀子》一书开篇的话来说就是“学不可以已(停止)”。
这篇短文是带着对Linus大神的敬意来写的,希望大家受到鼓舞,学习Linus爱家爱代码的敬业精神,不要误以为老雷在亵渎圣贤啊。
如果你希望品读Linus大神的更多精妙代码,那么你或许对Linux研习班感兴趣。
关于格友:
格友微信公众号,正心诚意,格物致知,以人文情怀审视软件,以软件技术改变人生。
关于“Linux宝库”微信公众号:
欢迎关注"Linux宝库"微信公众号,这里每天发布最新的开源人物和开源事件。谨以此号记录Linux和开源业界的点点滴滴,为开源爱好者和从业者点亮人生。
-END-
-责任编辑 丸子-
雕刻在LINUX内核中的LINUS故事相关推荐
- 调皮的程序员:Linux之父雕刻在Linux内核中的故事
本文内容由公众号"格友"原创分享. 1.引言 (不羁的大神,连竖中指都这么帅) 因为LINUX操作系统的流行,Linus 已经成为地球人都知道的名人.虽然大家可能都听过钱钟书先生的 ...
- Linux内核中max()宏的奥妙何在?(二)——大神Linus对这个宏怎么看?
最新max()宏 上回,我们在<Linux内核中max()宏的奥妙何在?(一)>一文中说到,在3.18.34版Linux内核源码中的max()宏,采用了GCC的扩展特性,可以避免一些错误. ...
- Linux 之父 LinusTorvalds 喊话:Rust 即将出现在 Linux 内核中
上个月,Linus Torvalds 本人在 Linux 基金会开源峰会上发言称,Rust 有可能很快就会出现在 Linux 的内核中,最快是下一个内核周期. Linus Torvalds 和 Dir ...
- Linux内核中max()宏的奥妙何在?(一)
Linux内核中max()宏的奥妙何在?(一) 1.max()宏那点事 在Linux内核中,有这样四个比较大小的函数,如下: max(x,y) //两个数求最大值 min(x,y) //两个数求最小值 ...
- Linux 内核中的宏定义
Linux 内核中的宏定义 rtoax 日期 内核版本:linux-5.10.13 注释版代码:https://github.com/Rtoax/linux-5.10.13 __attribute__ ...
- 为了研究,可以在 Linux 内核中植入漏洞吗?
聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士 Linux 内核的开发和维护团队负责人之一 Greg Kroah-Hartman 颁发禁令,禁止美国明尼苏达大学向 Linux 内核贡献任 ...
- Linux内核中锁机制之完成量、互斥量
在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内容,首先需明确完成量表示为一个执行单元需要等 ...
- 简单谈一点linux内核中套接字的bind机制--数据结构以及端口确定
众所周知,创建一个套接字可以bind到一个特定的ip地址和端口,实际上套接字这一概念代表了TCP/IP协议栈的应用层标识,协议栈中的应用层就是通过一个ip地址和一个端口号标识的,当然这仅仅是对于TCP ...
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- 如何放出Linux内核中的链表大招
前言 上回,我们说到Linux内核中max()宏的终极奥义,Linux内核链表也不甘示弱,那么接下来,让我们看看Linux内核中的链表大招. 如何放出Linux内核中的链表大招 前言 一.链表简介 ( ...
最新文章
- apache php 调优_记一次apache+php调优
- python安装numpy-如何为python安装numpy和scipy?
- 【Flask】SelectedField 同步数据库
- TIOBE Programming Community Index
- zabbix如何选择适合的监控类型(107)
- 梯度与散度与拉普拉斯算子
- 类别动态绑定到TreeView控件
- log4j 和slf4j的比较
- 学校计算机的使用作文,电脑课上作文(3篇)
- 【BZOJ4260】Codechef REBXOR(前i个数的最大区间异或值---01字典树+dp)
- c语言在线翻译器,【C语言】【window】--在线翻译器.doc
- java开发实例大全_java编程实例大全100例
- 【AD10】Altium Designer 10导入元件库图文教程
- python文件操作
- matlab画中国地图深浅,科学网—MATLAB绘制中国地图 - 栾威的博文
- Spring学习(五):动态代理的两种实现方式(全网最容易懂)
- Mac 下读写NTFS文件
- 数据分析-划分客户等级
- 华盛顿道格拉斯县计划建立区块链创新园区
- 名帖196 米芾 行书《诉衷情》
热门文章
- 基于OHCI的USB主机 —— UFI读扇区代码
- linux命令补遗 - 1
- 关于DHCP的中继问题
- SQL Server里面如何导出包含数据的SQL脚本
- 3. file、inode结构体及chardevs数组等相关知识解析
- 2014年java软件project师面试题收集
- c语言--直接插入算法
- Atitit 通信技术概要 艾提拉著 目录 1. 通信系统原理(孔英会编著的图书)_百度百科.html	2 1.1. 第1章绪论1	2 1.2. 第2章信号分析基础25	2 1.3. 第3章信道5
- Atitit 算法的理解 目录 1. 算法(Algorithm),是程序的灵魂	1 2. 2. 算法的图形化表示	2 3. 3. 算法在实际软件开发项目中的应用	3 4. 算法的特点:	4 4.1.
- Atitti 存储引擎支持的国内点与特性attilax总结