close

Android 淺探(二):系統架構

本篇目的在儘量不觸及技術細節的情況下簡介 Android 架構,並探討其設計的特殊處,以及在版權上的意義。主要資料來源為 Anatomy & Physiology of an Android,有興趣深入研究的讀者可參考。

首先來一張現在大概已經很有名的圖片:

由下到上,可以看到紅色的 kernel 層,綠色的系統函式庫,黃色的虛擬機器,以及藍色的 Java 程式碼。以下將一一介紹。

Linux kernel

必也正名乎:一般所稱 Linux,其實是統稱,指根基在 Linux kernel 以及其他許多跟 kernel 不見得有關的軟體所組成的作業系統。最早,Linux 一詞其實是專指 kernel,它提供了系統底層與硬體間的基本平台,讓其他程式可以在上頭執行。其最早作者是 Linus Torvalds,他用自己的名字,加上採用了與 Unix 系統相容的介面,將自己的作品命名為 Linux。

如前所述,在 Linux kernel 上頭執行的程式,跟 kernel 本身不見得有關係。可以是自由軟體,也可以完全不是。把它加上一些自由軟體,例如基本的函式庫、工具、圖形介面,應用程式等等,所組成的一套完整作業系 統,才是一般所稱的 Linux。為了避免誤解,而且也為了正確傳達自身的貢獻,自由軟體基金會建議大家稱呼這樣的一套作業系統為 GNU/Linux。其中的原因是,kernel 提供底層機制,但系統中重要的元件幾乎都是來自於 GNU,也就是自由軟體基金會。

希望大家還沒被這些名詞搞混。要弄清這些不同的原因是,Android 是在 Linux kernel 上頭運作的,但他並不是 GNU/Linux。因為在一般 GNU/Linux 裡面會有的東西,Android 很多都沒有。

Linux kernel 的版權是 GNU General Public License version 2 (GPLv2),這又是什麼玩意呢?GPLv2 是所謂的 Copyleft 版權,簡單來說,就是為了確保智慧財產能夠繼續公開流傳,所以任何基於此創作的延伸創作,都自動採用了相同版權。GPL本身還有個特色,就是「共同運作」 也算是延伸的一部分,意思是說你的程式沒直接改GPL的程式碼,但是連結了GPL的東西跟你的程式共同運作,那你的程式也必須採用GPL版權。

舉例來講,假定今天某公司覺得某GPL軟體不錯,拿來改了改,放在自己的產品裡頭拿出去賣,那某公司就一定要明確的一起散佈修改後的程式碼。如果沒有,那就是觸犯版權了。有個組織叫 GPL Violations, 專門抓這種案例,國內公司如 D-Link 以及 ASUS 都上過榜。這下問題來了:如果你是硬體廠商,希望你的硬體能在 Linux kernel 下運作,那麼就必須要有驅動程式。驅動程式就是按照硬體的規格寫的程式,用來告訴 kernel 怎麼操作這個硬體。如果驅動程式的程式碼公開,等於硬體規格也公開的差不多了。許多廠商不願意這麼做,所以就提供編好的驅動程式,但不提供原始碼。版權所 有者,也就是 Linus Torvalds 以及其他許許多多的 kernel 作者們,為了支援儘可能多的硬體,對這種行為是採取睜一隻眼閉一隻眼的態度,也就是目前這種編譯好的驅動程式,算是處在灰色地帶。

既然 Android 採用了 Linux kernel,當然得照遊戲規矩來。但我們從前文可知,Android 的重點就是商業應用,他們可不願意系統裡有什麼「灰色地帶」,於是採用了一些手法來繞過這問題。他們把驅動程式移到 「userspace」,也就是說,把驅動程式變成在 Linux kernel 上頭跑,而不是一起跑的東西,這樣就可以避過GPL。然後,在 kernel 這邊開個小門,讓本來不能直接控制到硬體的 「userspace」 程式也可以碰得到,這樣只要把「開個小門」的程式碼公佈就行啦。事實上,目前因為 Android 已經發行,所以依法他們已經公開了對 kernel 的修改,其原始碼在 http://git.android.com/

走筆至此,可以看出 Google 的原則之一 「Do no evil」 是很有意思的。他們自己的確承諾,而且也願意公開 Android 的程式碼,但是他們給了其他人 「Do evil」 的選擇。這樣還算不算是 Do no evil 呢?當作哲學問題吧。

關於 Android 對 kernel 的修改,Google 的簡報還提供了兩個重點:

  1. Binder (IPC):提供有效率的程式間溝通管道(Inter-Process Communication)。Android 系統中有很多服務,而上層的應用程式經常要取用這些服務,一般的 Linux 系統已經提供了不少 IPC 的方式,不過 Android 還是搞了套自己的。雖說文件中解釋原因為「一般 IPC 會造成額外資源花費,以及安全問題」,但其實這些都是可以基於原有架構在 kernel 外頭解決的,為何要改在 kernel 裡頭,筆者對此存疑,也只能等找時間去研究程式碼才知了。
  2. Power Management:與桌上型電腦或筆記型電腦不同,手持裝置的電源一向相當有限,必須無所不用其極的去想辦法省電,但又不損及順暢的使用經驗。 Android 在此採取了頗為積極的作法:「沒有人說要用,就關掉」。例如某程式在放 MP3 音樂,於是此程式會需要 CPU 的計算能力,那就得開口要。如果與此同時沒其他程式在執行,那麼 LCD 顯示器就可能被關掉,藉以省電。另一特別處,是在於 Linux kernel 一般考慮的都是在電腦上的作法,所以多半隻有進入暫停、休眠等等的選擇,而不會如此細緻的去控制到各個小裝置的電源供應。

系統函式庫

這裡說的系統函式庫是指 「native libraries」,是跑在系統裡頭的函式庫,採用的語言不是 Java,提供一些基礎建設。裡頭有幾個值得一提的元件:

  1. Bionic:這是 Android 版的 libc。libc 是 GNU/Linux 以及其他類似 Unix 系統上最基礎的函式庫,一般最常用的是 glibc,就是 GNU 做的 libc。不然在比較小型的裝置上也可以用 uclibc。不論是 glibc or uclibc,版權都是LGPL (GPL 的略為弱化版)。看到這大概可以猜到了吧,又是 Copyleft 問題。官方的說法是,除了版權問題以外,還考慮必須輕量以及快速,所以才做了自己的 libc。不過輕量、快速,本來就是小型裝置用的 uclibc 一開始的目標,因此,最主要的恐怕還是版權問題。
  2. Webkit:鼎鼎大名的 Apple Safari 瀏覽器背後的引擎就是 Webkit,Android 也包含進去了。離線使用的 html 配上 html 5 的一些新發展,產生了各種有趣的可能,這部分值得另文介紹,這裡就不再贅述。
  3. Surface Flinger:提供把各種」surface」組合在一起的能力。在這裡 surface 解釋為程式想要顯示在螢幕的東西,可能同一螢幕上有來自不同程式的內容,而這些內容有可能是 2D 顯示或是 3D 顯示等等之類。Surface flinger 就是把這些東西結合起來,一起送到螢幕上。目前程式碼還沒公佈,不過 2D 跟 3D 的混合顯示一直都是問題,根本原因是我們通常告訴 3D 顯示卡的東西都是一些「我要在哪裡哪裡畫上什麼形狀,貼上某某材質然後旋轉多少度」之類的事情,也就是說,我們並不知道最後顯示出來會長什麼樣子,那是顯 示卡上頭的 GPU 去算出來的。一般這些東西是顯示在一個有裝飾的視窗裡頭,這裝飾通常是 2D 效果。接下來假定我們想要旋轉這整個視窗,而且裡頭的東西還要繼續動,那等於要隨時把握 3D 視窗裡的東西長什麼樣子,然後把它跟 2D 的視窗框框結合,然後再開始轉動。目前在一般 GNU/Linux 上這件事情還沒有處理的非常好,Android 怎麼做,值得在程式碼公佈之後注意。
  4. 硬體抽象層 (Hardware Abstraction Libraries):這就是前文所述的 userspace 驅動程式,如果想要將 Android 在某硬體平台上執行,基本上完成這些驅動程式就行了。其內定義了 Android 對各硬體裝置例如顯示晶片、聲音、數位相機、GPS、GSM 等等的需求。

Android Runtime 前文已有涉及,這裡不再重複。另外藍色部分的 「Application Framework」 主要是跟如何在 Android 上寫程式有關係,之後將另文介紹。

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 huenlil 的頭像
    huenlil

    H's 手札

    huenlil 發表在 痞客邦 留言(0) 人氣()