2020年9月19日 星期六

DISM - Windows 映像檔佈署工具

DISM 是Windows下用以佈署映像檔的工具。

/Split-image

將 .wim檔分割為多個 WIM(.swm)檔案。以 /FileSize來指定 .swm檔的檔案大小上限。
/CheckIntegrity 用以偵測並追蹤 WIM檔案毀損狀況。

dism /Split-Image /ImageFile:"<WIM_PATH>" /SWMFile:"<SWM_PATH>"
/FileSize:<MB> [/CheckIntegrity]


分割 install.wim
在製作 Windows USB開機隨身碟時,會遇到 install.wim檔案大小大於 4GB的情況。
目前 UEFI系統只支援 FAT32格式,而 FAT32有單一檔案大小不能超過 4GB的限制,
所以如果要不透過其他工具直接製作 USB開機碟,可以將 install.wim分割成多個
檔案來避開限制,使用分割出的 .swm檔取代原本的 .wim檔。


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年8月30日 星期日

USB多重開機選單製作工具(2) - Ventoy


官方網址

https://www.ventoy.net
https://github.com/ventoy

與前篇介紹的YUMI一樣,Ventoy也是製作USB多重開機選單的工具,但是使用上我覺得更
方便,只需要製作完Ventoy的USB碟,就可以直接把ISO檔放進USB空間中使用。


Install: 製作Ventoy的開機USB碟

Update: 更新USB碟的Ventoy版本

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)以下的記憶體。

2020年6月12日 星期五

[Batch] 移除數字的前置0


Example: 移除0120的前置0
@set var=0120

@for /f "tokens=* delims=0" %%a in ("%var%") do @set var=%%a
@if "%var%"=="" set var=0

@echo %var%

Output:
120

2020年6月1日 星期一

[VSCode] 相關檔案預設位置


記錄VS code 相關檔案的預設存放位置

setting.json

C:\Users\%USERNAME%\AppData\Roaming\Code\User\settings.json

Workspace storage

C:\Users\%USERNAME%\AppData\Roaming\Code\User\workspaceStorage

Code snippet

C:\Users\%USERNAME%\AppData\Roaming\Code\User\snippets

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而衝突。