追踨法蘭克

2012年4月27日 星期五

以BIOS的角度看PC架構

PC的發展已經有二、三十年,它的架構簡單的可以分為CPU、Memory、I/O和許多Chipset與Bus所組成,這裡不會介紹太多,將以BIOS的角度去看它。

CPU: 內部為ALU、CU、Register, 有許多暫存器,如AX, BX, CX, DX, CS, DS, IP, ES, SI, DI和旗標暫存器,每個暫存器都有它的作用,它們會依機械碼的來做邏輯和運算,旗標則顯示它們
運算的一些結果。CPU可以運作在不同模式,Real mode、Big Real mode、Protected mode和System Management mode, 這幾個mode的差別為:

Real mode: 運作在16 位元環境,用segment-offset的定址方式,它只能定址到1MB以下的 Memory,所以在這個模式,程式和資料都放在1MB Memory以下。

Big Real mode: 運作在16位元環境,也是用segment-offset定址方式,A20打開後可以定址到4GB,但程式還是只能放在1MB以下,1MB~4GB之間的記憶體可以放資料。

Protected mode: UEFI可以運作在這個模式下,和以前的Legacy BIOS不同,它運作在32位元環境,可以定址到4G的Memory,程式和資料都可以放在1MB~4GB之間的記憶體來動作。

System Management mode: 這個模式比較特別,只有在發出SMI的時候也會進入這個模式,用來處理一些特別的事件,它中斷的優先權很高屬於CPU中斷(比一般硬體中斷高),它所使用的記憶體也是其他模式下不能存取的。SMM 的處理程式將會放在SM RAM,也就是T-segment的地方,在進入SMM時會把CPU原先暫存器的值先備份在SM RAM中,直到SMM程式結束後再回存至暫存器裡,以便CPU繼續執行原先的程式。


Memory: 也就是RAM,只有CPU的暫存器是不能做太多事情的,記憶體存放了程式和資料,在CPU運作時,會在Memory和CPU 暫存器之間做許多運算和搬移的動作,來達到程式想做的事情。MMIO,Memory Mapped-IO,利用Memory位置來代表I/O的位置,一般是不會設定在可存放資料的Memory範圍內,假如插了4G,那麼MMIO就在4G以上,這些MMIO的位置設定在BIOS階段都會設定好。

I/O: 這是比較慢的週邊裝置,當這些裝置需要運作時,會透過中斷控制器8259跟CPU溝通,發出中斷需求,然後交由給中斷服務常式,執行完服務的程式後,再回到CPU原先做的事情。I/O space的定址為legacy mode: 0~0x3FF, native mode: 0~0xFFFF.(I/O address就是用代表I/O裝置的位置,和記憶體的位址是不一樣的,它有自己的address space)

Chipset: 這邊每一代的Chipset都不盡相同,但大致都可以分為South Bridge、North Bridge和許多控制器。North Bridge主要是處理CPU、記憶體的運作和VGA顯示,這是比較高速的裝置。South Bridge下連接的有一般的PCI/PCI-E裝置、SATA、USB、Audio和LPC介面,這些都是比較低速的裝置。 Low Pin Count連接的是許多pin腳較少的介面,速度也不快的週邊會接在這裡,一般會在有個控制器來控制其週邊設備,控制器如Super I/O、EC/KBC,週邊裝置如TPM、80 port等。

Bus: 這裡會介紹PCI和PCI-E的PCI Configuration space、addressing的算法。

PCI Configuration space: 0~0xFF甚至更多,它列出了PCI裝置的許多屬性,可以在BIOS階段來設定它,有些則可以在OS階段設定,有些是HW廠商去設定之。0~4 offset是Vendor ID和Device ID,如下圖.




PCI address: 它的位址由Bus/Device/Function/Register所組成,由PCI spec所定義,一個PCI Function address代表著一個Deivce,都有一個PCI Configuration space以表示它的屬性。
計算方式:
PFA = Bus(8 Bits) / Device/Function (5 + 3 Bits)/ Register (8 Bits) + PCI Base address(MMIO 位址) 共32 Bits, Bit 0和Bit 1 為read only = 0.
  範例: Bus = 0x01, Device = 0x10, Function: 0x2, PCI Base Address: 0x80000000
            請讀取該裝置的Register 0x05 = ? (PCI addres port: 0xCF8, PCI data port: 0xCFC)
       Device Function 共8bit = 0x82 (<==不會算請自己轉二進制:10000 10)
                                                                                                                    dev   fun
  ∴ PFA = 0x80000000 + (0x018204)
  經過簡單的計算 PFA = 0x80018204, 因為Bit 0, 1是read only 所以始終為0
    pesudo code:

    mov eax, 0x80012204
    mov dx, cf8
    out dx, eax
   
    mov dx, cfd ;位址Reg是0x04,要讀的是0x05,剛好0xCFC port + 1的位址,所以可以直接讀cfd值
    in al


PCI-E的Register多了4 Bits,算法和PCI一樣,但是只能用MMIO的方式來存取。
 範例: Bus = 0x00, Device = 0x1F, Function: 0x0, (PCI-E Base Address: 0xF0000000)
            讀取Register 0x100.
         PFA = 0xF0000000 + (0x00F8100) = 0xF00F8100
          pesudo code:
          
          mov eax, 0xf00f8100
          mov esi, eax
          mov al, ds:[esi]        ;Read byte value to al

沒有留言:

張貼留言