2019年8月30日 星期五

General-Purpose Event (GPE)


本篇文章參考
ACPI Specification Version 6.3
Vol. 1: Intel® 200 and Z370 Series Chipset Families PCH
Vol. 2: Intel® 200 and Z370 Series Chipset Families PCH

Fixed ACPI Description Table (FADT)

Field   Byte Length   Byte Offset   Description  
Signature   4   0   'FACP'  
......   ......   ......   ......  
GPE0_BLK   4   80   GPE 0 Register Block 的 port address。
若不support,則值為0。
GPE1_BLK   4   84   GPE 1 Register Block 的 port address。
若不support,則值為0。
......   ......   ......   ......  
GPE0_BLK_LEN   1   92   GPE 0 Register Block 所decode 的bytes 長度。
其值必為2的正指數冪。
GPE1_BLK_LEN   1   93   GPE 1 Register Block 所decode 的bytes 長度。
其值必為2的正指數冪。
GPE1_BASE   1   94   GPE1 events在ACPI general-purpose event中
的offset。GPE0 events 的offset為0。
......   ......   ......   ......  

General-Purpose Event Register Blocks

ACPI spec在 FADT table定義了兩組 GPE register blocks:GPE 0與 GPE 1。register block包含 enable 與 status register (ex:GPE0_EN與 GPE0_STS),這兩個 register長度各佔 register block長度的 一半,所以 FADT中 register block的長度 GPE0_BLK_LEN與 GPE1_BLK_LEN必為 2的冪次。



使用RWEverything讀取GPE Register Block


從 FADT table 中可得 GPE0的 IO port addresss為 0x1880,和其使用的長度為 0x20。


與 Intel PCH spec對照,可從 PMC Controller (D31:F2)的 Offset 40-43h讀出 ACPI Base Address,用 RW讀出其值為 0x1801,bit 1代表為 IO space,所以其 IO address為 0x1800。




與 Spec中的 PMC I/O Based Register 對照,Offset 0x80為 GPE0 block register起始位置,跟 FADT table位置為0x1880 (0x1800 + 0x80) 符合。



再用RW 讀取IO address 0x1880,就可得出GPE0 Register Block位置。若要知道GPE register 每 個bit實際上對應的 GPIO pin,則需參考chipset的相關設定。




GPIO


配置 GPIO用以產生 SCI event

要將 GPIO配置成 GPE的 source,要先將 GPIO配置成可以產生 SCI。需先將 GPI General Purpose Event Enable設起來。

還要配置 Pad Configuration中的 GPIROUTSCI bit。



\_GPE

為ACPI predefined 的namespace,用以處理GPE register block中的General events。



使用RWEverything讀取\_GPE


以我所使用的主機板為例,\_GPE中定義了_E02 的Method,表示其為 handle GPE0_STS bit2 edge event的method。




2019年7月4日 星期四

在Windows 使用gcc - Cygwin


官方網址

http://www.cygwin.com/

Cygwin 可以讓我們在Windows 上執行Liunx或Unix-like的軟體,包含gcc。

要搭建基本的gcc C/C++開發環境,除本身預設安裝的套件外,需額外安裝幾個套件
  Categories    Package     Description  
Develgcc-coreGNU Compiler Collection (C, OpenMP)
Develgcc-g++GNU Compiler Collection (C++)
DevelmakeThe GNU version of the 'make' utility
Develbinutils GNU assembler, linker and similar utility
Develgdb The GNU debugger


test.c

#include <stdio.h>
int main() {
  printf("Hello World!\n");
  return 0;
}


編譯test.c並輸出test.exe
$ gcc test.c -o test

執行test.exe
$ ./test.exe
Hello World!


在Cygwin上安裝新的套件


1. 執行原本安裝時所使用的安裝檔(如果遺失就直接重新下載)。


2. 選擇"Download Without Installing",只下載套件不安裝。並在「Select Local Package Directory」的頁面中選擇之前安裝套件所使用的資料夾。


3. 接著選擇需要的套件下載。

4. 下載完成後,再執行Cygwin安裝檔,選擇"Install from Local Directory"來從下載好的套件安裝。

5. 在「Select Root Install Directory」選擇先前Cygwin所安裝的路徑。並一樣在
「Select Local Package Directory」的頁面中選擇之前安裝套件所使用的資料夾,
之後找到所選擇的套件進行安裝即可。

2021/07/02 Note: 安裝新套件的步驟2可直接選擇"Install from Internet",相當於步驟3到5。

2019年4月25日 星期四

USB多重開機選單製作工具 - YUMI


官方網址

https://www.pendrivelinux.com
https://www.pendrivelinux.com/yumi-multiboot-usb-creator

YUMI可在USB儲存裝置上建立多重開機選單,目前支援建立Windows 10、Ubuntu等常見OS選
單,也支援像是MemTest86的系統測試工具。


Step 1: 選擇USB磁碟磁區
Step 2: 選擇要加入的OS
Step 3: 選取OS ISO檔的路徑

2019年3月30日 星期六

Beyond BIOS Note - CH2 Basic UEFI Architecture


I believe in standards. Everyone should have one.
- George Morrow

UEFI System table

  • UEFI Boot Services
  • UEFI Runtime Services
  • Protocol Services

Handle Database

由Handle 與Protocol 組成,Handle 是Protocol 的集合,而Protocol 則是以GUID 識別的資
料結構,用來提供系統的資訊及服務。

在UEFI系統初始階段,由UEFI Driver 建立Handle 並且安裝一個或多個Protocol 在其上,而
這些Handle會被記錄在由系統韌體所管理的Handle database 中。

Protocol

  • Driver
  • 在系統初始階段會根據系統的需求來建立相關的Protocol。

  • Protocol
  • 以GUID 為識別,為包含function pointer 與data 的結構。

  • Working with Protocols
  • Handle database 在ExitBootServices() 之後就無法使用。

  • Multiple Protocol Instances
  • Driver 會安裝特定Protocol 的多個instance在不同的handle 上。例如PCI bus driver
    會負責安裝PCI I/O Protocol在不同的Device Handle上,這些instance 包含PCI
    Device獨有的數值,像是Option ROM的位置及Size。

  • Tag GUID
  • Protocol可以不包含任何東西,僅用Protcol GUID作識別用,可以方便系統找到特定的Handle。

UEFI Images

UEFI image by processor type

  • UEFI applications
  • 在Application exit之後,image其使用的記憶體將會被系統回收。

  • UEFI Boot Service drivers
  • 在ExitBootServices ()之後,image其使用的記憶體將會被系統回收。

  • UEFI Runtime drivers
  • 在ExitBootServices ()之後依然存在,可以被UEFI OS執行。

Start an UEFI image

  1. gBS->LoadImage()
  2. gBS->LoadImage() 的流程
    1. Allocate image所要被加載的記憶體位置
    2. Relocation fix-up
    3. 在Handle database建立一個image handle,並且安裝
      EFI_LOADED_IMAGE_PROTOCOL 的Instance。

  3. gBS->StartImage()

Image entry point

Image 的entry point會接收到兩個參數
  • Image 所在的Hangle
  • 讓 Image能知道從哪裡被加載及加載後的記憶體位置。

  • 指向 UEFI System Table的指標
  • 讓Image 可以調用UEFI 系統服務。

OS Loader

在OS Kernel取得控制權之前,由OS Loader負責去呼叫ExitBootServices()。

Event and Task Priority Levels

一個Event可以被create或者destroy,且只能是signaled state或waitiing state其中一種狀態。
最常見的應用是讓UEFI driver使用timer event來輪詢(polling)需要服務的device。

Elements associated with Event

  • Notification function
  • Wait Event在waited upon及Signal event從waiting state變成signaled state時所執
    行的function。

  • Notification context
  • 傳入Notification function的參數。

  • Task Priority Level(TPL)
  • Notification function的優先執行順序(priority)
    • TPL_APPLICATION
    • TPL_CALLBACK
    • TPL_NOTIFY
    • TPL_HIGH_LEVEL
    當多個event都在signaled stated時,會依TPL來執行notification function。而TPL 較高的event會中斷TPL較低的event。

    Driver在可以暫時提高TPL來避免其他的event衝出造成使用相同的data structure而衝突。


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

2018年10月22日 星期一

[VSCode] Code Snippet 程式碼片段


Visual Studio Code有提供Code Snippet的功能,讓使用者可以透過自己設定的關鍵字, 來快速產出程式碼的片段,提升開發的效率及方便性。

使用者程式碼片段


程式碼片段的設定在 "檔案 -> 喜好設定 -> 使用者程式碼片段"


Code Snippet可以分別對不同的程式語言做設置,讓使用者能針對不同的開發環境使用相應的
程式碼片段。此外,也能設置在全域環境使用的Code Snippet。



設定方法


Code Snippet是透JSON檔案來進行設置,以Python語言為例,設置Python Code Snippet的
JSON檔案就名為python.json。JSON的每個物件就代表一個程式碼片段。


以"Print to console"為例,prefix的值"prt"即為產出此Code Snippet的關鍵字。


prefix - 關鍵字
body - 產出內容
  $1, $2... - tab stop
  $0 - 游標最後停留處
  ${1:Label1}, ${2:Label2}... - 游標選取文字
description - 說明文字

2018年10月15日 星期一

檔案加密軟體 - AxCrypt


官方網址

https://www.axcrypt.net

測試系統

Windows 10

使用版本

AxCrypt2.1.1560.0

AxCrypt 為一套開源的檔案加密軟體,有釋出免費、付費及商用版本。
其免費版本就含有使用AES-128的檔案加解密功能。

安裝完成後,AxCrypt 會要求使用者提供帳密來做加解密使用。
接者,就可在所要加密的檔案上按下右鍵,選擇功能表中的AxCrypt來加密檔案。



AxCrypt會將加密過的檔案顯示在其列表中。



使用者也可以"右鍵 -> Remove from list but keep file secured" 來移除列表的檔案但保持其加密的狀態。



若要在其他裝置使用加密檔案,只需在該裝置上安裝AxCrypt,並使用同組帳密登入即可。

2018年9月13日 星期四

[Python] 套件管理程式 - pip


pip 是Python內建的套件管理的程式,用來安裝及管理Python的套件


pip install


安裝套件 pip install [MODULE_NAME]
安裝套件的特定版本 pip install [MODULE_NAME]==Version
更新套件至最新版本 pip install --upgrade [MODULE_NAME]
參考requirements.txt檔案安裝套件 pip install -r requirements.txt

pip show


顯示套件資訊 pip show [MODULE_NAME]

pip freeze


以requirements的形式顯示安裝的套件 pip freeze

pip uninstall


解除安裝套件 pip uninstall [MODULE_NAME]


保存套件的開發環境
可搭配virtualenv在乾淨的套件環境中使用

1. 使用pip freeze取出當前開發環境所使用的套件 python -m pip freeze > requirements.txt

2. 再用requirements.txt安裝開發環境的套件 python -m pip install -r requirements.txt

2018年8月27日 星期一

[Pythonic] 迴圈計數應用 enumerate()


在Python中,for迴圈可用來遍訪字串、串列等iterator,若要計算迴圈的數量,可在迴圈
中用counter來記錄。



seq = ["one", "two", "three", "four", "five"]
counter = 0
for e in seq:
  print (counter, e)
  counter += 1


1 one
2 two
3 three
4 four
5 five

另外還有比較Pythonic的寫法,就是使用enumerate (sequence, [start=0]) 函數。
sequence代入iterator,start則為起始位置。


seq = ["one", "two", "three", "four", "five"]
for idx, e in enumerate(seq):
  print (idx, e)


1 one
2 two
3 three
4 four
5 five


2018年8月7日 星期二

建置 Windows Debugger(WinDbg) 環境 via USB 3.0 cable

本篇文章參考
Debugging Tools for Windows

Preparation

Host Computer (with USB3.0 port)
  - windows-10-sdk
Target Computer (with USB3.0 Debug port)
USB 3.0 Debug Cable (A-A crossover, no VBus)

Setup Target Computer

1. 使用UsbView.exe來確認該port是否能Debug(Is Port Debug Capable: yes)。

2. 紀錄該port的xHCI Controller的Bus、Device和Function的number。

3. 使用系統管理員權限開啟command prompt,並輸入以下命令
bcdedit /debug on
bcdedit /dbgsettings usb targetname:TargetName
TargetName為自行命名。

4. 將step2 所記下的資訊帶入以下命令
bcdedit /set "{dbgsettings}" busparams b.d.f

5. 重新開機。

Setup Host Computer

1. 安裝Windows SDK

2. 安裝WinDbg的USB driver
(預設路徑:C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\usb)


使用WinDbg

1. 開啟WinDbg
(C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe)

2. 點選"File" > "Kernel Debugging"

3. 標籤頁切換到"USB",並輸入Setup Target Computer step 3的TargetName


3. 按下確定,開始執行WinDbg


設定Symbols

https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/symbol-path

.sympath
設定Debugger所要參考的symbol file的位置。

.sympath srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols 使用Microsoft Public Symbol Server https://msdl.microsoft.com/download/symbols 所提供的symbol並把local端的c:\MyServerSymbols 用來存放symbols。

或使用 "File" > "Symbol File Path ..." (Ctrl+S) 來設定。


2020/06/02 Note
最近嘗試用這樣的方式設symbol path會遇到ERROR_INTERNET_CANNOT_CONNECT無法 load symbol的情況。
所以參考how-to-specify-symbol-file-locations-from-the-command-line的方式,將
_NT_SYMBOL_PATH設成系統的環境變數,就能正常load到symbol。


Modules

lm
列出已載入的Modules

m PATTERN - 指定符合PATTERN的Module
ex: lm m a* 為列出所有a開頭的Modules

.reload
重新從Symbol Path載入Modules