## 0.4 軟件程序運行
鳥哥在上課時常常會開玩笑的問:“我們知道沒有插電的電腦是一堆廢鐵,那么插了電的電腦是什么?” 答案是:“一堆會電人的廢鐵”!這是因為沒有軟件的運行,電腦的功能就無從發揮之故。 就好像沒有了靈魂的軀體也不過就是行尸走肉,重點在于軟件/靈魂啰!所以下面咱們就得要了解一下“軟件”是什么。
一般來說,目前的電腦系統將軟件分為兩大類,一個是系統軟件,一個是應用程序。但鳥哥認為我們還是得要了解一下什么是程序, 尤其是機器程序,了解了之后再來探討一下為什么現今的電腦系統需要“操作系統”這玩意兒呢!
### 0.4.1 機器程序與編譯程序
我們前面談到電腦只認識0與1而已,而且電腦最重要的運算與邏輯判斷是在CPU內部, 而CPU其實是具有微指令集的。因此,我們需要CPU幫忙工作時,就得要參考微指令集的內容, 然后撰寫讓CPU讀的懂的指令碼給CPU執行,這樣就能夠讓CPU運行了。
不過這樣的流程有幾個很麻煩的地方,包括:
* 需要了解機器語言:機器只認識0與1,因此你必須要學習直接寫給機器看的語言! 這個地方相當的難呢!
* 需要了解所有硬件的相關功能函數:因為你的程序必須要寫給機器看, 當然你就得要參考機器本身的功能,然后針對該功能去撰寫程序碼。例如,你要讓DVD影片能夠放映, 那就得要參考DVD光驅的硬件信息才行。萬一你的系統有比較冷門的硬件,光是參考技術手冊可能會昏倒~
* 程序不具有可攜性:每個CPU都有獨特的微指令集,同樣的,每個硬件都有其功能函數。 因此,你為A電腦寫的程序,理論上是沒有辦法在B電腦上面運行的!而且程序碼的修改非常困難! 因為是機器碼,并不是人類看的懂得程序語言啊!
* 程序具有專一性:因為這樣的程序必須要針對硬件功能函數來撰寫, 如果已經開發了一支瀏覽器程序,想要再開發文件管理程序時,還是得從頭再參考硬件的功能函數來繼續撰寫, 每天都在和“硬件”挑戰!可能需要天天喝蠻牛了!@_@
那怎么解決啊?為了解決這個問題,電腦科學家設計出一種讓人類看的懂得程序語言, 然后創造一種“編譯器”來將這些人類能夠寫的程序語言轉譯成為機器能看懂得機器碼, 如此一來我們修改與撰寫程序就變的容易多了!目前常見的編譯器有C, C++, Java, Fortran等等。 機器語言與高階程序語言的差別如下所示:
圖0.4.1、編譯器的角色
從上面的圖示我們可以看到高階程序語言的程序碼是很容易察看的!鳥哥已經將程序碼(英文)寫成中文說~ 這樣比較好理解啦!所以這樣已經將程序的修改問題處理完畢了。 問題是,在這樣的環境下面我們還是得要考慮整體的硬件系統來設計程序喔!
舉例來說,當你需要將運行的數據寫入內存中,你就得要自行分配一個內存區塊出來讓自己的數據能夠填上去, 所以你還得要了解到內存的位址是如何定位的,啊!眼淚還是不知不覺的流了下來... 怎么寫程序這么麻煩啊!
為了要克服硬件方面老是需要重復撰寫控制碼的問題,所以就有操作系統(Operating System, OS)的出現了! 什么是操作系統呢?下面就來談一談先!
### 0.4.2 操作系統
如同前面提到的,在早期想要讓電腦執行程序就得要參考一堆硬件功能函數,并且學習機器語言才能夠撰寫程序。 同時每次寫程序時都必須要重新改寫,因為硬件與軟件功能不見得都一致之故。那如果我能夠將所有的硬件都驅動, 并且提供一個發展軟件的參考接口來給工程師開發軟件的話,那發展軟件不就變的非常的簡單了?那就是操作系統啦!
* 操作系統核心(Kernel)
操作系統(Operating System, OS)其實也是一組程序, 這組程序的重點在于管理電腦的所有活動以及驅動系統中的所有硬件。 我們剛剛談到電腦沒有軟件只是一堆廢鐵,那么操作系統的功能就是讓CPU可以開始判斷邏輯與運算數值、 讓內存可以開始載入/讀出數據與程序碼、讓硬盤可以開始被存取、讓網卡可以開始傳輸數據、 讓所有周邊可以開始運行等等。總之,硬件的所有動作都必須要通過這個操作系統來達成就是了。
上述的功能就是操作系統的核心(Kernel)了!你的電腦能不能做到某些事情,都與核心有關! 只有核心有提供的功能,你的電腦系統才能幫你完成!舉例來說,你的核心并不支持TCP/IP的網絡協定, 那么無論你購買了什么樣的網卡,這個核心都無法提供網絡能力的!
但是單有核心我們使用者也不知道能作啥事的~因為核心主要在管控硬件與提供相關的能力(例如存取硬盤、網絡功能、CPU資源取得等), 這些管理的動作是非常的重要的,如果使用者能夠直接使用到核心的話,萬一使用者不小心將核心程序停止或破壞, 將會導致整個系統的崩潰!因此核心程序所放置到內存當中的區塊是受保護的! 并且開機后就一直常駐在內存當中。

**Tips** 所以整部系統只有核心的話,我們就只能看著已經準備好運行(Ready)的電腦系統,但無法操作他! 好像有點望梅止渴的那種感覺啦!這個時候就需要軟件的幫忙了!
* 系統調用(System Call)
既然我的硬件都是由核心管理,那么如果我想要開發軟件的話,自然就得要去參考這個核心的相關功能! 唔!如此一來不是從原本的參考硬件函數變成參考核心功能,還是很麻煩啊!有沒有更簡單的方法啊!
為了解決這個問題,操作系統通常會提供一整組的開發接口給工程師來開發軟件! 工程師只要遵守該開發接口那就很容易開發軟件了!舉例來說,我們學習C程序語言只要參考C程序語言的函數即可, 不需要再去考慮其他核心的相關功能,因為核心的系統調用接口會主動的將C程序語言的相關語法轉成核心可以了解的任務函數, 那核心自然就能夠順利運行該程序了!
如果我們將整個電腦系統的相關軟/硬件繪制成圖的話,他的關系有點像這樣:
圖0.4.2、操作系統的角色
電腦系統主要由硬件構成,然后核心程序主要在管理硬件,提供合理的電腦系統資源分配(包括CPU資源、內存使用資源等等), 因此只要硬件不同(如x86架構與RISC架構的CPU),核心就得要進行修改才行。 而由于核心只會進行電腦系統的資源分配,所以在上頭還需要有應用程序的提供,使用者才能夠操作系統的。
為了保護核心,并且讓程序設計師比較容易開發軟件,因此操作系統除了核心程序之外,通常還會提供一整組開發接口, 那就是系統調用層。軟件開發工程師只要遵循公認的系統調用參數來開發軟件,該軟件就能夠在該核心上頭運行。 所以你可以發現,軟件與核心有比較大的關系,與硬件關系則不大!硬件也與核心有比較大的關系! 至于與使用者有關的,那就是應用程序啦!

**Tips** 在定義上,只要能夠讓計算機硬件正確無誤的運行,那就算是操作系統了。所以說, 操作系統其實就是核心與其提供的接口工具,不過就如同上面講的,因為最陽春的核心缺乏了與使用者溝通的友好接口, 所以在目前,一般我們提到的“操作系統”都會包含核心與相關的使用者應用軟件呢!
簡單的說,上面的圖示可以帶給我們下面的概念:
* 操作系統的核心層直接參考硬件規格寫成, 所以同一個操作系統程序不能夠在不一樣的硬件架構下運行。舉例來說,個人電腦版的Windows 8.1 不能直接在 ARM 架構 (手機與平板硬件) 的電腦下運行。
* 操作系統只是在管理整個硬件資源,包括CPU、內存、輸入輸出設備及文件系統文件。 如果沒有其他的應用程序輔助,操作系統只能讓電腦主機準備妥當(Ready)而已!并無法運行其他功能。 所以你現在知道為何Windows上面要達成網頁影像的運行還需要類似PhotoImpact或Photoshop之類的軟件安裝了吧?
* 應用程序的開發都是參考操作系統提供的開發接口, 所以該應用程序只能在該操作系統上面運行而已,不可以在其他操作系統上面運行的。 現在您知道為何去購買線上游戲的光盤時,光盤上面會明明白白的寫著該軟件適合用于哪一種操作系統上了吧? 也該知道某些游戲為何不能夠在Linux上面安裝了吧?
* 核心功能
既然核心主要是在負責整個電腦系統相關的資源分配與管理,那我們知道其實整部電腦系統最重要的就是CPU與內存, 因此,核心至少也要有這些功能的:
* 系統調用接口(System call interface)
剛剛談過了,這是為了方便程序開發者可以輕易的通過與核心的溝通,將硬件的資源進一步的利用, 于是需要有這個簡易的接口來方便程序開發者。
* 程序管理(Process control)
總有聽過所謂的“多任務環境”吧?一部電腦可能同時間有很多的工作跑到CPU等待運算處理, 核心這個時候必須要能夠控制這些工作,讓CPU的資源作有效的分配才行!另外, 良好的CPU調度機制(就是CPU先運行那個工作的排列順序)將會有效的加快整體系統性能呢!
* 內存管理(Memory management)
控制整個系統的內存管理,這個內存控制是非常重要的,因為系統所有的程序碼與數據都必須要先存放在內存當中。 通常核心會提供虛擬內存的功能,當內存不足時可以提供內存交換(swap)的功能哩。
* 文件系統管理(Filesystem management)
文件系統的管理,例如數據的輸入輸出(I/O)等等的工作啦!還有不同文件格式的支持啦等等, 如果你的核心不認識某個文件系統,那么您將無法使用該文件格式的文件啰!例如:Windows 98就不認識NTFS文件格式的硬盤;
* 設備的驅動(Device drivers)
就如同上面提到的,硬件的管理是核心的主要工作之一,當然啰,設備的驅動程序就是核心需要做的事情啦! 好在目前都有所謂的“可載入模塊”功能,可以將驅動程序編輯成模塊,就不需要重新的編譯核心啦! 這個也會在后續的[第十九章](../Text/index.html)當中提到的!

**Tips** 事實上,驅動程序的提供應該是硬件廠商的事情!硬件廠商要推出硬件時,應該要自行參考操作系統的驅動程序開發接口, 開發完畢后將該驅動程序連同硬件一同販賣給使用者才對!舉例來說,當你購買顯卡時, 顯卡包裝盒都會附上一片光盤,讓你可以在進入Windows之后進行驅動程序的安裝啊!
* 操作系統與驅動程序
老實說,驅動程序可以說是操作系統里面相當重要的一環了!不過,硬件可是持續在進步當中的! 包括主板、顯卡、硬盤等等。那么比較晚推出的較新的硬件,例如顯卡,我們的操作系統當然就不認識啰! 那操作系統該如何驅動這塊新的顯卡?為了克服這個問題,操作系統通常會提供一個開發接口給硬件開發商, 讓他們可以根據這個接口設計可以驅動他們硬件的“驅動程序”,如此一來,只要使用者安裝驅動程序后, 自然就可以在他們的操作系統上面驅動這塊顯卡了。
圖0.4.3、驅動程序與操作系統的關系
由上圖我們可以得到幾個小重點:
* 操作系統必須要能夠驅動硬件,如此應用程序才能夠使用該硬件功能;
* 一般來說,操作系統會提供開發接口,讓開發商制作他們的驅動程序;
* 要使用新硬件功能,必須要安裝廠商提供的驅動程序才行;
* 驅動程序是由廠商提供的,與操作系統開發者無關。
所以,如果你想要在某個操作系統上面安裝一張新的顯卡,那么請要求該硬件廠商提供適當的驅動程序吧! ^_^! 為什么要強調“適當的驅動程序”呢? 因為驅動程序仍然是依據操作系統而開發的, 所以,給Windows用的驅動程序當然不能使用于Linux的環境下了。
### 0.4.3 應用程序
應用程序是參考操作系統提供的開發接口所開發出來軟件,這些軟件可以讓使用者操作,以達到某些電腦的功能利用。 舉例來說,辦公室軟件(Office)主要是用來讓使用者辦公用的;影像處理軟件主要是讓使用者用來處理影音數據的; 瀏覽器軟件主要是讓使用者用來上網瀏覽用的等等。
需要注意的是,應用程序是與操作系統有關系的,如同上面的圖示當中的說明喔。因此,如果你想要購買新軟件, 請務必參考軟件上面的說明,看看該軟件是否能夠支持你的操作系統啊!舉例來說,如果你想要購買線上游戲光盤, 務必參考一下該光盤是否支持你的操作系統,例如是否支持Windows XP/Windows Vista/MAC/Linux等等。 不要購買了才發現該軟件無法安裝在你的操作系統上喔!
我們拿常見的微軟公司的產品來說明。你知道Windows 8.1, Office 2013之間的關系了嗎?
* Windows 8.1 是一套操作系統,他必須先安裝到個人電腦上面,否則電腦無法開機運行;
* Windows 7 與Windows 8.1 是兩套不同的操作系統,所以能在Win 7上安裝的軟件不見得可在Win 8.1上安裝;
* Windows 8.1安裝好后,就只能擁有很少的功能,并沒有辦公室軟件;
* Office 2013是一套應用程序,要安裝前必須要了解他能在哪些操作系統上面運行。
- 鳥哥的Linux私房菜:基礎學習篇 第四版
- 目錄及概述
- 第零章、計算機概論
- 0.1 電腦:輔助人腦的好工具
- 0.2 個人電腦架構與相關設備元件
- 0.3 數據表示方式
- 0.4 軟件程序運行
- 0.5 重點回顧
- 0.6 本章習題
- 0.7 參考資料與延伸閱讀
- 第一章、Linux是什么與如何學習
- 1.1 Linux是什么
- 1.2 Torvalds的Linux發展
- 1.3 Linux當前應用的角色
- 1.4 Linux 該如何學習
- 1.5 重點回顧
- 1.6 本章習題
- 1.7 參考資料與延伸閱讀
- 第二章、主機規劃與磁盤分區
- 2.1 Linux與硬件的搭配
- 2.2 磁盤分區
- 2.3 安裝Linux前的規劃
- 2.4 重點回顧
- 2.5 本章習題
- 2.6 參考資料與延伸閱讀
- 第三章、安裝 CentOS7.x
- 3.1 本練習機的規劃--尤其是分區參數
- 3.2 開始安裝CentOS 7
- 3.3 多重開機安裝流程與管理(Option)
- 3.4 重點回顧
- 3.5 本章習題
- 3.6 參考資料與延伸閱讀
- 第四章、首次登陸與線上求助
- 4.1 首次登陸系統
- 4.2 文字模式下指令的下達
- 4.3 Linux系統的線上求助man page與info page
- 4.4 超簡單文書編輯器: nano
- 4.5 正確的關機方法
- 4.6 重點回顧
- 4.7 本章習題
- 4.8 參考資料與延伸閱讀
- 第五章、Linux 的文件權限與目錄配置
- 5.1 使用者與群組
- 5.2 Linux 文件權限概念
- 5.3 Linux目錄配置
- 5.4 重點回顧
- 5.5 本章練習
- 5.6 參考資料與延伸閱讀
- 第六章、Linux 文件與目錄管理
- 6.1 目錄與路徑
- 6.2 文件與目錄管理
- 6.3 文件內容查閱
- 6.4 文件與目錄的默認權限與隱藏權限
- 6.5 指令與文件的搜尋
- 6.6 極重要的復習!權限與指令間的關系
- 6.7 重點回顧
- 6.8 本章習題:
- 6.9 參考資料與延伸閱讀
- 第七章、Linux 磁盤與文件系統管理
- 7.1 認識 Linux 文件系統
- 7.2 文件系統的簡單操作
- 7.3 磁盤的分區、格式化、檢驗與掛載
- 7.4 設置開機掛載
- 7.5 內存交換空間(swap)之創建
- 7.6 文件系統的特殊觀察與操作
- 7.7 重點回顧
- 7.8 本章習題 - 第一題一定要做
- 7.9 參考資料與延伸閱讀
- 第八章、文件與文件系統的壓縮,打包與備份
- 8.1 壓縮文件的用途與技術
- 8.2 Linux 系統常見的壓縮指令
- 8.3 打包指令: tar
- 8.4 XFS 文件系統的備份與還原
- 8.5 光盤寫入工具
- 8.6 其他常見的壓縮與備份工具
- 8.7 重點回顧
- 8.8 本章習題
- 8.9 參考資料與延伸閱讀
- 第九章、vim 程序編輯器
- 9.1 vi 與 vim
- 9.2 vi 的使用
- 9.3 vim 的額外功能
- 9.4 其他 vim 使用注意事項
- 9.5 重點回顧
- 9.6 本章練習
- 9.7 參考資料與延伸閱讀
- 第十章、認識與學習BASH
- 10.1 認識 BASH 這個 Shell
- 10.2 Shell 的變量功能
- 10.3 命令別名與歷史命令
- 10.4 Bash Shell 的操作環境:
- 10.5 數據流重導向
- 10.6 管線命令 (pipe)
- 10.7 重點回顧
- 10.8 本章習題
- 10.9 參考資料與延伸閱讀
- 第十一章、正則表達式與文件格式化處理
- 11.1 開始之前:什么是正則表達式
- 11.2 基礎正則表達式
- 11.3 延伸正則表達式
- 11.4 文件的格式化與相關處理
- 11.5 重點回顧
- 11.6 本章習題
- 11.7 參考資料與延伸閱讀
- 第十二章、學習 Shell Scripts
- 12.1 什么是 Shell scripts
- 12.2 簡單的 shell script 練習
- 12.3 善用判斷式
- 12.4 條件判斷式
- 12.5 循環 (loop)
- 12.6 shell script 的追蹤與 debug
- 12.7 重點回顧
- 12.8 本章習題
- 第十三章、Linux 帳號管理與 ACL 權限設置
- 13.1 Linux 的帳號與群組
- 13.2 帳號管理
- 13.3 主機的細部權限規劃:ACL 的使用
- 13.4 使用者身份切換
- 13.5 使用者的特殊 shell 與 PAM 模塊
- 13.6 Linux 主機上的使用者訊息傳遞
- 13.7 CentOS 7 環境下大量創建帳號的方法
- 13.8 重點回顧
- 13.9 本章習題
- 13.10 參考資料與延伸閱讀
- 第十四章、磁盤配額(Quota)與進階文件系統管理
- 14.1 磁盤配額 (Quota) 的應用與實作
- 14.2 軟件磁盤陣列 (Software RAID)
- 14.3 邏輯卷軸管理員 (Logical Volume Manager)
- 14.4 重點回顧
- 14.5 本章習題
- 14.6 參考資料與延伸閱讀
- 第十五章、例行性工作調度(crontab)
- 15.1 什么是例行性工作調度
- 15.2 僅執行一次的工作調度
- 15.3 循環執行的例行性工作調度
- 15.4 可喚醒停機期間的工作任務
- 15.5 重點回顧
- 15.6 本章習題
- 第十六章、程序管理與 SELinux 初探
- 16.1 什么是程序 (process)
- 16.2 工作管理 (job control)
- 16.3 程序管理
- 16.4 特殊文件與程序
- 16.5 SELinux 初探
- 16.6 重點回顧
- 16.7 本章習題
- 16.8 參考資料與延伸閱讀
- 第十七章、認識系統服務 (daemons)
- 17.1 什么是 daemon 與服務 (service)
- 17.2 通過 systemctl 管理服務
- 17.3 systemctl 針對 service 類型的配置文件
- 17.4 systemctl 針對 timer 的配置文件
- 17.5 CentOS 7.x 默認啟動的服務簡易說明
- 17.6 重點回顧
- 17.7 本章習題
- 17.8 參考資料與延伸閱讀
- 第十八章、認識與分析登錄文件
- 18.1 什么是登錄文件
- 18.2 rsyslog.service :記錄登錄文件的服務
- 18.3 登錄文件的輪替(logrotate)
- 18.4 systemd-journald.service 簡介
- 18.5 分析登錄文件
- 18.6 重點回顧
- 18.7 本章習題
- 18.8 參考資料與延伸閱讀
- 第十九章、開機流程、模塊管理與 Loader
- 19.1 Linux 的開機流程分析
- 19.2 核心與核心模塊
- 19.3 Boot Loader: Grub2
- 19.4 開機過程的問題解決
- 19.5 重點回顧
- 19.6 本章習題
- 19.7 參考資料與延伸閱讀
- 第二十章、基礎系統設置與備份策略
- 20.1 系統基本設置
- 20.2 服務器硬件數據的收集
- 20.3 備份要點
- 20.4 備份的種類、頻率與工具的選擇
- 20.5 鳥哥的備份策略
- 20.6 災難復原的考慮
- 20.7 重點回顧
- 20.8 本章習題
- 20.9 參考資料與延伸閱讀
- 第二十一章、軟件安裝:源代碼與 Tarball
- 20.1 開放源碼的軟件安裝與升級簡介
- 21.2 使用傳統程序語言進行編譯的簡單范例
- 21.3 用 make 進行宏編譯
- 21.4 Tarball 的管理與建議
- 21.5 函數庫管理
- 21.6 檢驗軟件正確性
- 21.7 重點回顧
- 21.8 本章習題
- 21.9 參考資料與延伸閱讀
- 第二十二章、軟件安裝 RPM, SRPM 與 YUM
- 22.1 軟件管理員簡介
- 22.2 RPM 軟件管理程序: rpm
- 22.3 YUM 線上升級機制
- 22.4 SRPM 的使用 : rpmbuild (Optional)
- 22.5 重點回顧
- 22.6 本章習題
- 22.7 參考資料與延伸閱讀
- 第二十三章、X Window 設置介紹
- 23.1 什么是 X Window System
- 23.2 X Server 配置文件解析與設置
- 23.3 顯卡驅動程序安裝范例
- 23.4 重點回顧
- 23.5 本章習題
- 23.6 參考資料與延伸閱讀
- 第二十四章、Linux 核心編譯與管理
- 24.1 編譯前的任務:認識核心與取得核心源代碼
- 24.2 核心編譯的前處理與核心功能選擇
- 24.3 核心的編譯與安裝
- 24.4 額外(單一)核心模塊編譯
- 24.5 以最新核心版本編譯 CentOS 7.x 的核心
- 24.6 重點回顧
- 24.7 本章習題
- 24.8 參考資料與延伸閱讀