IES101 嵌入式系統基本軟體技術
(1)嵌入式系統的基本程式語言技術-----------------------------------------------------------------------------------------------------------------
1-01 ----------------------------------------------------------------------------------------------------------
BIOS(Basic Input/Output System的縮寫、中文:基本輸出輸入系統),是載入在電腦硬體系統上的最基本的軟體程式碼。BIOS這個字眼是第一次由CP/M作業系統中出現,描述在開機階段載入CP/M與硬體直接溝通的部份。(CP/M機器通常只有ROM裡面的一個簡單開機載入程式)最早的DOS版本有個檔案叫做"IBMIO.COM"或是"IO.SYS",類似於CP/M的軟碟BIOS。
BIOS技術源於IBM PC/AT機器的流行以及第一台由康柏公司研製生產的「克隆」PC。在PC啟動的過程中,BIOS擔負著初始化硬體,檢測硬體功能,以及引導作業系統的責任。在早期,BIOS還提供一套執行時的服務程式給作業系統及應用程式使用。BIOS程式存放於一個斷電後內容不會丟失的唯讀記憶體中;系統過電或被重置 (reset)時,處理器第一條指令的位址會被定位到BIOS的記憶體中,讓初始化程式開始執行。英特爾公司從2000年開始,發明了可延伸韌體介面(Extensible Firmware Interface),用以規範BIOS的開發。而支援EFI規範的BIOS也被稱為EFI BIOS。之後為了推廣EFI,業界多家著名公司共同成立了統一可延伸韌體介面論壇(UEFI Forum),英特爾公司將EFI 1.1規範貢獻給業界,用以制訂新的國際標準UEFI規範。目前UEFI規範的最新版本是2.1b,而根據來自英特爾公司的預測,到2010年,全世界將有60%以上的個人電腦使用支援UEFI規範的BIOS產品。
[] 啟動電腦原理
當電腦的電源開啟,BIOS就會由主機板上的快閃記憶體(flash memory)執行,並將晶片組和記憶體子系統初始化。BIOS會把自己從快閃記憶體中,解壓縮到系統的主記憶體;並且從那邊開始執行。PC的BIOS程式碼也包含診斷功能,以保證某些重要硬體元件,像是鍵盤、軟碟裝置、輸出輸入埠等等,可以正常運作且正確地初始化。幾乎所有的BIOS都可以選擇性地執行CMOS記憶體的設定程式;也就是保存BIOS會存取的使用者自訂設定資料(時間、日期、硬碟細節,等等)。IBM技術參考手冊中曾經包含早期PC和AT BIOS的80x86原始碼。
[] BIOS韌體
由於BIOS與硬體系統整合在一起(將BIOS程式指令燒錄在IC中),所以有時候也被稱為韌體。在大約1990年BIOS是保存在ROM(唯讀記憶體)中而無法被修改。因為BIOS的大小和複雜程度隨時間不斷增加,而且硬體的更新速度加快,令BIOS也必須不斷更新以支援新硬體,於是BIOS就改為儲存在EEPROM或者快閃記憶體中,讓使用者可以輕易更新BIOS。然而,不適當的執行或是終止BIOS更新可能導致電腦或是裝置無法使用。為了避免BIOS損壞,有些新的主機板有備份的BIOS(「雙BIOS」主機板)。有些BIOS有「啟動區塊」,屬於唯讀記憶體的一部份,一開始就會被執行且無法被更新。這個程式會在執行BIOS前,驗證BIOS其他部分是否正確無誤(經由檢查碼,湊雜碼等等)。如果啟動區塊偵測到主要的BIOS已損壞,通常會自動由軟碟機啟動電腦,讓使用者可以修復或更新BIOS。一部份主機板會在確定BIOS已損壞後自動搜尋軟碟機看看有沒有完整的BIOS檔案。此時使用者可以放入儲存BIOS檔案的軟碟(例如由網上下載的更新版BIOS檔案,或是自行備份的BIOS檔案)。啟動區塊會在找到軟碟中儲存的BIOS檔案後自動嘗試更新BIOS,希望以此修復已損壞的部份。硬體製造廠商經常發出BIOS升級來更新他們的產品和修正已知的問題。
-----------------------------------------------------------------------------------------------------------------
1-02 ----------------------------------------------------------------------------------------------------------
在讀 Linux Permier 中文版的時候. Page 2-41 有一段
使用 likely() 與 unlikely() 巨集透過編譯器告知 CPU 有哪些程式區段不需要預測(likely)或有哪些程式區段需要預測(unlikely).
likely/unlikely
在 Kernel 中用來優化分支指令的巨集 (Macro)。考慮以下程式碼:
if( likely(blah) ) {
blah blah blah...
}
else {
blah blah blah...
}
此段程式碼代表 if 區段比較有可能發生,所以在轉換成組合語言時就會針對 if 條件最佳化。
詳情請見 Kernel : likely/unlikely macros : http://kerneltrap.org/node/4705
在 Kernel 中用來優化分支指令的巨集 (Macro)。考慮以下程式碼:
if( likely(blah) ) {
blah blah blah...
}
else {
blah blah blah...
}
此段程式碼代表 if 區段比較有可能發生,所以在轉換成組合語言時就會針對 if 條件最佳化。
詳情請見 Kernel : likely/unlikely macros : http://kerneltrap.org/node/4705
-----------------------------------------------------------------------------------------------------------------
1-03 ----------------------------------------------------------------------------------------------------------
基本概念題
-----------------------------------------------------------------------------------------------------------------
1-04 ----------------------------------------------------------------------------------------------------------
kernel 裡的 system call 實作函數中(C 函數),為什麼每一個函數原型宣告的前面都有一個 "asmlinkage" 的字串?例如:
asmlinkage long sys_nice(int increment)
"asmlinkage" 是在 i386 system call 實作中相當重要的一個 gcc 標籤(tag)。
當 system call handler 要呼叫相對應的 system call routine 時,便將一般用途暫存器的值 push 到 stack 裡,因此 system call routine 就要由 stack 來讀取 system call handler 傳遞的參數。這就是 asmlinkage 標籤的用意。
system call handler 是 assembly code,system call routine(例如:sys_nice)是 C code,當 assembly code 呼叫 C function,並且是以 stack 方式傳參數(parameter)時,在 C function 的 prototype 前面就要加上 "asmlinkage"。
加上 "asmlinkage" 後,C function 就會由 stack 取參數,而不是從 register 取參數(可能發生在程式碼最佳化後)。
更進一步的說明...
80x86 的 assembly 有 2 種傳遞參數的方法:
1. register method
2. stack method
2. stack method
Register method 大多使用一般用途(general-purpose)暫存器來傳遞參數,這種方法的好處是簡單且快速。另外一種傳遞參數的做法是使用 stack(堆疊),assembly code 的模式如下:
push number1
push number2
push number3
call sum
push number2
push number3
call sum
在 'sum' procedure 裡取值的方法,最簡單的做法是:
pop ax
pop ax
pop bx
pop cx
pop ax
pop bx
pop cx
Stack Top 是放 IP,我們傳給 sum procedure 的參數由 stack 的後一個 entry 開始讀取。
-----------------------------------------------------------------------------------------------------------------
1-05 ----------------------------------------------------------------------------------------------------------
NOP
電腦科學中,NOP或NOOP(No Operation或No Operation Performed的縮寫,意為無操作)是組合語言的一個指令,一系列編程語句,或網路傳輸協議中的表示不做任何有效操作的命令。
[] NOP機器指令
有的電腦指令集包含一條指令,其主要目的是不改變任何程式可存取的暫存器,處理器狀態標誌或主記憶體,而且可能需要特定的時鐘周期來執行。在其它指令集中,NOP是用執行一條具有運算元,具有相同效果的指令來類比的(例如SPARC處理器推薦使用sethi 0, %g0類比NOP)。
NOP指令通常用於控制時序的目的,強制記憶體對齊,防止流水線災難,佔據分支指令延遲),或是作為佔位符以供程式的改善(或替代被移除的指令)。在某些情況中,NOP指令會產生副作用;例如在摩托羅拉 68000處理器中,NOP操作碼會產生流水線同步[1]。
-----------------------------------------------------------------------------------------------------------------
1-06 ----------------------------------------------------------------------------------------------------------
副程式/子程式(subroutine)
在電腦科學中,子程式(英語:Subroutine, procedure, function, routine, method, subprogram),是一個大型程式中的某部份程式碼,由一個或多個語句塊組成。它負責完成某項特定工作,而且相較於其他程式碼,具備相對的獨立性。
[] 分類
c = max (a,b);
程式(procedure)是一種子程式,它能夠接受不同的引數,來執行某些特別的動作。例如:
printf("Hello World\n") ;
巨集(Macro),中國稱為宏,是一種批次批次處理的稱謂。
電腦科學裡的巨集是一種抽象(Abstraction),它根據一系列預定義的規則替換一定的文字模式。直譯器或編譯器在遇到巨集時會自動進行這一模式替換。對於編譯語言,巨集展開在編譯時發生,進行巨集展開的工具常被稱為巨集展開器。巨集這一術語也常常被用於許多類似的環境中,它們是源自巨集展開的概念,這包括鍵盤巨集和巨集語言。絕大多數情況下,「巨集」這個詞的使用暗示著將小命令或動作轉化為一系列指令。
巨集的用途在於自動化頻繁使用的序列或者是獲得一種更強大的抽象能力——但這常常是一回事。
Lisp類語言如Common Lisp和Scheme有更精巧的巨集系統: 巨集的行為如同是函式對自身程式文字的變形,並且可以應用全部語言來表達這種變形。一個 C 巨集可以定義一段語法的替換,然而一個 Lisp 的巨集卻可以控制一節代碼的計算。
獲得了控制代碼的執行順序(見惰性計算和非限制函式)的能力,使得新建立的語法結構與語言內建的語法結構不可區分。例如,一種 Lisp 方言有 cond 而沒有 if ,就可以使用巨集由前者定義後者。Lisp 語法的去部主要擴充功能,比如物件導向的 CLOS 系統,可以由巨集來定義。
MacroML有型別語法巨集,一種有效的理解方式是把這種語法巨集看作是多階段計算。
-----------------------------------------------------------------------------------------------------------------
1-07 ----------------------------------------------------------------------------------------------------------
??
-----------------------------------------------------------------------------------------------------------------
1-08 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-09 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-10 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-11 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-12 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-13 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-14 ----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
1-15 ----------------------------------------------------------------------------------------------------------
沒有留言:
張貼留言