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


2018年7月24日 星期二

[ACPI] ASL Operator


本篇文章參考
ACPI Specification Version 6.2 (Errata A)
ACPI Specification Version 5.1 (Errata B)
參考章節為CH19 ACPI Source Language(ASL) Reference

Add

Add(Addend1, Addend2, Result) => Integer
將Addend1與Addend2相加存放到Result。

CreateWordField

CreateWordField(SourceBuffer, ByteIndex, WordFieldName)
在SourceBuffer的ByteIndex Offset建立一個Word長度且名為WordFieldName的Object。

DerefOf

DerefOf(Source) => Object
回傳Source所Reference的Object。

Device

Device(DeviceName) {TermList}
建立一個名為DeviceName的Object,用以代表processor、bus或device等硬體。並會開啟一個name scope。

EISAID

EISAID(EisaIdString) => DWordConst
將形式為"UUUNNNN"(U為大寫字母,N為十六進位數字)的文字字串轉換為4 byte長度的EISA ID數字編碼。

Field

Field (RegionName, AccessType, LockRule, UpdateRule) {FieldUnitList}
可用以代表RegionName中的某段區塊資料。
AccessType為預設存取寬度,可為AnyAccByteAccWordAccDWordAccQWordAcc
FileUnitList的Entry可為下列幾種形式,
FieldUnitName, BitLength - Field Unit所使用的命名與長度。Field Unit用以代表某段資料。
Offect (ByteOffset) - 下個Field Unit的Offset。

Include

Include(FilePathName)
引入其他ASL File。

Index

Index (Source, IndexNum, Destination) => ObjectReference
取得 Source 中第 IndexNum項的 Reference。
如 Source為 Buffer,Index會回傳第IndexNum的byte的Reference。
如 Source為 String,Index會回傳第IndexNum的字元的Reference。
如 Source為 Package,Index會回傳第IndexNum的Object的Reference。

Method

Method (MethodName, NumArgs, SerializeRule, SyncLevel, ReturnType, ParameterTypes) {TermList}
建立一個名為MethodName的control method,並會開啟一個name scope。
NumArgs代表Method的參數數量。為optional如不使用則代表此Method不使用參數,而最多可使用7個參數,參數分別reference到Arg0 - Arg6
SerializeRule可填為SerializedNotSerialized,Serialized代表此Method不會被其他thread同時存取,用以防止產生相同namespace object。若沒有指定則視為NotSerialized

Name

Name(ObjectName, Object)
建立名為ObjectName的Object,並且references到Object。

OperationRegion

OperationRegion(RegionName, RegionSpace, Offset, Length)
宣告名為RegionName的Operation Region,配合Field Object用以讀取系統硬體空間。

PowerResource

PowerResource(ResourceName, SystemLevel, ResourceOrder) {ObjectList}
宣告名為ResourceName的power resource。

Scope

Scope(Location) {ObjectList}
宣告名為Location的namespace,並且ObjectList以Location為參考namespace。
或將目前namespace切換成已存在的namespace。


Beyond BIOS Note - Ch1 Introduction

Chapter 1 Introduction


The suddenness of the leap from hardware to software cannot but produce a period of anarchy and collapse, especially in the developed countries.
- Marshall McLuhan

UEFI - UEFI is about booting, or passing control to successive layer of control

PI - PI describes the phase of control from the platform reset and into the success phase of operation

UEFI在於提供介面來讓其他應用來使用系統服務,而PI則在於規劃系統韌體的流程。


2018年7月17日 星期二

[ACPI] Device Configuration


本篇文章參考
ACPI Specification Version 6.2 (Errata A)
ACPI Specification Version 5.1 (Errata B)
參考章節為CH6 Device Configuration

OSPM 會根據 Configuration Object去管理操作相關的 Device,其大致分為幾個類型:

Device identification objects

_ADR (Address)

提供OSPM此裝置在所屬的Bus上的Address。
Bus   Address Encoding  
PCI   High word - Device Number, Low word - Function Number  
(ex: device 3, function 2 會是 0x00030002)  
若要參照device的所有function,Function Number則使用0xFFFF  
USB Ports   Port Number (1-n )  

Device configuration objects

_DIS (Disable)

用來 disable device。

_PRT (PCI Routing Table)

回傳包含PCI interrupt mapping package列表的package。

Device insertion and removal objects

_RMV (Status)

通知OSPM此裝置是否隨時都為可移除。

_STA (Status)

回傳裝置的狀態,其狀態可為enabled、disabled和removal。
若裝置的Object沒有_STA,則視為設起所有的return bit(present、enabled、shown in UI and functioning)。

Other Objects and Control Methods


_INI (Init)

用來對裝置進行特定的初始化操作,在OSPM加載description table時執行,會根據_STA來決定_INI是否及如何執行。


2018年7月12日 星期四

EDK常見的Macro - CR

在追EDK的Source Code時,會常看見Macro CR()的使用,其意義在於利用某個struct成員的記憶體位址,來獲得該struct的起始記憶體位址, 以此可以在記憶體操作上做更靈活的運用, 通常用於EFI Protocol。


#define CR (Record, TYPE, Field) \
  ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))


Record - Struct成員的記憶體位址
TYPE - Struct所宣告的型態
Field - Struct成員使用的名稱


CR拆解


1. &(((TYPE *) 0)->Field)
取得Struct成員在Struct中的offset

2. (CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)
用Struct成員的實際記憶體位址減去Offset,就可得到Struct的記憶體位址

3. (TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))
再轉型回Struct的宣告型態


2018年7月8日 星期日

使用Visual Studio Community 2017/2019 Build EDK2 on Windows

參考來源
https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems
https://github.com/tianocore/tianocore.github.io/wiki/UDK2018#how-to-build-UDK2018

Source

Visual Studio Community 2017
https://visualstudio.microsoft.com

UDK2018
https://github.com/tianocore/edk2/releases/tag/vUDK2018

Basetools-Win32
https://github.com/tianocore/edk2-BaseTools-win32

Python2.7
https://www.python.org/

Cygwin
https://www.cygwin.com/

NASM
https://www.nasm.us/

iASL
https://acpica.org/downloads/binary-tools

Environment Variable

PYTHON_HOME - Python安裝路徑 (預設C:\Python27)
CYGWIN_HOME - Cygwin安裝路徑 (預設C:\cygwin64)
EDK_TOOLS_BIN - Basetools-Win32路徑
NASM_PREFIX - NASM路徑
IASL_PREFIX - iASL路徑

target.txt

ACTIVE_PLATFORM
指定要build的DSC file的路徑。Ex: Nt32Pkg/Nt32Pkg.dsc。
(build -p Nt32Pkg/Nt32Pkg.dsc)

TARGET
指定build target。Ex: DEBUG RELEASE。
(build -b DEBUG)

TARGET_ARCH
指定使用架構。Ex: IA32 X64。
(build -a X64)

TOOL_CHAIN_TAG
指定Tool Chain的Tagname。Ex: VS2017。
(build -t VS2017)

Setup Reference

Directory Structure

C:\
├ ─ ─ ─ Python27
└ ─ ─ ─ cygwin64
└ ─ ─ ─ Program Files (x86)
    └ ─ ─ ─ Microsoft Visual Studio
        └ ─ ─ ─ 2017
            └ ─ ─ ─ Community

(WORKSPACE)
├ ─ ─ ─ UDK2018
└ ─ ─ ─ edk2-BaseTools-win32
└ ─ ─ ─ iasl-win-20180629
└ ─ ─ ─ nasm-2.13.03
└ ─ ─ ─ (Build-UDK2018)

Build-UDK2018.bat

@echo off

set PYTHON_HOME=C:\Python27
set CYGWIN_HOME=C:\cygwin64

set EDK_TOOLS_BIN=%cd%\edk2-BaseTools-win32
set NASM_PREFIX=%cd%\nasm-2.13.03\
set IASL_PREFIX=%cd%\iasl-win-20180629\

cd .\UDK2018

call edksetup.bat
cmd

Run Nt32Pkg

1. Build the Nt32Pkg
build -p Nt32Pkg/Nt32Pkg.dsc -t VS2017 -a X64

2. Run the Nt32 emulation
build -t VS2017 -a X64 run


2019/04/08 Note:
在更新完EDK的source code之後,會出現build failed ...\CryptoPkg\Library\OpensslLib\OpensslLibCrypto.inf(31): error 000E: File/directory not found in workspace
  ...\CryptoPkg\Library\OpensslLib\openssl\e_os.h

參考檔案 CryptoPkg\Library\OpensslLib\OpenSSL-HOWTO.txt 需加入OpenSSL submodule

在已擁有local source且未加入submodule的情況下,加入OpenSSL submodule git submodule update --init --recursive

若還未擁有local source,可直接使用"--recursive" flag git clone --recursive https://github.com/tianocore/edk2

2020/08/09 Note:
要build最新 edk2 EmulatorPkg,basetool部分需要重新rebuild
且需使用VC2019,使用VC2017會build不過


2021/10/06 Note:
在另一台電腦重新架環境,並rebuild BaseTools的時候會遇到 assert.h
找不到的問題。後來才發現 %include%的 path有問題,原因是那台電腦中安裝的
WDK可能造成在設定 SDK path的時候出問題,後來解除安裝 WDK就能避開這個問題。


2018年7月3日 星期二

PSPP (PCIe Speed Power Policy)

本篇文章參考來源:
AGESA Interface Specification for Arch2008
BKDG for AMD Family 12h Processors

PSPP 是動態調整PCIe的Link Speed的使用策略,藉此來達到省電的效果,需有處理器的支援。
其透過 Driver及 Interrupt來使用 BIOS所提供的 ACPI method ALIB(ACPI ASL Library) 達成其在Runtime時的所需的功能。

ALIB

ALIB method是由幾組Function所構成的服務。

ALIB (Arg0, Arg1)


 Arg0
     所要使用的Function的號碼。
 Arg1
     Function的輸入及輸出參數,會根據Function而有所不同。

Function 3 - PSPP Start/Stop Management Request

 用來決定是否使用PSPP。


2018年6月28日 星期四

RAMDisk 軟體 - ImDisk


官方網址

https://sourceforge.net/projects/imdisk-toolkit

測試系統

Windows 10

使用版本

2.0.9

RamDiskUI.exe


Size: RAMDisk磁碟的大小
Allocate Memory Dynamically: 動態記憶體配置



Quick Format: 快速格式化



Load Content from Image File or Folder: 指定RAMDisk磁碟所要備份的參考路徑
Excluded Folders: 忽略所要備份的目錄
Synchronize now: 將RAMDisk磁碟同步到參考路經


config.exe


Request administrator rights in Explorer: 執行RAMDisk中的檔案時以Administrator權限執行


Windows Print Screen 按鍵功能


Print Screen為鍵盤上所提供相容於Windows系統的按鍵,通常縮寫為PrtSc。

PrtSc
將全螢幕的圖像存入隨機記憶體,使用Ctrl + V將圖像讀出。

Alt + PrtSc
將應用程式的圖像存入隨機記憶體,使用Ctrl + V將圖像讀出。


Win8/Win10

Win + PrtSc
將全螢幕的圖像存入PNG檔到圖片資料夾。

Win + Alt + PrtSc
將應用程式的圖像存入PNG檔到影片資料夾。

2018年6月20日 星期三

[Batch] 取得字元的ASCII Number

在寫Batch script的時候,有時候會需要用到某些字元的 ASCII Number 來做判斷(ex: 判斷 英文字母的排序),但是cmd.exe並沒有提供這樣的服務,這時候可以應用一個非官方文件 所記載的動態變數 %=ExitCodeAscii% 來達成目的。

%=ExitCodeAscii% 的值為最後一個額外的cmd.exe所回傳的ExitCode的ASCII character。

Example: 找出 "A" 的ASCII Number
@echo off
setlocal EnableDelayedExpansion

set char=A
for /l %%a in (32,1,126) do (
   cmd /c exit %%a
   if "!=exitcodeAscii!" EQU "%char%" echo %%a
)

Output:
65

延遲變數展開 (EnableDelayedExpansion)

在剛開始寫Batch的迴圈(for)的時候,都會遇到一個問題,就是在迴圈中,想要去改變(set)
某個變數的值,可是卻沒有作用。

Example:
set var=0
for %%a in (1 1 1 1 1) do (
   set /a var+=%%a
   echo %var%
)
echo %var%

Output:
0
0
0
0
0
5

上面範例原意是想讓var在每次的迴圈中都+1,最後的值會是5。可是在迴圈中每次echo 出
的值都是一開始的var值0。


原因是 var在 batch file被解析的時候就會提前展開,所以在迴圈中會 echo出一開始被展開的
值。要得到預想的結果就要使用setlocal EnableDelayedExpansion來延遲變數展開,使其在
執行的階段才會被展開。


Example:
setlocal EnableDelayedExpansion
set var=0
for %%a in (1 1 1 1 1) do (
   set /a var+=%%a
   echo !var!
)
echo %var%

Output:
1
2
3
4
5
5

注意在取值時,要延遲展開的變數需使用!var!才會有效果。

與setlocal EnableDelayedExpansion對應的是setlocal DisableDelayedExpansion,其作用為取消延遲變數展開。

2018年6月11日 星期一

記憶體(SDRAM) 的規格標示

以DDR4為例,目前在市面上常見的產品有:DDR4 2133、DDR4 2400、DDR4 2666及DDR4 3200 等。

用DDR4 2400來說,有時候也會看到PC4-19200等其他標示,這裡的DDR4 2400的"2400", 單位是MT/s (megatransfers per second),意義上代表每秒鐘可完成2400×106次傳輸操作。

而目前記憶體DIMM的Bus width為8 Bytes(64 Bits),表示DDR4 2400的資料傳輸速率為19200 MB/s (8 Byte × 2400 MT/s),所以PC4-19200的"19200"就代表記憶體傳輸速率的峰值(Peak Transfer Rate),單位為MB/s。


SMBIOS Type 17中的"Speed"欄位,在先前的SPEC (3.0.0 與之前的版本)中,是用時脈來表示記 憶體速度,單位是MHz。在之後的SPEC,"Speed"欄位則改用MT/s來表示。以DDR4 2400為例,"Speed"所 要填的值為0x0960(2400)(MT/s),而若是SMBIOS 3.0.0以前,就要填為0x4B0(1200)(MHz)。

記憶體的MHz和MT/s間轉換,就是將MHz的數值×2就能獲得MT/s,因為資料傳輸同時計入時脈 的正緣與負緣。

2018年6月10日 星期日

System Management BIOS(SMBIOS) 概述

SMBIOS是由DMTF(https://www.dmtf.org/)組織所制定及維護的業界規範,其目的在於讓主機 板及系統廠商有統一的標準格式,來描述產品相關的管理資訊,並供給作業系統使用。

本篇文章以SMBIOS 3.2.0 Specification 當作參考:
DSP0134_3.2.0

  • SMBIOS entry point

要得到SMBIOS的資訊,首先必須先找到SMBIOS 的Entry point,再透過SMBIOS entry point structure中的 "Structure Table Address",來找到SMBIOS table的記憶體位址。

SMBIOS Entry Point主要可以區分為較早期的版本SMBIOS 2.1及現在的SMBIOS 3.0版本,以32-bit和64-bit作為分別。


SMBIOS Entry Point structure的訪問方法


Legacy
在實體記憶體位址0x000F0000-0x000FFFFF之間,尋找"_SM_"(SMBIOS 2.1) 或者"_SM3_"(SMBIOS 3.0)字串,就可以訪問到其Entry Point structure。

UEFI
透過EFI Configuration Table和SMBIOS GUID來進行訪問。
SMBIOS 2.1為SMBIOS_TABLE_GUID{EB9D2D31-2D88-11D3-9A16-0090273FC14D}。
SMBIOS 3.0為SMBIOS3_TABLE_GUID{F2FD1544-9794-4A2C-992E-E5BBCF20E394}。


得到SMBIOS Entry Point 之後,就可以透過其"Structure Table Address"來訪問 SMBIOS structure。

EDK2中定義的 SMBIOS Entry Point結構
typedef struct {
  UINT8     AnchorString[5];
  UINT8     EntryPointStructureChecksum;
  UINT8     EntryPointLength;
  UINT8     MajorVersion;
  UINT8     MinorVersion;
  UINT8     DocRev;
  UINT8     EntryPointRevision;
  UINT8     Reserved;
  UINT32   TableMaximumSize;
  UINT64   TableAddress;
} SMBIOS_TABLE_3_0_ENTRY_POINT;

  • SMBIOS Structure

SMBIOS Structure可以分為formatted section和optional unformed section。
formmated section以長度4 byte的header起始,而接在header之後的資料格式根據Structure type有所不同。 optional unformed section則由文字字串組成。


SMBIOS Structure Header


Offset   Name   Length   Description  
00h   Type   BYTE   Structure的類型。Type 00h到 7Fh是預留給SMBIOS spec定義,而Type 80h到 FFh則讓系統廠可以自行 定義。 
01h   Length   BYTE   Structure formatted section的資料長度,從header的Type開始算起,不包含文字字串的 部分 
02h   Handle   WORD   用來識別不同structure實體的一組16 bit number,其值範圍是從 FF00h到 FFFFh。 

Text String


SMBIOS Structure的Text String區塊接在Structure的formatted section之後。而其是選擇性的, SMBIOS的Structure內並不一定要含有Text String。每個Text String的結尾都是null character(00h)。

在SMBIOS structure的formatted section中,需要使用Text String的時候,就需要填上一個非0 值。假設其填值為02h,就代表這個string field要去參考Text String區塊中的第二個Text String。若其 填為0,就代表此string field不使用Text String。

SPEC中的BIOS Infomation(Type 0)範例:

使用Text String的BIOS Infomation(Type 0)
BIOS_Info LABEL BYTE
db    0                 ; Indicates BIOS Structure Type
db    13h                ; Length of information in bytes
dw    ?                 ; Reserved for handle
db    01h                ; String 1 is the Vendor Name
db    02h                ; String 2 is the BIOS version
dw    0E800h               ; BIOS Starting Address
db    03h                ; String 3 is the BIOS Build Date
db    1                 ; Size of BIOS ROM is 128K (64K * (1 + 1))
dq    BIOS_Char             ; BIOS Characteristics
db    0                 ; BIOS Characteristics Extension Byte 1
db    'System BIOS Vendor Name',0      ;
db    '4.04',0               ;
db    '00/00/0000',0           ;
db    0                 ; End of strings

沒有使用Text String的BIOS Infomation(Type 0)
BIOS_Info LABEL BYTE
db    0                 ; Indicates BIOS Structure Type
db    13h                ; Length of information in bytes
dw    ?                 ; Reserved for handle
db    00h                ; No Vendor Name provided
db    00h                ; No BIOS version provided
dw    0E800h               ; BIOS Starting Address
db    00h                ; No BIOS Build Date provided
db    1                 ; Size of BIOS ROM is 128K (64K * (1 + 1))
dq    BIOS_Char             ; BIOS Characteristics
db    0                 ; BIOS Characteristics Extension Byte 1
dw    0000                ; Structure terminator

2018年6月8日 星期五

HTML escape characters

Symbol   Entity Name  
space    
en space    
em space    
&   &
<   &lt;
>   &gt;
"   &quot;

bcdedit - Windows 管理BCD存放區的工具

本篇文章參考網頁:
bcdedit-command-line-options

在Windows內建管理BCD(Boot Configuration Data) 存放區(store)的工具,可以用來修改開機順序,或其他與開機相關操作。

bcdedit /COMMAND [ARGUMENT1] [ARGUMENT2]

HELP


bcdedit /? [COMMAND] 輸出bcdedit 命令列表。若有COMMAND參數,則輸出COMMAND的詳細資訊。


操作存放區


export bcdedit /export <FILENAME> 匯出系統存放區的內容至檔案,這個檔案可以用import命令來還原系統存放區,此命令只對系統存放區有效。

import bcdedit /import <FILENAME> [/clean] 能將export的檔案匯入系統存放區,此命令只對系統存放區有效。

store bcdedit /store <FILENAME> 指定要操作的存放區。如果沒有指定,bcdedit將會以系統存放區(system store)進行操作。


修改entry的項目


set bcdedit /set [{<id>}] <datatype> <value> [/addfirst|/addlast|/remove] 設定entry項目的值。


輸出控制


enum bcdedit /enum [<type>|<id>] 列出存放區中的entries


控制開機管理程式的命令


displayorder bcdedit /displayorder <id> [...] [/addfirst|/addlast|/remove] 調整開機管理程式顯示的選項順序


Debugging


dbgsetting bcdedit /dbgsetting [ <debugtype> [TARGETNAME:<targetname>] ] 設定系統的全域Debugger,不加參數則顯示目前全域Debugger設定。

<debugtype> - 指定Debugger類型。可為SERIAL、USB和NET等。
<targetname> - 用於USB偵錯,指定用於偵錯的USB目標名稱。

debug bcdedit /debug [<id>] { ON | OFF } 開啟或關閉開機項目的Kernel Debugger。若id沒有指定,則開啟或關閉目前的開機選項的Kernel Debugger。


  • 使用bcdedit在Windows下調整boot order(使用USB Device開機)


1. 列出系統存放區所有firmware applications
bcdedit /enum firmware
2. 找到要使用於開機的USB Device的firmware application,並記錄其id(identifier)。

3. 將fwbootmgr entry的USB device選項用displayorder設到最前面。
bcdedit /set {fwbootmgr} displayorder <id> /addfirst
4. 重新開機,這時系統應該會boot進USB device的image中。

2018年6月7日 星期四

diskpart - Windows 管理硬碟與分割區的工具

diskpart是Windows下用以管理及操作磁碟與分割的CLI工具。

assign

指派一個磁碟機代號或掛接點到所選擇磁碟區。


clean

清除磁碟上所有資訊,可以用以清除磁碟上的分割區。


create

建立一個磁碟區、磁碟分割或虛擬磁碟。

partition - 建立一個磁碟分割。
efi - 建立一個EFI系統磁碟分割。
extended - 建立一個延伸磁碟分割。
logical - 建立邏輯磁碟區。
msr - 建立一個Mircrosoft保留的磁碟分割。
primary - 建立主要磁碟分割。

volume - 建立一個磁碟區。
vdisk - 建立虛擬磁碟檔案。


exit

離開diskpart。


format

格式化磁碟區或磁碟分割。

OPTIONS
fs=<FS> - 指定檔案系統的類型。ex: fs=ntfs。
label=<"LABEL"> - 指定磁碟區標籤。ex: label=D。
quick - 執行快速格式化。


list

列出物件的清單。

disk - 列出磁碟。
partition - 列出所選磁碟上的分割。
volume - 列出磁碟區。
vdisk - 列出虛擬磁碟。


select

將襙作移至所選物件。

disk - 將操作移至所選磁碟。
partition - 將操作移至所選分割。
volume - 將操作移至所選磁碟區。
vdisk - 將操作移至所選虛擬磁碟。


shrink

縮小所選磁碟區。

OPTIONS
desired=<N> - 指定要縮減的磁碟區空間大小(MB)。ex: desired=100000。
querymax - 回傳所選磁碟區可縮減的空間最大值(磁碟區上的可用空間),但如果
  應用程式正在存取磁碟區,此值可能會改變。



diskpart批次檔


diskpart也能寫成批次檔形式,可以參考:
diskpart-scripts-and-examples

執行diskpart script
diskpart /s example.txt

Batch script 筆記

參考網頁
windows-commands
https://ss64.com/nt/
https://en.wikibooks.org/wiki/Windows_Batch_Scripting

  • 參數

Batch的參數使用 %n (%0、%1、%2、%3 ...) 來代表第n個參數,%0 代表batch檔本身。

%n 還可以使用下列擴充語法,詳細內容可以使用 call /? 來參考:
%~1 - 展開 %1 並移除包圍的引號(")
%~f1 - 展開 %1 為一個完整合格路徑名稱
%~d1 - 只展開 %1 為磁碟機代號
%~p1 - 只展開 %1 為路徑
%~n1 - 只展開 %1 為檔名
%~x1 - 只展開 %1 為副檔名
%~z1 - 顯示 %1 的檔案大小

常見應用

%~dp0
batch檔所在的目錄,常與%CD%作為比較,%CD%代表的是當前的工作目錄。


  • 動態變數

cmd.exe下可使用的動態變數,不會出現在set 命令的環境變數列表中,在每次展開時
都會重新計算一次。


%CD%
展開當前工作目錄的字串。

%RANDOM%
展開一個範圍0到32767間的整數。

%ERRORLEVEL%
展開目前ERRORLEVEL的值。

參考範例
在Batch 中取出字元的ASCII Number


  • 輸出命令重新定向

COMMAND > FILENAME
清除原有內容後再寫入

COMMAND >> FILENAME
在原有內容後寫入

COMMAND < FILENAME
將FILENAME的內容傳入COMMAND

COMMAND_A | COMMAND_B
將COMMAND_A的output傳入COMMAND_B

常見應用

COMMAND > nul
不印出輸出命令結果


  • cd

切換目錄

/d
同時切換磁碟機


  • del

刪除一或多個檔案

/q
Quiet Mode。不會再次詢問是否刪除檔案。


  • endlocal

復原setlocal前的環境變數


  • exit

結束cmd.exe或目前的batch script。

/b
結束目前的batch script而不是cmd.exe。

/b [exitCode]
將ERRORLEVEL variable設為exitCode所設的數字。


  • findstr

搜尋檔案中的字串

/c:string
所要逐字搜尋的字串。若要搜尋多個字串,可用空白字元分隔。

/r /c:string
將string視為regular expression來使用。


  • for 迴圈


使用for 迴圈iterate 項目
for %%PARAMETER in (ITEM1 ITEM2 ITEM3 ...) do COMMAND

一次讀出字串並將其分成獨立的項目(tokens)
for /f ["OPTIONS"] %%PARAMETER in ("Text string to process") do COMMAND

一次讀出command的輸出並將其分成獨立的項目(tokens)
for /f ["OPTIONS"] %%PARAMETER in ('COMMAND_TO_PROCESS') do COMMAND

使用一段範圍的數字iterate
for /l %%PARAMETER in (start,step,end) do COMMAND
start - 起始數字
step - 迴圈數字所要增加的值,可為負數
end - 結束數字


OPTIONS
Key   Description  
delims=xxx   設定分隔字元(預設為空白字元),xxx表示可設定多個字元。  
token=x,y  
token=z*  
token=m-n  
用來決定要取出的item,並且放到parameter中。 
若token=x,就取出第x項item。  
token=x,y,若parameter設為%a,便取出第x與y項item分別置於%a和%b自動變數中。 
token=z*,若parameter設為%a,取出第z項置於%a中,並將第z項後的所有item置於%b中。 
若token=m-n,便取出第m至第n項。 


  • if 判斷式


判斷檔案存在與否
if [not] exist FILENAME COMMAND if [not] exist FILENAME (COMMAND) else (COMMAND)
判斷文字字串是否相符 if [not] STRING1==STRING2 COMMAND
使用數值進行判斷 if [not] ITEM1 compare-op ITEM2 COMMAND if [not] ITEM1 compare-op ITEM2 (COMMAND) else (COMMAND)
/i
忽略大小寫。

compare-op:
EQU - Equal
NEQ - Not Equal
LSS - Less Than
LEQ - Less Than or Equal
GTR - Greater Than
GEQ - Greater Than or Equal


  • set

顯示、設定或移除cmd.exe的環境變數。若不加任何參數,就會顯示所有環境變數。

將變數設為文字字串
set VARIABLE=STRING
將變數設為數學運算後的值
set /a "VARIABLE=expression"

常見應用

set VARIABLE=
VARIABLE初始化

set /a VARIABLE=HEX_NUMBER or OCT_NUMBER
可將十六進位數字(ex: 0x2F) 或八進位數字(ex: 057) 轉換成十進位數字。


  • setlocal

將環境變數帶入到Batch 的local變數中,在Batch執行完或endlocal時結束。

設定或取消延遲變數展開
setlocal {EnableDelayedExpansion | DisableDelayedExpansion}
EnableDelayedExpansion - 延遲變數展開
DisableDelayedExpansion - 取消延遲變數展開

補充說明
延遲變數展開 (EnableDelayedExpansion)


2018年6月5日 星期二

Docker 命令列介面筆記

本篇文章參考來源:
https://docs.docker.com/get-started/part2/
https://docs.docker.com/engine/reference/commandline/docker/

  • docker pull

從 registry取得 image

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

docker pull python


取得 python的image

docker pull python:3.8.16


取得 python版本為3.8.16的image

  • docker build

使用Dockerfile建立image

docker build [OPTIONS] PATH | URL | -
OPTIONS
Name, shorhand   Description  
--tag, -t   指定image的命名及tag,格式為name:tag,tag為optional  


  • docker image

管理操作image

docker image COMMAND

docker image ls


列出image

OPTIONS
Command   Description  
--all, -a   列出所有images  

docker image rm


刪除 image


  • docker run

在新的container中執行命令

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS
Name, shorhand   Description  
--detach, -d   讓container在背景執行  
--interactive, -i   保持 container中的 STDIN開啟  
--publish, -p   將container的port映射到host端  
--rm   在container exit後自動移除  
--tty, -t   分配一個 pseudo-TTY給 container  

docker run --rm -i -t python:3.8.16


python的交互模式在 container中執行


  • docker container

管理操作container

docker container COMMAND

docker container ls


列出container

OPTIONS
Command   Description  
--all, -a   列出所有container  

docker container stop


docker container stop [OPTIONS] CONTAINER [CONTAINER...]
終止執行中的container

2018年5月31日 星期四

Dockerfile 指令筆記

本篇文章參考來源:
https://docs.docker.com/get-started/part2/
https://docs.docker.com/engine/reference/builder/

使用者可以透過Dockerfile來定義Docker container的開發環境。

Dockerfile的基本格式:
# comment
INSTRUCTION arguments

引用官方範例如下:
# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]


FROM


FROM <image>[:<tag>]

引入container所需要的Base Image。


WORKDIR


WORKDIR /path/to/workdir

指定docker執行指令的工作目錄


ADD


ADD <src>... <dst>

將<src>的檔案及目錄複製到image的<dst>中


RUN


RUN <command>
RUN ['executable', 'param1, 'param2']

在當前的image上會再建立新的一層image,並在新的image執行RUN的command


EXPOSE


EXPOSE <port> [<port>/<protocol>...]

指定container對外部開放的port


ENV


ENV <key> <value>
ENV <key>=<value> ...

建立build stage時的environment variable


CMD


CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

image被啟動時所執行的command,在Dockerfile中只有最後一個CMD會被執行。


2018年5月28日 星期一

在 Ubuntu下安裝 Docker CE

本篇文章參考來源:https://docs.docker.com/install/linux/docker-ce/ubuntu

  • 移除舊版的 Docker

在Docker較新的版本中,將Docker區分為CE(Community Edition)與EE(Enterprise Edition)的版本, 所以在安裝前,最好先移除舊版的Docker。

$ sudo apt-get remove docker docker-engine docker-io

  • 透過 Docker的 repository來進行安裝


設定 Docker的 repository


1. 更新 apt的套件資訊

apt會使用 /etc/apt/sources.list來更新套件資訊,讓套件與相關 repository同步。

$ sudo apt-get update

2. 安裝相關套件讓 apt能透過 HTTPS使用 repository

$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

3. 加入Docker的 GPG key

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
接下來,確認剛加入的key是否含有以下fingerprint
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88

搜尋fingerprint最後8個字元為0EBFCD88 $ sudo apt-get fingerprint 0EBFCD88 pub   4096R/0EBFCD88 2017-02-22
      Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-0222

4. 使用Docker Stable 的 repository

$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"


安裝Docker CE


1. 再次更新 apt的套件資訊

$ sudo apt-get update

2. 安裝Docker CE

$ sudo apt-get install docker-ce

3. 運行 hello-world image來確認Docker是否安裝成功

$ sudo docker run hello-world

2018年5月14日 星期一

使用 Virtualenv 開發 Python



  • 安裝 Virtualenv

使用pip指令安裝Virtualenv

Windows:
> python -m pip install virtualenv


  • 使用 Virtualenv 建立虛擬環境

將路徑切換至Python需要建立虛擬環境的目錄下,並執行

Windows:
> python -m virtualenv [env_name]
env_name為所要建立虛擬環境的名稱,之後就會在目錄下產生名為[env_name]的資料夾


  • 運行虛擬環境

執行env_name/Scripts中的activate檔案

Windows:
> .\venv\Scripts\activate.bat

執行成功後,命令視窗就會出現目前正運行在虛擬環境中的提示字樣
(env_name)


  • 離開虛擬環境

執行env_name/Scripts中的deactivate檔案

Windows:
> .\venv\Scripts\deactivate.bat

若命令視窗中的提示字樣消失,就代表已經成功離開虛擬環境