2017年11月24日 星期五

ROM之於PCI

ROM的目的:裝置可以在啟動程序中被使用

為了啟動OS到記憶體中,系統需要三個裝置:

  • 用來從其中載入OS的大量儲存媒體。這有時也稱為IPL(Initial Program Load,初始程式載入)裝置,通常是一個IDE或SCSI硬碟。
  • 在啟動過程中,用來顯示進行中訊息的顯示配接卡。通稱為輸出裝置。
  • 在啟動過程中,用來讓使用者與機器交談的鍵盤。通稱為輸入裝置。
OS必須同時找到這三個裝置,同時必須找到與每一個裝置有關的裝置驅動程式。這個階段還未從磁碟機載入任何可載入的裝置驅動程式到記憶體中。這是ROM存在的主因。它包含允許裝置在啟動過程中被使用的裝置驅動程式。

ROM偵測

當組態軟體正在組態PCI功能時,它會檢查設計者是否實作擴充ROM基底位址暫存器的方式,決定是否有功能特定的ROM存在。

程式執行裝置下列方式,確認裝置是否存在:

  • 指定一"基底位址"給暫存器的基底位址欄位,
  • 致能其解碼器(以設定暫存器的位元0為1的方式),
  • 設定功能指令暫存器的記憶體空間位元,
  • 然後嘗試去讀取ROM的前兩個位置。

假如前兩個位置包含ROM簽名,AA55h的話,則ROM存在。


ROM Shadowing的必要

  • PCI規格要求裝置ROM程式碼不能在原地執行(即在ROM裡面)。它必須被複製到主記憶體裡面。這稱為"Shadowing"ROM程式碼。這要求的存在有兩個原因:

ROM的存取時間通常很慢,每次讀取ROM程式碼來執行都會造成極差的效能。

  • 一旦在ROM裡裝置驅動程式的初始化程式碼部分被執行後,它就可以被丟棄,並且在主記憶體裡的程式碼影像(code image)可以被縮短到只剩執行期操作所需要的部分。配置給儲存程式碼的初始化部分之主記憶體可以被釋放,使得主記憶體的使用更有效率。
一旦發現裝置ROM存在,組態軟體必須複製程式碼影像到主記憶體中,然後關閉(Disable)ROM位址解碼器。在非PC環境裡,儲存程式碼影像副本的記憶體區域可以在4GB空間的任何一處。該環境所用的規格可以定義一個特定的區域給程式碼影像。

在PC環境裡,ROM程式碼影像必須被複製到主記憶體裡與裝置ROM在歷史上有相關聯的位址範圍內:000C0000h 到 000DFFFFh。假如類別碼表示這是一個VGA的裝置ROM,則其程式碼必須被複製到000C0000h位置最開始的地方。


BIOS呼叫不同匯流排環境的匯流排列舉器(Bus Enumerator)

一個機器架構裡面可以含有許多種不同的裝置環境。例如PCI、CardBus、EISA、Plug-and-Play、ISA等等。用來存取每一個與這些不同裝置種類相關的組態暫存器的方法彼此間有很大的差異。以外,其組態暫存器的配置和格式也有相當大的差異。

BIOS會含有每一個環境所需的一個單獨的、匯流排特定的程式。這程式經常被稱為匯流排列舉器(Bus Enumerator)。匯流排列舉器知道:

  • 如何存取特定型態裝置(例如:PCI裝置)裡的組態暫存器。
  • 如何找到在這環境裡的裝置。例如,在PCI環境裡,程式執行裝置讀取PCI功能製造商識別碼暫存器裡的製造商識別碼。任何非FFFFh的值代表有效的識別碼,而FFFFh代表在目前的定址的位置上沒有任何裝置存在。
  • 如何探測裝置的組態暫存器,以便找到裝置的資源需求。
  • 如何配置已選定的資源給裝置。

系統BIOS必須呼叫每一個所支援之平台匯流排環境的匯流排列舉器。每當特定的列舉器被呼叫時,它會找到所有其target環境裡的裝置,找到每一個裝置所需的資源,並且將不互相衝突的資源配置給每一個裝置。不過,它不會致能這些裝置。列舉器在記憶體內建立一個資料結構,列出它所找到屬於其形態的所有裝置。然後,它將指向該資料結構開頭的指標傳回給系統BIOS。

BIOS選擇啟動裝置並找到它們的驅動程式

接著,系統BIOS掃描資料結構,找出輸入裝置、輸出裝置、以及一個IPL裝置,以便在啟動OS到記憶體時使用。為了在啟動程序裡,使用這些裝置,因此需要有每一個裝置的裝置驅動程式。驅動程式可以內嵌在BIOS本身裡面,或是在所找到的每一個裝置的ROM裡面。

對這三個啟動裝置的每一個說,BIOS接下來會:
  • 呼叫在裝置驅動程式裡的初始化程式碼。接著,初始化程式碼完成使用裝置的準備
  • 然後,BIOS設定在組態指令暫存器裡適當的位元(EX記憶體空間;IO空間;Bus Master),致能此裝置,並讓它上線。

BIOS啟動隨插即用OS並將指標傳給它

然後,系統BIOS使用這三個裝置,啟動OS到記憶體內,並且將控制權傳給OS。它同時把指向這資料結構清單開頭的指標傳給OS,這資料結構用來確認所有OS必須操作的裝置。
OS找到並載入驅動程式,然後呼叫每一個裝置的初始化程式碼(Init Code)
請注意,Init Code(初始化程式碼)代表驅動程式的初始化部分。其次,OS找出每一個裝置在磁碟上的驅動程式,然後將它們一個接著一個地載入到記憶體內。每當它載入一個驅動程式時,它就會呼叫其初始化程式碼進入點,而驅動程式會完成裝置特定的設定,並且讓裝置上線。如此,機器便完成啟動並開始運作,從這一刻起,由OS來管理系統裝置。

沒有留言:

張貼留言