Skip to main content

BSD 與 Embedded BSD簡介

在類 Unix 系統的家族中,目前最為人所知的大概就算是 Linux 系統了。然而,還有另一支跟 Linux 系統很像,但又有點不太一樣的類 Unix 系統叫做 BSD 系統,也常被拿來使用。最近一個蠻有名的例子是 Apple 公司的 Mac OS X 作業系統,其底層所用的 Darwin 核心就是拿FreeBSD 的核心來做修改而來的。

BSD 系統的歷史

一開始的時候,加州大學柏客萊分校的電腦科學研究團隊 (CSRG,Computer Systems Research Group) 對貝爾實驗室 (Bell Labs) 所開發的 Unix 系統不太滿意,因此自行對它做了一些修改。後來越改越多,漸漸的跟原本 Bell Labs 的 Unix 系統越來越不一樣,因此後來這個由 CSRG 所開發的類 Unix 系統另外又稱做是 BSD (Berkeley Software Distribution) 系統。

後來 CSRG 解散了,原本他們所維護的 BSD 系統程式碼被 386BSD 計畫拿去移植並使用在 Intel 的 i386 系統上。過了幾年,這個 386BSD 計畫也終止了,但他們所維護的 386BSD 程式碼被 FreeBSD 跟 NetBSD 這兩個計畫拿去繼續發展。稍後由於 NetBSD 內部的意見分歧,有些人就從 NetBSD 內部獨立出來成立另一個 OpenBSD 計畫。

主流的 BSD 系統

因此目前主流的 BSD 系統大致有下列三種:

FreeBSD
http://www.freebsd.org/


圖:用來代表 FreeBSD 的小惡魔

原本專注於 i386 平台上的開發,後來也慢慢的加入了對 Alpha,Sparc 等其他平台的支援。FreeBSD 最主要的目標是成為Intel/AMD 平台上一個穩定並且經過最佳化後的 BSD 系統。

NetBSD
http://www.netbsd.org/

(按一下放大)
圖:舊的 NetBSD 圖示

立志要成為一個能夠在最多平台上運行的作業系統,到目前為止 NetBSD 可以在 50 多個硬體平台上執行,例如 Macintosh,Atari ST,Amiga,Intel,Playstation2,Sega Dreamcast 等等。時到今日,NetBSD 最主要的成就在於其高度的可移植性,以及成為學術上的研究目標。 很多學校的教授及學生都在 NetBSD 上面實做新的功能,以及驗證新理論的可行性。而某些確實有用的新功能最後也將被移植到其他的作業系統上,比方說 FreeBSD,OpenBSD 等等。

OpenBSD
http://www.openbsd.org/


圖:代表 OpenBSD 的河豚

特別專注在與安全相關的作業系統議題上。OpenBSD 的目標在於成為一個最安全的 BSD 系統。OpenBSD 的開發小組檢視過整個 OpenBSD 系統上的每一行程式碼,試圖找出不安全的部份並進行適當的修改。由於 OpenBSD 計畫是從 NetBSD 計畫中衍生出來的,因此 OpenBSD 也具有不錯的移植性,雖然沒有像 NetBSD 一樣號稱可在 50 多個平台上使用,但 OpenBSD 一樣支援目前一些主流的平台,例如 i386,PowerPC,m68k,Alpha等。並且,在 OpenBSD 上所進行的一些關於安全性的改良成果,最後也將會被移植到其他的 BSD 系統上,比方說 FreeBSD,NetBSD 等。

BSD 的版權宣告

BSD 的開發者往往使用的是 BSD 版權宣告來為他們所寫的軟體定義後續使用者應盡的權利與義務,而這個 BSD 版權宣告跟另一個 GPL 版權宣告常常拿來做一些比較。其實他們一個最明顯的不同點在於使用 BSD License 的軟體可以不用公開原始碼,而使用 GPL License 的軟體不管經過多少的修改都必須要公開修改過後的原始碼。因此在某些情況下,使用 BSD License 可能比較適合。例如商業性的軟體,商業公司不希望公開內部的機密或設計的方法等等。另一個情況是當一個標準 (standard) 的參考實做 (Reference Implementation) 如果使用 BSD License 的話將可以比較容易達到較高的推廣率。

然而,有些商業公司在將其產品開放原始碼的時候,反而比較喜歡採用 GPL,因為這樣可以確保競爭對手在對該程式碼做出修改後,還可以回饋給原來的公司。


BSD GPL
是否可使用在商業軟體中 可以 不行
散播原軟體的限制 必須同樣使用 GPL 才可散播該軟體
對程式碼做出修改後的限制 修改後的程式碼也必須要以 GPL 來進行散播
表:BDS License 跟 GPL License 的比較

核心 (Kernel)

各家不同 BSD 系統 (FreeBSD,NetBSD,OpenBSD 等等) 的核心幾乎都提供了分時排程 (Time-shared scheduling),不同配置演算法的需求分頁 (Demand paging),以及一個虛擬的檔案系統來簡化開發新檔案系統的流程。基本上,各家的 BSD 的核心很多部份都很類似,並且也會互相的截長補短,更慎者,縱使是拿各家的 BSD 核心來跟 Linux 核心相比,也都有很多部份幾乎一樣。

在 FreeBSD 5.3 的核心內,排程的基本單位是一個 thread,並且總共分為 255 個優先級,此外較低的優先權數字代表較高的優先權,這點跟 Linux 2.6 核心相同,但跟 Solaris 核心則相反。FreeBSD 5.3 核心支援 POSIX 定義的 SCHED_FIFO,SCHED_RR 及 SCHED_OTHER 三種排程。

在檔案系統中,FreeBSD 5.3 核心內類似 Linux 2.6 核心的 inode 資料結構是所謂的 vnode (virtual node) 資料結構。然而,FreeBSD 不像 Linux 一般,將檔案的處理分為 file operations 跟 inode operations,而是直接合併成一個 vnode operations。

而在一個完整的作業系統內,不可能只包含一個核心而已,也必須包含其他在執行時所必須的軟體元件,某些元件是執行時所一定需要的,某些則否。那些在執行時一定需要的軟體元件,在 BSD 的世界裡,就被合併起來稱為『基礎系統』。

基礎系統 (Base System)

基礎系統 (Base System) 是由一群用來啟動系統時所需的基本軟體套件所組合而成,這包括了 BSD 的 kernel,BSD 的 ls 以及 BSD 的 libc 等軟體套件,而這些套件被組合在一起開發來獲得最佳的整合性,並且在安裝的時候也必須要一起安裝,無法切割出來。比方說以基礎系統內的 OpenSSH 套件來說,使用者沒有辦法單獨升級 OpenSSH 套件,而必須要升級整個基礎系統才可以。

註:為什麼要特別指名是 BSD 的 ls 跟 libc 呢,這是因為一般在 Linux 系統上所使用的是 GNU 組織所發行的 ls 及 libc,但在 BSD 上則是直接拿 CSRG 所發展的 BSD 系統上的對應套件來修改使用。

不同的 BSD 系統,比方說 FreeBSD,NetBSD,OpenBSD 系統之間,對於基礎系統內應該包括哪些軟體套件的標準不太一樣,所以在這些不同的 BSD 系統之間,他們的基礎系統內所包含的內容也就會有所不同。比方說在 NetBSD 及 OpenBSD 系統內,X Window 視窗系統就被包含在基礎系統內,但在 FreeBSD 系統下,X Window 視窗系統是必須另外安裝的。

然而,縱使是在同一個系統內,也會隨著時間的不同,刪除或擴充其基礎系統的內容。比方說,由於 SSH Server 及 SSH Client的使用越來越廣泛,所以在 FreeBSD 的基礎系統內就涵蓋了 OpenSSH 這個高品質的SSH Server/Client 實作。

當然,由於軟體的一直發展與進步,因此在安裝完 BSD 系統之後,一定會有需要進行基礎系統的升級與更新。由於整個 BSD 的基礎系統是整合在一起開發的,所以也必須要一起安裝,這將會是個冗長的動作。然而,BSD 系統通常都會簡化這樣的步驟,使用者可以很輕鬆的透過抓取基礎系統的原始碼,並且在原始碼的根目錄下執行一些簡單的命令就可以完成整個基礎系統的編譯以及 升級。基本上,FreeBSD 基礎系統的升級流程類似上述的動作,然而 NetBSD 採用了一個比較不一樣的機制,OpenBSD 則是需要幾乎重新安裝整個作業系統才能完成基礎系統的升級。

Ports 系統 (Ports System)

而除了基礎系統之外,其他在 BSD 系統下的所有軟體套件都可以在所謂的 ports 系統下找到。所有可以在 BSD 下執行的軟體原始碼都被集中在一個大型的原始碼樹下,每一個軟體都是這個原始碼樹下的一個目錄,這麼做的原因是因為管理比較方便,除了把軟體蒐集並集中在 一起之外,在經過了或多或少的修改之後,使得所有軟體都能夠適合並緊密的整合到 BSD 系統中。

(按一下放大)
圖:FreeBSD 的 Ports 系統原始碼樹

註:為什麼叫做 Ports 系統?由於很多軟體必須經過或多或少的修改才可以在 BSD 系統上執行,因此用來蒐集並管理這些經過移植 (porting) 後的軟體的系統就稱做是 ports 系統。

基本上,如果要從 ports 系統安裝軟件,使用者必須先從 ports 系統下載軟體的原始碼,然後經過編譯與安裝的流程就可以在 BSD 上使用該軟體。當然這跟 Linux 系統的 rpm 或 deb 套件管理系統有些差異,rpm 或 deb 是以安裝二進位檔 (Binary file) 的角度來設計的,之後才設計出額外的從原始碼編譯軟體的機制。然而,ports 系統是以從原始碼編譯的角度來設計,之後才發展出直接拿事先編譯好的二進位檔來安裝的方便功能。如果讀者有使用過 Linux 世界裡的 gentoo 系統 (http://www.gentoo.org/) 的話,就會發現 gentoo 的 portage 套件管理系統就是模仿 BSD 的 ports 系統,可以讓使用者便利的從每一個軟體套件的原始碼開始自行編譯並且安裝系統。


類 ports 系統 類 rpm 或 deb 系統
硬碟空間使用量 由於需從原始碼開始編譯,所以需要較多的硬碟空間 由於直接安裝編譯好的二進位檔,所以只需較少的硬碟空間
安裝所需的時間 需要花費大量的時間在編譯原始碼上 只需要些許的時間就可完成安裝的動作
對套件的掌握度 極高,因為可以自行設定編譯時期的選項 較低,只能遵循套件管理者的設定
不同函式庫版本之間的衝突性 極低,因為套件是自行編譯的,所以可以針對當時所使用的函式庫版本來製作出對應的套件出來 較高,假如所使用的函式庫版本與套件管理者預先設定的版本不相容,則軟體在安裝或執行上就會有或多或少的問題
表:不同套件管理系統間的優缺點

FreeBSD 的版本編號命名法則

由於目前常用的 BSD 系統應該要算是 FreeBSD 了,而 FreeBSD 系統的每個版本間的命名法則有些複雜,因此筆者在這邊來做個說明。基本上 FreeBSD 的開發主要分成兩個主軸,其中一個發展主軸叫做 CURRENT,另外一個發展主軸叫做 STABLE。而 STABLE 的發展重點放在修正程式或安全性的錯誤,因此 STABLE 的變動性不大,所以 STABLE 的意思不是說整個系統執行起來很穩定,而是說 STABLE 這條發展主軸的變動性不大。而所有變動性大的修改,比方說架構上的更新,新功能的增加等等,都會實做在 CURRENT 這條發展線上。而在某些時間點,當開發小組覺得目前的發展狀態到了某種穩定度的時候,就會把當時的發展成果標記成 RELEASE。他們的關係可用下圖來做說明:

(按一下放大)
圖:FreeBSD 的開發軸線

FreeBSD 的版本編號主要還是依照一般開放原始碼的習慣,以數個英文字母來代表,比方說 2.3-STABLE。其中的 2 代表主要的版本編號,而 3 則代表次要的版本編號,-STABLE代表的則是 STABLE 的發展軸線,也就是說變動不會太大的意思。大版本編號的增加是當某些重大的架構變動或新功能加入到 FreeBSD 裡面後,就有可能會因此增加大版本編號。但通常在新版本的第二或第三個次要版本發展出來之後,該新的版本才會從 CURRENT 軸線放到 STABLE 軸線中。這整個流程可用下圖來做說明:

(按一下放大)
圖:FreeBSD 的版本編號演變流程

基本上,這個版本命名法則是以 FreeBSD 為中心,但 NetBSD 其實也有類似的情況。

BSD 系統上軟體的開發

一般說來,一個軟體只要所使用的作業系統功能是定義在標準內的,比方說該軟體都使用 POSIX 介面來與作業系統溝通。那麼這個軟體就幾乎確定可以在 BSD 系統上執行。然而,由於 Linux 系統的普及性,因此某些軟體使用到了專屬於 Linux 系統內的專屬功能,那麼這個時候,該軟體就必須要經過移植跟修改,才能夠在 BSD 系統下執行。

然而,並不是每個使用到專屬 Linux 系統功能的軟體都可以取得原始碼來進行修改。因此在 BSD 系統下,幾乎都提供了一個模擬 Linux 系統的模擬器,來讓上層那些特殊的軟體能夠順利的在 BSD 系統上執行。因此這些軟體的能否順利執行與否,就端視這一層模擬層能否提供所需的執行環境。

目前 BSD 在嵌入式系統上的應用

雖然很少為人所知,但目前的確已經有許多嵌入式計畫或裝置上面使用 BSD 作業系統。

PicoBSD
http://people.freebsd.org/~picobsd/picobsd.html

PicoBSD 是 FreeBSD 官方的一個計畫,這個計畫的目的是把一個相對完整的 FreeBSD 系統給放置到一張容量為 1.44MB 的軟碟片上。這個計畫的最新版本是 0.42 版。它宣稱可以在一台 386SX 並配有 8MB 記憶體的機器上運作順利。

使用 PicoBSD 並搭配一台只有網路卡跟軟碟機的簡單電腦,就可以完成一個簡單的防火牆 (firewall) 設備了。

Wasabi Systems
http://www.wasabisystems.com/


圖:Wasabi 公司的標誌

Wasabi 公司是由一群 NetBSD 的開發者所成立的公司,這裡面包含了 NetBSD 的核心開發小組。他們專注於將 NetBSD 移植到嵌入式裝置或網路裝置上,並且進行開發的工作。

Soekris
http://www.soekris.com/


圖:Soekris 的公司標誌

(按一下放大)
圖:Soekris 公司設計的 Net4801 開發版

Soekris 是一家專門設計嵌入式電腦跟通訊設備的公司。他們最新的產品 Net4801 開發版上面就明確支援了 FreeBSD,NetBSD 以及 OpenBSD。

在 Net4801 開發版上,裝載了一顆 266 Mhz 的中央處理器,以及 128MB 的隨機存取記憶體。可以使用一般的硬碟來當主要的儲存裝置,也可以使用 Compact Flash 卡。如果要在 net4801 開發版上面安裝 BSD 系統的話,可以參考下面的計畫成果。

OpenSoekris 計畫
http://opensoekris.sourceforge.net/

這個計畫的成果是一些 script 檔案,透過執行這些 script 檔案,使用者可以為 Soekris 公司的產品製作出一個可開機的 OpenBSD 映像檔。最新的版本是 1.0.12 版。

CompactBSD 計畫
http://sourceforge.net/projects/compactbsd

CompactBSD 計畫可以讓使用者製作出一個小型的 OpenBSD 系統,並且把它放到 Compact flash 卡中。目前的最新版本是 0.1.0 版。

Apple Mac Mini

(按一下放大)
圖:Apple 出的 Mac Mini

在 Mac Mini 一出廠的時候,內部安裝的是 Mac OS X。所以如果我們想把 BSD 裝在上面的話,得先把硬碟重新分割。不過 Mac OS X 內建的分割工具非常陽春 (比方說 Disk Utility),幾乎只能夠重新分割硬碟而已,因此除非使用第三方軟體,否則就只能夠重灌 Mac OS X 了。

針對硬體支援部份,目前的 BSD 系統沒有辦法支援 Mac Mini 上的 Airport Extreme 卡以及內建的 modem。然而,顯示卡及音效卡這兩個部份都可以順利的運作,因此 X Window 也可以正常的啟動。

如果你想要在 Mac Mini 上開發程式的話,BSD 系統幾乎都採用 GNU Compiler Collection,因此開發軟體也就不是一件困難的事情了。

自行製作一個 Embedded BSD 系統

由於 BSD 所採用的 BSD License 對商業公司來說或許比較適當,所以在嵌入式系統上,不難見到 BSD 的蹤跡。因此我們現在來看看要如何製作出一個 Embedded 的 BSD 系統。

製作 Kernel

首先我們得製作出一個符合目標系統所使用的核心 (kernel) 出來。製作 kernel 的方法非常簡單,根據你平台的硬體配置來包含相關的驅動程式,如果你有編譯過 BSD 的核心或 Linux 的核心,那麼這一個步驟將會很容易的。

製作 /sbin/init 執行檔

/sbin/init 執行檔也就是當 kernel 起來後所呼叫的第一個使用者程式。所以使用者可以自行撰寫一個 init 程式,然後把所有需要執行的功能都放到 init 內,這種方法適合用在目標平台在開機後就只需要執行一項事先定義好的任務,而不需要動態的啟動新的任務起來。

另一種方法是使用一般的 init 程式,也就是一般我們使用在 BSD 系統內的 init,並且搭配一個 shell 來動態的啟動我們所需要的服務。這個方法的好處是比自行撰寫一個 init 程式來的簡單,而且假如日後要加入新的功能的話,也僅僅只需要把新的執行檔放到目標平台上即可。

製作其他所需軟體

除了 kernel 之外的軟體基本上都可以透過在一般的電腦系統上進行跨平台編譯 (Cross-compile) 後放置到目標平台上。如果需要小型化的軟體的話,可以參考 busybox 或者是自行採用Crunchgen 這類的工具來從許多的程式中組合出一個較小的執行檔出來。

@附註:Crunchgen 的運作原理:由於在某些版本的 BSD 系統上許多的程式都是使用 static link 的方式 (比方說 NetBSD),所以相同的函式庫空間可能會在好幾個執行檔裡面出現,這樣也就浪費了記憶空間 (記憶體或硬碟),而 Crunchgen 這類的工具程式就是用來把這些 static link 的函式庫

製作目標平台的檔案系統 (File System)

在準備好核心 (kernel),以及其他所需的軟體之後,我們就可以開始來製作目標平台上的檔案系統了。在這個檔案系統裡應該要有 /dev 目錄,/sbin/init 執行檔,如果需要 shell 的話,它應該會位於 /bin/sh,而其他所需的軟體也應該照著正確的目錄來擺近這個檔案系統內。

製作出最後的映像檔 (Image file)

接下來,我們可以使用 makefs 這個工具程式來把我們剛剛製作出來的檔案系統目錄組合成一個單一的映像檔。而在產生這個映像檔之後,我們還可以使用 mdsetimage 這個工具程式來把它與 kernel 連結在一起。而當目標平台上的開機啟動程式 (boot loader) 啟動這個 kernel 的時候,它就會自動執行 /sbin/init,以及使用者所設定的開機程序。

結語

由於 BSD 系統擁有穩定的核心及優良的 TCP/IP 協議實作,因此在很多網路設備上,例如 router 跟無線網路裝置上都可以看到 BSD 系統的蹤影。筆者認為不論是 BSD 還是 Linux 都很適合使用在嵌入式設備上,但最後到底要使用哪一種系統端視比較喜歡 BSD License 還是 GPL License。如果選定使用 BSD License 的話,那麼就可以選擇 FreeBSD,OpenBSD 或者是 NetBSD 來當作嵌入式設備的作業系統;反之,如果選定採用 GPL License 的話,那麼就可以使用 Linux。由於 BSD 跟 Linux 在整個系統架構上都很相近,所以 Embedded BSD 的開發跟 Embedded Linux 的極為類似。因此相信在未來,一定會有更多的嵌入式系統中使用 BSD,不論是 FreeBSD,NetBSD,還是 OpenBSD,相信都會在嵌入式裝置上佔有一席之地的。


Comments