0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内核的代码隐藏的美妙故事

Linux阅码场 来源:未知 作者:工程师曾玲 2018-09-23 14:49 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

因为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.

*/

#defineLINUX_REBOOT_MAGIC10xfee1dead

#defineLINUX_REBOOT_MAGIC2672274793

#defineLINUX_REBOOT_MAGIC2A85072278

#defineLINUX_REBOOT_MAGIC2B369367448

#defineLINUX_REBOOT_MAGIC2C537993216

注意啊,在这个文件和文档中,代表生日的四个常量都是以十进制表达的,应该是为了隐藏一下秘密吧。

0:000> .formats 0n85072278

Evaluate expression:

Hex: 00000000`05121996

如此看来,Linus大神不仅把这些常量写在Linux内核代码中,而且使它们成为Linux API的一部分。这意味着,这将成为永远。只要Linux系统还在,那么这些常量就将永远使用,因为API意味着用户态和内核态的法定接口。为了保障应用程序的兼容性,不可轻易变化。

无论哪种文化,家庭都有着极其重要的地位。修身齐家治国平天下,欲治其国者,先齐其家。从上面的故事来看,Linus大神是个很爱家的男人。他把自己心爱的家庭成员生日铭记(雕刻)在了他的伟大作品之中。

那么,Linus大神为什么选择reboot系统调用呢?reboot代表着新的开始,代表不拘泥于现状,从新出发,从头再来。这是很多人都喜欢的人生哲学。在古老的易经中,第63卦是既济,字面意思是渡河成功,代表成就了一个目标。但这并不是终结,最后一卦(第64卦)是未济,代表还有新的目标没有达到,需要继续努力。

某种程度上来说,人生应该在实现一个个“既济”的成果之后,不断地向着“未济”的目标进军。这也意味着人生要不断学习,用《荀子》一书开篇的话来说就是“学不可以已(停止)”。

这篇短文是带着对Linus大神的敬意来写的,希望大家受到鼓舞,学习Linus爱家爱代码的敬业精神,不要误以为老雷在亵渎圣贤啊。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    4

    文章

    1474

    浏览量

    43089
  • Linux
    +关注

    关注

    88

    文章

    11810

    浏览量

    219513
  • 代码
    +关注

    关注

    30

    文章

    4976

    浏览量

    74358

原文标题:雕刻在LINUX内核中的LINUS故事

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何理解Linux内核中的PCIe驱动

    我们习惯了用 Verilog 去死磕 PCIe 的底层协议状态机。但一旦越过硬件边界来到操作系统层面,Linux 内核是如何接管并驱动这些 PCI/PCIe 设备的呢?由于不同的 CPU 架构实现了
    的头像 发表于 04-11 17:22 1241次阅读

    Linux内核驱动开发的技术核心精要

    社区维护流程。 总之,Linux驱动开发要求开发者融会贯通并发、中断、内存、设备模型、调试等维度,不断实践并跟进内核演进,方能写出健壮高效的底层代码
    发表于 03-10 13:56

    Linux内核编码风格权威总结:从缩进到底层设计,让你的代码更“内核味”

    作为全球最庞大的开源项目之一,Linux 内核代码量早已突破千万行。要让来自世界各地的开发者高效协作,一套统一、严谨的编码风格必不可少 —— 这不仅是 “代码颜值” 的要求,更是可读
    的头像 发表于 02-09 16:29 273次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>编码风格权威总结:从缩进到底层设计,让你的<b class='flag-5'>代码</b>更“<b class='flag-5'>内核</b>味”

    Linux内核bug狩猎指南:从栈跟踪到修复,官方文档教你搞定系统核心故障

    内核Linux 系统的 “心脏”—— 一旦它出 bug,小则功能异常,大则系统崩溃、死机。但内核 bug 往往藏在百万行代码中,想快速定位、修复绝非易事。
    的头像 发表于 02-06 16:59 3283次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>bug狩猎指南:从栈跟踪到修复,官方文档教你搞定系统核心故障

    Linux内核的“心跳”:jiffies如何为系统计时?

    Linux 内核的世界里,有一个默默工作的 "计时器"——jiffies。它不像我们手机上的时钟那样显示年月日,却掌控着内核中绝大多数时间相关的操作:从进程调度到设备驱动的定时检查,都离不开它的身影。
    的头像 发表于 02-04 16:27 923次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>的“心跳”:jiffies如何为系统计时?

    深入RK3588内核:rockchip_linux_defconfig的作用与调试价值

    在 RK3588 芯片的 Linux 开发中,有一个文件始终是开发者绕不开的核心 ——kernel/arch/arm64/configs/rockchip_linux_defconfig。无论是首次
    的头像 发表于 02-03 15:56 1361次阅读
    深入RK3588<b class='flag-5'>内核</b>:rockchip_<b class='flag-5'>linux</b>_defconfig的作用与调试价值

    Linux系统内核参数调优实战指南

    Linux 内核参数调优是系统性能优化的核心环节。随着云原生架构的普及和硬件性能的飞速提升,默认的内核参数配置往往无法充分发挥系统潜力。在高并发 Web 服务、大数据处理、容器化部署等场景下,合理的
    的头像 发表于 01-28 14:27 679次阅读

    【「Linux 设备驱动开发(第 2 版)」阅读体验】Linux内核开发基础

    感谢电子发烧友论坛提供的《Linux设备驱动开发(第2版)》阅读机会,测评将从Linux内核开发基础、Linux内核平台抽象和设备驱动程序、
    发表于 01-12 22:45

    【「Linux 设备驱动开发(第 2 版)」阅读体验】+读内核处理的核心辅助函数

    上周收到《Linux 设备驱动开发(第 2 版)》书籍,这是一本介绍Linux内核开发的指导性书籍。全面了解Linux内核所提供的一些接口函
    发表于 01-10 22:08

    深入Linux内核:进程调度的核心逻辑与实现细节

    ,背后都离不开内核调度算法的精准操控。今天,我们就从优先级、调度算法、时间片分配到底层实现,全方位拆解Linux内核进程调度的核心逻辑。 一、进程调度的“身份标识”:优先级与分类 要理解调度逻辑,首先得搞懂:进程凭什么“插队”?
    的头像 发表于 12-24 07:05 4560次阅读
    深入<b class='flag-5'>Linux</b><b class='flag-5'>内核</b>:进程调度的核心逻辑与实现细节

    代码里的青春——我与RT-Thread的故事

    故事,与各位小伙伴分享。如果你也有故事,那么请一起参与进来——你的代码岁月,值得被记录!悟空的故事RT-Thread相伴,共赴五年时光之约邂逅期初入行时,对未知充满
    的头像 发表于 12-12 20:11 1229次阅读
    <b class='flag-5'>代码</b>里的青春——我与RT-Thread的<b class='flag-5'>故事</b>

    Linux内核printk日志级别全解析:从参数解读到实操配置

    一、开篇:一个命令引出的核心问题 在 Linux 终端执行 cat /proc/sys/kernel/printk,你可能会看到这样的输出: 这串数字不是随机的,而是内核日志系统的“核心配置开关
    的头像 发表于 11-20 15:54 1942次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>printk日志级别全解析:从参数解读到实操配置

    deepin亮相2025中国Linux内核开发者大会

    11 月 1 日,第二十届中国 Linux 内核开发者大会(CLK)在深圳举办。CLK 作为国内 Linux 内核领域极具影响力的峰会,由清华大学、Intel、华为、阿里云、富士通南大
    的头像 发表于 11-05 17:59 922次阅读

    Linux内核参数调优方案

    在高并发微服务环境中,网络性能往往成为K8s集群的瓶颈。本文将深入探讨如何通过精细化的Linux内核参数调优,让你的K8s节点网络性能提升30%以上。
    的头像 发表于 08-06 17:50 1147次阅读

    如何配置和验证Linux内核参数

    Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要。合理的参数调整可以显著提升网络性能、系统稳定性及资源利用率。然而,仅仅修改参数是不够的,如何验证这些参数是否生效同样关键。
    的头像 发表于 05-29 17:40 1349次阅读