調皮的程序員:Linux之父雕刻在Linux內核中的故事

本文內容由公衆號「格友」原創分享。php

一、引言

(不羈的大神,連豎中指都這麼帥)html

由於LINUX操做系統的流行,Linus 已經成爲地球人都知道的名人。雖然你們可能都聽過錢鍾書先生的名言:「假如你吃個雞蛋以爲味道不錯,又何須認識那個下蛋的母雞呢?」 可是若是真是遇到一個「特別顯赫」的雞蛋,不少人仍是想看看能生出這顆神蛋的母雞的,或者想聽聽這隻母雞的故事。linux

其實,在Linux內核的代碼裏,就隱藏着關於Linus大神的一些美妙故事。程序員

(本文同步發佈於:http://www.52im.net/thread-1859-1-1.htmlexpress

二、代碼中隱藏着「feel dead」這句話

啓動Linux系統,Ctrl + Alt + T打開一個終端窗口,執行以下命令,喚出GDB,並打開描述內核空間的kcore虛擬文件:api

$ sudo gdb --core /proc/kcoresass

而後在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,幹嗎要重啓呢?

三、Linus大神的生日也藏在了代碼中

再往下看,會看到這樣一條比較指令:

cmp    edi,0x28121969

這個常量是不也很特別,0x28121969,是不很像是日期,對的,這就是Linus大神的出生年月日:1969年12月28日。

明年,Linus大神50歲了,時光如流水啊,當年的毛頭小夥,就要50歲了。三十而立,四十不惑,五十而知天命。Linus大神顯然提早完成了「知天命」的目標。他就是上天派下來革Windows的命的。(^_^)

四、Linus大神把一家人都藏在代碼裏了

再往下看,還有一個日期:

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公司工做。

(照片來自https://www.cs.helsinki.fi/u/torvalds/)

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,那麼前兩個參數必須嚴格按以下規則填寫:

1)第一個參數必須是0xfee1dead;

2)在Linus大神的大女兒Patricia出生以前,第二個參數能且只能是0x28121969,也就是大神的生日;

3)當Linus有了大女兒Patricia後,第二個參數也能夠是Patricia的生日0x5121996。這樣說有點不精確,精確的說法是從Linux內核2.1.17版本開始,第二個參數也能夠是0x5121996。查閱kernel.org上的內核;4)發佈歷史,2.1.17應該發佈於1996年12月22日。能夠想見,Linus大神在喜得愛女的幾天內就修改了內核代碼,而後在女兒滿月以前把把這個代碼發佈給世界了;

5)當Linus有二女兒後,第二個參數也能夠是二女兒的生日;

6)當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愛家愛代碼的敬業精神,不要誤覺得老雷在褻瀆聖賢啊。

附錄1:更多感悟文章和故事

一個微信實習生自述:我眼中的微信開發團隊

微信程序員創業總結:如何提升Android開發效率

如何作一個合格的 iOS Team Leader

程序員中年危機:拿什麼拯救你,個人三十五歲

一個魔都程序員的3年:從程序員到CTO的歷練

爲何說即時通信社交APP創業就是一個坑?

致咱們再也回不去的 Github ...

一名90後二流大學程序員的自述:我是如何從「菜鳥」到「辣雞」的

一個魔都程序員的3年:從程序員到CTO的歷練

選擇比努力更重要:我是如何從流水線工人到程序員的?

程序員的抉擇:必須離開帝都——由於除了工做機會,還有什麼值得留戀?

即時通信創業必讀:解密微信的產品定位、創新思惟、設計法則等

乾了這碗雞湯:從理髮店小弟到阿里P10技術大牛

程序員神級跳槽攻略:何時該跳?作什麼準備?到哪裏找工做?

感悟分享:在騰訊的八年,個人成長之路和職業思考

調皮的程序員:Linux之父雕刻在Linux內核中的故事

附錄2:大廠技術往事

技術往事:微信估值已超5千億,雷軍曾有機會收編張小龍及其Foxmail

QQ和微信兇猛成長的背後:騰訊網絡基礎架構的這些年

閒話即時通信:騰訊的成長史本質就是一部QQ成長史

2017微信數據報告:日活躍用戶達9億、日發消息380億條

騰訊開發微信花了多少錢?技術難度真這麼大?難在哪?

技術往事:創業初期的騰訊——16年前的冬天,誰動了馬化騰的代碼》 

技術往事:史上最全QQ圖標變遷過程,追尋IM巨人的演進歷史》 

技術往事:「QQ羣」和「微信紅包」是怎麼來的?》 

開發往事:深度講述2010到2015,微信一路風雨的背後》 

開發往事:微信千年不變的那張閃屏圖片的由來》 

開發往事:記錄微信3.0版背後的故事(距微信1.0發佈9個月時)》 

一個微信實習生自述:我眼中的微信開發團隊

首次揭祕:QQ實時視頻聊天背後的神祕組織

爲何說即時通信社交APP創業就是一個坑?

微信七年回顧:歷經多少質疑和差評,才配擁有今天的強大

前創始團隊成員分享:盤點微信的前世此生——微信成功的必然和偶然

即時通信創業必讀:解密微信的產品定位、創新思惟、設計法則等

>> 更多同類文章 ……

(本文同步發佈於:http://www.52im.net/thread-1859-1-1.html

相關文章
相關標籤/搜索