為什麼要在Linux(Ubuntu)底下build Bios module呢?
因為接手了大陸同事的UEFI Shell code,而他使用了 gcc 的library "Atomic Memory Access",這個library在平常我們慣用的Visual Studio compiler下無法直接使用。
所以這兩天,花了點時間研究一下如何在Ubuntu下建構可以編譯的環境。
由於網路上比較少有這樣的文章分享, 因此特地新增一篇網誌做說明以及紀錄
基本上我是參考以下這兩篇Using EDK II with Native GCC、UDK2014 How to Build
,這邊解釋一下必要的流程
#取得EDK2 code base 請參考 https://github.com/tianocore/edk2
#安裝所需要的編譯工具
bash$: sudo apt-get install build-essential subversion uuid-dev iasl
#取得nasm組譯器
bash$: sudo apt-get install nasm
bloggerads
2016年12月1日 星期四
2016年11月23日 星期三
x86 architecture : Graphic UMA Frame buffer
傳統的顯卡控制方式是透過A/B Segment MMIO來輸出螢幕,但只有128K MMIO address, 顯然這樣的空間不夠用。現在的內顯都會在DRAM上"偷"一塊Memory做為輸出顯示用,系統上是看不到這塊Memory的,而這塊Memory稱為UMA frame buffer。一般在系統上看到系統顯示的記憶體遠小於所插的Dram記憶體,一大部分就是被frame buffer挖走的,至於frame buffer的size是可以在Bios選單去改變設定的。
UMA frame buffer之所以特殊是,他宣告為MMIO resource,但實際上decoder會將含有此address的cycle再forward給memory. 示意圖如下:
一般CPU bus的 traffic control 設計通常會先看這筆cycle是否往MMIO (C2P cycle),若不是則再看是否往Memory (C2M cycle),若都不是的話,則透過報錯機制回報錯誤(EBMC, MCA...)。
而外插式顯卡本身有自己的DRAM, 雖然都會要求MMIO resource, 但使用的是自己的記憶體。
Keyword: UMA( Unified Memory Architecture), Frame buffer, Graphic
UMA frame buffer之所以特殊是,他宣告為MMIO resource,但實際上decoder會將含有此address的cycle再forward給memory. 示意圖如下:
一般CPU bus的 traffic control 設計通常會先看這筆cycle是否往MMIO (C2P cycle),若不是則再看是否往Memory (C2M cycle),若都不是的話,則透過報錯機制回報錯誤(EBMC, MCA...)。
而外插式顯卡本身有自己的DRAM, 雖然都會要求MMIO resource, 但使用的是自己的記憶體。
Keyword: UMA( Unified Memory Architecture), Frame buffer, Graphic
2016年11月15日 星期二
g++ : libgcc_s_dw2-1.dll is missing
解決某些Windows平台在執行exe檔時,找不到libgcc_s_dw2-1.dll。缺少的這個dll應該是C++的library
我的g++版本(gcc -v): 4.8.1
解決方法就是在compile code 時加入 -static-libgcc -static-libstdc++ 參數把所需要的library包進去
如下:
g++ -o main main.cpp 改成
g++ -o main -static-libgcc -static-libstdc++ main.cpp
2016年11月11日 星期五
使用DeviceIoControl::IOCTL_DISK_GET_LENGTH_INFO 獲取 Disk 大小
一般若要得到Sata硬碟或Usb硬碟Size,須要透過傳遞PASS_THROUGH參數來下Identify command,而參數須符合ATA command/ SCSI command spec, 使用上比較麻煩。
WinApi提供了一個比較通用的方式(IOCTL_DISK_GET_LENGTH_INFO)來得到,如下:
#include <windows.h> #include <winioctl.h> #include <stdio.h> unsigned long long GetDiskLengthIoctl(const char *dsk) { HANDLE hDisk = CreateFile( dsk, GENERIC_READ, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0); if(hDisk == INVALID_HANDLE_VALUE) { printf("Could not open the disk. GetLastError() returned ", GetLastError()); return 0; } GET_LENGTH_INFORMATION gli; DWORD ret; DeviceIoControl( hDisk, IOCTL_DISK_GET_LENGTH_INFO, 0, 0, &gli, sizeof(gli), &ret, 0); CloseHandle(hDisk); return gli.Length.QuadPart; } int main() { const char *Disk = "\\\\.\\PhysicalDrive0"; // or \\\\.\\C: printf("size = %d (GB)\n", GetDiskLengthIoctl(Disk)/1024/1024/1024); printf("Lba = %x \n", GetDiskLengthIoctl(Disk)/512); }
2016年8月5日 星期五
ATA : SATA-to-USB and SSD
由於USB的方便攜帶跟普及性,所以現在市售走USB protocol 的外接硬碟非常多,大部分的構造都是一顆SATA硬碟搭配SATA-to-USB 轉卡。還有些人是自行購買SATA-to-USB 轉卡透過USB port來外接硬碟 or SSD。接 SSD這樣的用法是有隱憂的,接下來解釋原因。
以上的架構(SATA過轉卡轉USB), 如果想傳原生的ATA Command給硬碟,則必須穿過 SATA-to-USB 轉卡才能將ATA command傳給碟機。方法是透過呼叫 DeviceIoControl 來發出 SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER。以前在硬碟廠寫相關Utility (Update FW/ Identify...), 就是透過這個protocol發出ATA 給硬碟。
以上的架構(SATA過轉卡轉USB), 如果想傳原生的ATA Command給硬碟,則必須穿過 SATA-to-USB 轉卡才能將ATA command傳給碟機。方法是透過呼叫 DeviceIoControl 來發出 SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER。以前在硬碟廠寫相關Utility (Update FW/ Identify...), 就是透過這個protocol發出ATA 給硬碟。
2016年7月1日 星期五
UEFI : 編譯文件
現有的Project要升級EDK2, 因此整理一下使用EDK2的經驗,並把所理解的做個簡單記錄:
首先,INF/DEC/DSC/FDF file是標準編譯UEFI code所需要準備的,在 AMI code裡DSC/FDF file是AutoGen出來的,而且因為AMI有自己的編譯介面,所以編譯AMI code還須要準備 "SDL", "CIF", "VEB"和 "ldl"檔。
以下介紹INF/DEC/DSC files
● 先定義名詞: $(Arch) (對像是何種architecture)
● $(MORDULE_TYPE) (如SEC, PEI_CORE, PEIM, DXE_CORE,...)
首先,INF/DEC/DSC/FDF file是標準編譯UEFI code所需要準備的,在 AMI code裡DSC/FDF file是AutoGen出來的,而且因為AMI有自己的編譯介面,所以編譯AMI code還須要準備 "SDL", "CIF", "VEB"和 "ldl"檔。
以下介紹INF/DEC/DSC files
● 先定義名詞: $(Arch) (對像是何種architecture)
| Arch | Description |
| IA32 | X86 32位CPU |
| X64 | X86 64位CPU |
| IPF | Itanium Processor Family |
| ARM | |
| EBC | EFI Byte Code |
● $(MORDULE_TYPE) (如SEC, PEI_CORE, PEIM, DXE_CORE,...)
2016年6月24日 星期五
UEFI : BuildOptions (Compiler Options)
用來access IO的變數若不宣告成volatile,但又怕因為最佳化而沒有實際access到IO的話,可以改Compiler Options 關掉最佳化編譯。更改UEFI 的Compiler Options, 可以選擇一次改全部 modules 或只改單一個 module,在EDK2都是透過修改DSC file。
1. 更改單一個 module 的 compiler options
[Components]
PackageNamePkg/NameOneDxe/NameOneDxe.inf {
<BuildOptions>
MSFT:*_*_*_CC_FLAGS = /Od
}
訂閱:
文章 (Atom)
