bloggerads

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

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);

}