天天看點

樸素的UNIX之-翻開曆史

可以毫不誇張地說,UNIX模型就是現代作業系統的原型!不管是原汁原味的UNIX各大系列比如AIX,Solaris,HP-

UX,FreeBSD,NetBSD,...還是類UNIX比如Linux...還是基于Windows

NT架構的各種微軟作業系統,其基本思想都是來源于UNIX。雖然這些系統一個比一個複雜,但是請記住一句話:所有的基本思想都是也必須是樸素的,簡單

的!

也許,很多人看到這裡就覺得有點不屑一顧,畢竟他們覺得自己是技術狂人,覺得隻有擺弄複雜的東西才能證明自己的學識和技術,認為上世紀70年代的被

UNIX

v6是一個過時的系統,裡面的内容早就被歲月無情地抛棄了,但事實上,如果你真的看了那個時代的UNIX源碼,或者讀了萊昂氏的神書,并且細細琢磨之後,

你會發現,那些樸素的觀念一點也不過時,我們如今的很多技術所依托的思想早在1975年的時候就已經被樸素地實作了。三歲看老,無視曆史就是藐視未來。

如果你想知道下一步我們要做什麼,聽别人講是沒用的,你必須親自翻開曆史。正如給你一條曲線的一部分,問你該曲線的下一步走勢,你肯定可以猜個八九不離

十,因為任何事物都是循着曆史前進的,這就是讀史使人明智。前些日子和朋友一起吃飯,請客的是位晶片專家,但是對除晶片以外的任何事物都是不屑一顧,好一

個中國傳統的所謂術業有專攻,就好像世界上除了晶片是高科技之外,其它的都是小兒科,好一個排他!但是你有沒有通過這件事想到些什麼,這位朋友是典型的中

國式學究,所謂的術業有專攻的學究,正是這種所謂的專攻,導緻我們中國事實上從來沒有引領過一個時代,我們從早的說,農業革命發力于美索不達米亞以及尼羅

河中下遊,青銅時代是西亞和東歐遊牧民族引領的,民主觀念來自于希臘,帝國主義來自于羅馬,工業革命來自于西歐,電力革命來自西歐,計算機革命來自美國,

關于最後這一點我會詳細說,以上這些我并沒有提到文藝複興,那是我故意的,因為如果我提到了文藝複興,很多人就會說,我們中國也有很多這類事情,比如周昭

共和,秦王掃六合,漢武大帝,光武中興,貞觀之治,...康乾盛世,但是你要知道,這些和文藝複興一樣,都是局域性事件,不管怎樣,我們現在住着樓房,玩

手機,玩電腦,開汽車,坐高鐵,所有這些都是舶來品,沒有一樣是我們自己的,原因就在于我們的思維不夠發散,我們做軟體就是做軟體,不知道一些思想還可以

用于硬體,我們學OO學得很精通,精通了C++,Java,卻不知道OO來自AI...知道列維飛行卻不知道它和計算機記憶體通路模型的關聯...

說了這麼多看似沒用的,事實上是想說,弄點别的吧,雖然我們都是搞IT的。很多程式設計高手可能真的不屑于1975年的UNIX源代碼,那就是曆史,這位高手

知道怎麼設計類,知道怎麼實作一個排序算法,但是也僅僅如此,說到底,他隻是一個高價的雇傭兵,永遠都成不了将軍,而且随時都可能陣亡。我寫這個系列的文

章,就是想說明一點,用曆史的眼光看作業系統以及任何技術的發展,你會得到更多,往窄的說,UNIX就是一座寶庫,凡是你在現代軟體中能找到的思想,在

UNIX中都是它的影子。

在正式開始之前,簡單的說一下背景。我們現在所面對的計算機早就不是40年前的計算機了,由于需要産業化和降低門檻,整個計算機産業和通訊産業經曆了多次

整合,最終我們把軟體和硬體嚴格區分開來,并且在軟體和硬體的各個組成部分之間也嚴格劃分了界限,這樣的結果就是有利于社會化分工,人們走上了術業有專攻

的專業化道路(其實很多思想家從古希臘梭倫時×××始就開始抨擊專業化了),但是其缺點也是顯而易見的,那就是“對于geek而言,現代計算機已經不好玩

了”。

現代計算機已經不好玩了

看了Linus的自傳,認同一點,現在的計算機已經不适合玩了,主要原因是已經

不好玩了。Linus始終認為技術為娛樂而生!值得注意的是,Linus的自傳《Just for

fun》并非要表達“計算機已經不好玩”這樣的觀點,但是Linus認為,現在的計算機“和你的汽車一樣複雜”,已經不适合讓你随性折騰了。

       事實上,由于計算機已經不再好玩,我們也就無法或者很難就計算機本身再創造所謂的“時代”!現在搞計算機已經淪為了一種職業,一種謀生的手段,其内容也随之淪為了套路和規則!要想創造一個時代,你必須不能術業有專攻,你必須是全才。

時代是玩出來的,我以為!當時的那幫人是無心為之的,之後當所有的玩法标準化時,利益便主宰了一切。能玩得轉的東西必須是簡單的,太複雜的東西在藝術上沒

有美感,在工程學上你必須花費巨大的精力去進行複雜性管理,是以本質的東西便被隐藏在複雜性之下了,你很難去挖掘它,欣賞它。近期讀了幾本書,頗有感受。

太複雜的東西,可以向不懂的人大肆炫耀,但事實上,聽的人根本不知道你在說什麼,你隻是自說自話,孤芳自賞罷了。你可曾想過,為何大師都是紮堆出現的,古

希臘的哲學家,中國先秦的諸子,文藝複興時期的畫家,20世紀初的實體學家,20世紀50-60年代的計算機天才,20世紀70年代的黑客...

計算機産業也是從全民折騰時×××始的,這就和希臘的梭倫改革一樣,但是和希臘的伯裡克利終結了一個時代一樣,産業化,專業化也終結了計算機的嬉皮時代,現

如今,隻有Richard Stallman,Eric S

Raymond他們還在盡力延續那個geek的時代,而事實上,如今的專業化讓很多準geek面對複雜的計算心有餘而力不足。那麼,這個geek時代是怎

麼被終結的呢?我從軟體和硬體相遇的地方說起。

硬體和軟體相遇的地方

最初設計的機器并不是想讓每個人都可以操

控它的,它是隸屬于精英階層的。但是如果有人發現了這些機器中蘊藏的巨大的商機,他便會推動一種全民化運動,全民化運動發展到一定程度,技術已經足夠複

雜,就會出現專業化,于是這種技術便逐漸遠離了大衆,再次被精英所壟斷,正如它最初時那樣。

對于計算機技術而言,我把前一個精英時代的技術成為硬體,我把後一個精英時代的技術稱為軟體,如今在硬體領域,擁有矽晶體技術,Verilog,HDL

等,在軟體領域,有JAVA,Python,PHP,OO,設計模式,靈活開發等術語,專業性讓所有這些東西都具有了排他的性質,而創造計算機時代的地

方,正是軟體和硬體相遇的地方,那就是彙編語言向C語言進化的地方。

要知道,如果你不懂機器的特性,你是用不好彙編語言的,如果你不懂機器的特性,你也不可能用C寫出最高效的代碼,反過來,如果你隻懂C語言,你也不可能将

機器的能力發揮的淋漓盡緻,彙編和C,這就是軟體和硬體相遇的地方,時代就是它們開創的,曆史就是它們寫就的。

彙編語言程式設計讓人循着機器指令走,程式員很難建構自己的高層邏輯,因為你要花費大量的精力在指令本身上,C語言出現後,人們的邏輯思維被解放了,你可以寫

諸如a=b+c這類語句了,而不必“先将立即數放入一個寄存器,再将立即數....兩個寄存器的值相加或者一個寄存器和一個立即數直接相加,結果存

在...”。C語言的最大共享在于解決了“尋址問題”,這就意味着它解決了所有的問題,因為計算機程式設計可以歸為尋址的藝術,C将所有的尋址問題歸結為一個

概念,那就是指針!要知道,現代存儲式計算機的運作,唯一的問題就是尋址問題,不管是資料還是指令,都存在記憶體中,你必須有辦法可以在正确的地方找到指令

或者資料。C指針屏蔽了所有的尋址細節,讓輕松建構應用邏輯成了可能,這些應用邏輯包括複雜的條件語句,循環語句,goto語句,甚至緩沖區溢出。

       硬體和軟體的關系就是怎麼做和做什麼的關系,程式設計人員告訴硬體做什麼之後就可以放心做别的事了,因為他相信硬體知道怎麼做。這個接口就是C語言,而硬體的内部電路邏輯則實作了“怎麼做”的邏輯。

水不知冰有多冷,冰不知水的多情。同一個東西,一旦被隔離,那就是隔行如隔山,本來硬體和軟體是一家的,可如今變成了排他的兩個行業,就算在軟體行業内

部,還經常有各種排他性的隔離,諸如什麼“搞底層的”,“搞協定棧的”,“寫類的”,...軟硬通吃的全棧程式員現在被人和酷(苦)逼聯系在了一起。但是

在30-40年前,計算機時代就是這幫全棧程式員開創的!在軟體和硬體相遇的地方,那幫人同時屬于硬體精英和軟體精英,實際上他們引領的是一種全民玩轉計

算機的嘻哈時代,這個時代被20世紀70-80年代的黑客們所延續,衆所周知的業界名人幾乎都出自那個由UNIX開啟被黑客精神延續的時代,比如喬布斯的

Apple,比爾.蓋茨的Microsoft,理查德.斯托曼的GNU,比爾.喬伊的BSD,IBM PC,Intel

IA32,...不勝枚舉。這是一個簡單純真的時代,一個精簡濃縮的年代。

PC技術與UNIX技術

軟體和硬體相遇的地方就是UNIX誕生的地方,UNIX作為一個營養豐富的根,注定會長成參天大樹,這棵樹上的果實太多,以至于幾乎囊括的所有現如今我們在使用的技術。

PC技術使得計算機小型化,進而出現了微型化的趨勢,随着工藝越來越先進,硬體越來越小,越來越便宜,巨大的商機促進了PC技術的發展,但是軟體這方面卻

沒有實時跟進。多使用者多任務分時系統當時最風靡的就是UNIX,然而UNIX卻受制于各種非技術因素的控制,正因為如此,才讓微軟,蘋果等公司占了先機,

它們兩家你追我趕,一直到今天,導緻這個結果的另一個原因是UNIX從來都不屬于草根(正因為如此才有了GNU),而不管是蘋果還是微軟,都和一個叫“家

釀俱樂部”的草根組織有關,大家在一個相對平和的環境中展示自己的機器和技術,那個時代是黑客的時代。可以說,UNIX并沒有趕上PC時代的潮流,但是這

就是UNIX,正如啟蒙思想家本人不參加法國大革命一樣,UNIX作為一位思想先驅,它的一些古老的觀念,甚至Windows 8系統還在使用。SVR4

VM的設計概念,

可以說是颠覆了傳統對記憶體的了解;檔案抽象使得IO接口變得簡單;基于頁面交換和按需調頁實作的虛拟記憶體的思想影響了幾乎所有的作業系統設計;分級存儲

思想更絕妙,在CPU内部,CPU緩存是記憶體的Cache,在VM裡面,實體記憶體是虛拟記憶體的Cache,在MMU,實體記憶體是磁盤或者網絡的

Cache...;最重要的還是UNIX程序模型(線程模型和程序組模型都是程序模型的擴充),它的重要性我真的不知道該怎麼才能說得清。

       不得不提到的是Intel和微軟以及PC技術這三者的關系,但是這個話題過大,也隻能在此提示一下,總之,PC技術造就了兩大帝國,而Intel和微軟配合太默契,以至于成了一個好像羅馬帝國那樣的存在...

Mac OS X技術

以說,PC技術所依托的Intel技術和微軟的技術是并行發展的,其間出現了太多太多花哨的特性,甚至很多東西都直接固化在了硬體中。如今,蘋果也采用了

Intel晶片,然而它并沒有采用微軟的技術,而是采用了UNIX系統Mach/BSD來建構自己的作業系統Mac OS

X,可以說正是蘋果将PC技術拉進了UNIX,在另一個方向,Android正在和iOS争奪市場,但是不管是Android還是iOS,其底層都是基于

直接的UNIX思想建構的系統,一個是Linux,一個是Mach/BSD。返璞歸真,UNIX技術曆經40年,其基本觀念以及核心基本沒有變過,這足以

說明它的設計是多麼的優秀。

UNIX成功的觀念是,它從來不關注實作細節,因為細節會将你拉離目标。UNIX隻提供基本理念,是以,不管是

AIX,Solaris,Mach,xxBSD,它們的實作絕對截然不同,但是都叫做UNIX。如果微軟願意,Windows

NT也可以稱為UNIX,因為NT系統在70%的程度上實作了UNIX的基本理念。

在UNIX之外,有另一條演進道路,那就是複雜性演化。它是嚴格遵循硬體的最新特性,軟體迎合硬體,硬體慣壞軟體,大家彼此阿谀奉承,實際上大家都忘了,

其實原本大家都是一家。有些時候,僅僅為了一些單一的商業利益,就會把一些複雜但不普适的機制固化在硬體中,這一點的反例就是RISC架構,它就是

UNIX在硬體領域的直接展現。

複雜性演化舉例

資料的位址按照其類型的長

度倍數自然對齊是一個不成文的程式設計約定。可是為何作如此的約定呢?難道不對齊就不行嗎?在某些架構的處理器上,真的就是不行,比如很多的RISC處理器。

然而在CISC架構的處理器,比如Intel/AMD x86架構處理器上,為了程式設計的友善,核心可以替你完成這種費力的操作。這一切的根源在哪裡?

在對整個事情分析之前,必須要明白的是,現代微處理器是超大規模內建電路的結晶,晶片是雕刻在矽這種半導體上的,工藝極其考究,是以布線的簡單就是一切的

根本,在矽晶體上雕刻電路是多麼的令人崇拜啊(還記得我們學過的《核舟記》嗎)。矽晶體雕刻不像進階語言程式設計,它甚至不允許你将事情搞得太複雜(主要是晶

體的布線難度),是以很多事情就要規定死,比如資料的自然對齊。完美的處理器架構隻需要實作一個完成任意操作的最小指令集即可,架構簡單,可以将更多的矽

晶體的空間用于實作高效的流水線而不是複雜的指令(某個複雜的指令往往和其他複雜指令擁有公共部分,這就造成了空間的浪費),這種處理器叫做RISC處理

器。以上這個事實是人們在早期內建電路技術開啟這個新時代的伊始,走了很多彎路才總結出來的,隻可惜,Intel就是那個最先吃螃蟹的人,随後它獲得了巨

大的成功,相容它的指令集将AMD也拉下了水。

       我們知道,抛開微處理器内部必須實作的運算邏輯,其與外部的接口就是尋址和IO。

Intel在最初實作16位微處理器的時候,恨不得為每個我們能想到的尋址邏輯都實作一條硬體指令,事實上它也是這麼努力做的。翻開任何一本彙編語言的

書,首先映入眼簾的就是大量的尋址指令,如果你對着Intel的手冊觀摩,你會發現很多寄存器都不是作為操作數存在的,而是内置于指令本身!是以mov

eax 1和mov ebx

1可能就是兩條完全不同的指令,而不僅僅是操作數的不同,就這樣,複雜指令的實作占據了大量的晶片面積,由于單獨指令完成的事務依然可分割,且長度不

一,Intel便很難實作高效的長流水線。機器指令就是硬體和軟體相遇的地方,是軟體請求到硬體落實的唯一接口,為了相容曾經的軟體,接口是不能随意更改

的,但是當Intel意識到指令必須是足夠簡化,功能足夠單一以便實作長流水線時,它上面的應用程式已經遍地開花了。于是Intel和AMD的政策就是修

改指令的實作,取指令之後,将單條的複雜指令分割為多條簡單指令,即使用了萬變不離其衷的神喻-添加一個中間層!

       于是,Intel的指令事實上最終也是由簡單操作實作的,這些操作稱為微操作,實作一條指令的微操作集合稱為微程式,所有的微程式稱為微碼。于是乎,x86架構實際上隻是在接口是CISC體系架構,其核心已經是RISC體系架構了!

為了解釋記憶體對齊問題,必須知道其實體構造,關鍵并不是如何設計記憶體晶片,而是如何将記憶體晶片的引腳和CPU引出的位址總線對應起來,如何建立兩者之間的

關系是最重要的,别忘了,計算機在CPU之外要解決的唯一問題就是尋址問題!如果資料是任意對齊的,那麼在CPU發出尋址指令時,就可能出現資料存在兩片

晶片上的情況,而為了布線的簡單,這種尋址指令必須兩次完成,如果兩次操作之間鎖住總線,就會大大降低效率,如果不鎖總線,就會有原子性問題。要求編譯器

或者程式員不寫出那樣的指令是最簡單的,是以這個任務就落在了編譯器或程式員的頭上。這就是為何在某些機器上資料一定要自然長度對齊。

UNIX之初

繼續閱讀