顯示具有 X86 標籤的文章。 顯示所有文章
顯示具有 X86 標籤的文章。 顯示所有文章

2021年11月23日 星期二

[X86] Real Mode to Protected Mode


參考來源:
Intel 64 and IA-32 Architectures Software Developer Manuals
AMD64 Architecture Programmer's Manual

System Reset後,BIOS在 SEC階段一開始就會從 Real Mode切換到 Protected Mode。
切換 Protected Mode前,BIOS最少要設定 GDTR及 Control Registers。

GDTR
透過 lgdt命令將 ROM中寫好的 table載入 GDT中,

Control Register
Enable CR0的 PE flag


2021年10月5日 星期二

[X86] Reset Vector


參考來源:
Intel 64 and IA-32 Architectures Software Developer Manuals
AMD64 Architecture Programmer's Manual

當前 x86架構下,CPU第一個指令執行位置是從 0xFFFF_FFF0開始。但 CPU啟動時是 Real

Mode,照理說只能定址到 1MB位置。所以其是透過 segment register(CS)中 invisible register

的機制來達成。

一般情況下 CS的 Base值會是 Selector左移 4 bits的值,但 CPU初始時會將 CS的 Selector及

Base設成 0xF000和 0xFFFF_0000。由於 EIP初始的值為 0xFFF0,如此將初始位置指向

0xFFFF_FFF0 (0xFFFF_0000 + 0xFFF0)。


0xFFFF_FFF0 是 ROM映射的位置,所以 BIOS會將 Reset Vector程式碼放在與之相應的位置。

以16 MB(0x100_0000)的BIOS來說,其會映射在0xFF00_0000 - 0xFFFF_FFFF


用 RWEverything實際看機器上 0xFFFF_FFF0位置的值

其 machine code為0x90 0x90 0xE9,後面則是 16 bits jmp address(0xC39B)。

可與EDK2中 Reset Vector程式碼對照 UefiCpuPkg\SecCore\Ia32\ResetVec.nasmb

;
; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte
; Execution starts here upon power-on/platform-reset.
;
ResetHandler:
  nop
  nop
ApStartup:
  ;
  ; Jmp Rel16 instruction
  ; Use machine code directly in case of the assembler optimization
  ; SEC entry point relative address will be fixed up by some build tool.
  ;
  ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in
  ; SecEntry.asm
  ;
  DB 0e9h
  DW -3

在兩個 nop後,接 near jump 0xE9,來確保 CS selector的值不會被改變。後面預留 DW

會由 build tool來填入 SEC進入點的位址。

上圖RW看到的位址是 0xC39B,此值與當前的 IP值 0xFFF5 (0xFFFF_FFF5)相加,就能找到

SEC的進入點在 0xFFFF_C390的位置。

開始的指令為0xDB 0xE3,是 FNINIT的 machine code。

2021年9月16日 星期四

[X86] Memory Paging


參考來源:
Intel 64 and IA-32 Architectures Software Developer Manuals
AMD64 Architecture Programmer's Manual
The Intel Microprocessors by Barry B.Brey

Paging Registers


Paging行為主要由 control register所控制。


若CR0的 PG(Paging)=0,程式所使用的 linear address就是 physical address。

PG=1,則 linear address會透過 Paging的機制轉換成 physical address。


CR3的PCD(Page-level Cache Disable)與 PWT(Page-level Write-Through) bit控制Page

Directory 的 cache type。

PCD=0為cachable,PCD=1為not cachable。PWT=0 cache type為 writeback,PCD=1 為

writethrough。

Page-Directory Base指向 Page Directory 的 physical address。


linear addresspage directory entrypage table entrymemory page offset

address組成。page directory entry(10 bits)為 1024(2^10) 個 page directory的 index。

每個 page directory entry可表示 4M的記憶體(1024個page table * 4k)。


而page table entry(10 bits)為 1024(2^10)個 page table的 index。page table會指向某段4K 記憶體。

memory page offset address(12 bits) 為該段 4K記憶體的offset。


2020年11月27日 星期五

[X86] Protected Mode


參考來源:
Intel 64 and IA-32 Architectures Software Developer Manuals
AMD64 Architecture Programmer's Manual
The Intel Microprocessors by Barry B.Brey

相關文章:
Real Mode

Protected Mode相對於 Real Mode,可以定址到 1MB以上的記憶體空間,而原本的 segment register變成用以選擇 descriptor的 selector。
discriptor中描述 memory的 segment 位置、長度與access right。

Protected Mode下,segment register從 descriptor table中指定 descriptor,透過 descriptor
間接地指定 memory segment,相對於在 Real Mode下 segment register是直接指定 memory
segment。


Selectors and Descriptors

descriptor table分為兩種,GDT(Global Descriptor Table)及 LDT(Local Descriptor Table),
每個 descriptor table可以存放 8192個 descriptror。GDT可以被系統中所有程式使用,而
每個程式可能會有自己的 LDT。

descriptor 的格式如下圖,其長度為 8 bytes,所以 descriptor table最大的長度為
64K (8 * 8192)。

其中 Base Address代表segment的起始位址,為32-bit address,可定址到 4GB記憶體位址。
Segment Limit 則為 segment可定址的最高位址。若 Base Address為 0x00F00000而 Segment
Limit為0x000FF,此 segment的範圍就是 0x00F00000 - 0x00F000FF。

G (Granularity) flag沒有被設定,表示Segment Limit為 byte increment,segment的size為1 byte - 1M bytes (0x00001 - 0xFFFFF)。
若 G flag被設定,Segment Limit為 4k bytes increment,則 segment size就是 4k bytes - 4G bytes。

L (Long) bit 只在long mode有效,代表segment在64-bit mode下運行(L=1),或是在
compatibility mode下運行(L=0)。

AV (Available) bit 是給system software使用,代表此segment是否available。

D/B (Default Operation Size) 若D=0,則此 segment中的 instruction都預設使用 16-bit
offset address及register。若D=1,則預設使用32-bit offset address及register。

Type field描述此 segment如何在系統中運作及direction of growth,並根據 code和 data或
system descriptor而有不同的定義。


descriptor 是由segment register在descriptor table中指定。

13-bit index用以指定descriptor table 8192(2^13) decriptor的其中一個。
TI (table indicator)代表 GDT (TI=0)或者 LDT (TI=1)。
RPL (requested privilege level)為要求存取 memory segment的權限。其值 00權限最高,
通常稱為 ring0,11權限最低,通常稱為ring3。
Windows的kernel及driver使用ring0,而一般應用程式通常使用ring3。


Program-Invisible Registers

這些暫存器是隱藏起來,不能被軟體直接使用。像是每個segment register,都有其對應的
program-invisible register。

有些 segment register隱藏起來的部分通常被稱為 "descriptor cache"、 "shadow register"或
"cache memory",此 cache並非 CPU的 L1 L2 cache。
當 segment register指定 segment,segment的 base address、limit及 access right就會被
load進 invisible register。讓處理器可以頻繁的存取 segment而不用去訪問 descriptor table。

GDTR(global descriptor table register)與 IDTR(interrupt descriptro table register) 掌握 descriptor table的 base address與 limit。

LDT的segment會在GDT中的某個descriptor中描述,LDTR則會載入 LDT的 base address、limit
及 attribute。

TR (Task Register)中的selector為visible,而selector會指向GDT其中的TSS descriptor為當前
task的segment。而其invisible的部分cache descriptor的 base address、limit及attribute。

2020年9月9日 星期三

I/O Port Map


0x2E/0x2F
0x4E/0x4F
SuperIO Address/Data Port

0x3F8
COM1(Serial Port 1)

0x2F8
COM2(Serial Port 2)

0x3E8
COM3(Serial Port 3)

0x2E8
COM4(Serial Port 4)

0x60/0x64
KBC
0x60 - Data Port (R/W)
0x64 - Status Register (R)
0x64 - Command Register (W)

0x62/0x66
EC

0x70/0x71
CMOS Index/Data Port

0x72/0x73
Extend CMOS Index/Data Port

0x92
FastInit
bit0 - FastInit
bit1 - A20 Enable Bar bit
bit2-7 - Reserved

0xC00/0xC01
PCI Interrupt Index/Data Port

0xCD4/0xCD5
BIOS Data Area(BIOS RAM) Index/Data Port

0xCD6/0xCD7
Power Management Register Index/Data Port

0xCF8/0xCFC
PCI Config Address/Data Port

0xCF9
System Reset Register

參考來源:
AMD Developer Central
OSDev

2020年6月14日 星期日

[X86] Real Mode


參考來源:
Intel 64 and IA-32 Architectures Software Developer Manuals
AMD64 Architecture Programmer's Manual
The Intel Microprocessors by Barry B.Brey

相關文章:
Protected Mode

Real Mode下是透過segment registeroffset register來定址。
定址方式為:
segment register * 10h + offset register

以CS (code segment)和IP (Instruction pointer)為例,processor以這樣的組合來取得執行
指令的位址。這樣的組合通常寫作CS:IP或者CS:EIP,IP/EIP根據當下的執行 operation mode。

若CS=1400H且IP/EIP=1200H,則processor執行指令位址就是:
1400H * 10H + 1200H = 15200H

另一種組合為Stack,Stack使用SS:SP(SS:ESP)和SS:BP(SS:EBP)來定址。

若SS=2000H且BP=3000H,則Stack的記憶題位址為:
2000H * 10H + 3000H = 23000H

由於此定址方式的限制,在Real Mode下只能定址到1MB (20 bits)以下的記憶體。

2019年3月17日 星期日

Memory Type Range Register (MTRR)

MTRR 為幾組CPU 所提供的MSR 暫存器,用來描述記憶體的區段讓CPU知道該用哪一種
Cache模式來存取。

CPU可用的快取模式為下列幾種
                       
  Memory Type and Mnemonic    Encoding in MTRR  
Uncacheable (UC)00H
Write Combining (WC)01H
Reserved02H
Reserved03H
Write-through (WT)04H
Write-protected (WP)05H
Write-back (WB)06H
Reserved07H-FFH


可藉由讀取CPUID判斷此CPU支不支援MTRR
CPUID Function 0x00000001, EDX
bit 12 - MTRR supported

MTRRCap - MTRR Capabilities

0x000000FE


bit 0-7 (VCNT) - Variable range register 的數量
bit 8 (FIX) - 是否支援Fixed range register
bit 10 (WC) - 是否支援Write Combining的cache type
bit 11 (SMRR) - 是否支援SMRR

MTRR 可以分為兩種,Fixed range register 與Variable range register,1MB記憶體以下位置的
cache 是由Fixed range register來控制,1MB以上就由Variable range register控制,剩下未被
指定的記憶體區塊就由 MTRRdefType (0x000002FF) 的bit0-7 來決定。



MTRRdefType - MTRR Default Memory Type

0x000002FF


bit 0-7 (Type) - 未被MTRR指定的Memory cache type
bit 10 (FE) - Enable Fixed MTRR
bit 11 (E) - Enable MTRR


1MB以下的記憶體由Fixed Range MTRR控制,可分為一組64k、兩組16k和八組4k,每組中可指
定八段range。

MtrrVar_64K

0x00000250

MtrrVar_16K

0x00000258, 0x00000259

MtrrVar_4K

0x00000268 - 0x0000026F


bit 0-3 (Type) - Memory cache type


1MB以上的記憶體可用Variable Range MTRR來控制,由Base與Mask成對組成,並可以指定長
度,其支援的數量可由MTRRCap的VCNT讀出

MtrrVarBase

0x00000200, 0x00000202, ...

bit 0-7 (Type) - 指定range的Memory cache type
bit 12-MAXPHYADDR (PhysBase) - 後面補上3個0,即為base address
  MAXPHYADDR為CPU的定址能力,可從CPUID Function 0x80000008讀出

MtrrVarMask

0x00000201, 0x00000203, ...

bit 11 (V) - 此組MTRR是否有效
bit 12-MAXPHYADDR (PhysMask) - 後面補上3個0,再取2的補數,即為MTRR長度
  Address_Within_Range & PhysMask == PhysBase & PhysMask