bloggerads

2016年5月28日 星期六

UEFI : Event (事件)

UEFI 基本上是個單核/單工/提供Timer中斷的系統。<note 1>
但因為他提供了Timer中斷, 理論上就有機會做到異步操作以及分時多工。

實現這樣的目標可以透過 Boot Service提供的事件(Event)來達成。

首先使用 gBS->CreateEvent() 註冊一個 NotifyFunction (或稱CallBackFunction) 等待事件的發生或讓事件週期性的在背景執行。關閉Event須要呼叫  gBS->CloseEvent() 。因為是Boot Service所提供的,因此ExitBootServices()被系統呼叫後,BS的service/data都會消失。

先來看看Event的 typedef

2016年5月19日 星期四

AHCI: Index-Data Pair (IDP)

寫AHCI "Legacy" Option Rom的時候,為了要Access MMIO (AHCI Base Address) 得從 real mode 切換到Protect Mode 。但是AHCI其實有定義一種叫做Index Data Pair的機制,透過Access IO來替代MMIO。這種方法就可以在純real mode (<1MB) 底下寫AHCI Driver了

AHCI Spec第2.4章,定義了一個SATA Capability(0x12), 有這個Capability就是代表此AHCI有support Index Data Pair


這個Cap的結構如下

2016年5月12日 星期四

UEFI : Coding after S3 BootScript

做這個實驗的動機是工作上必須在S3 BootScript完成後加patch code, 當時趕時間就把程式直接加在AMI 的 code裡。趁現在有空,就研究看有沒有辦法把她加在公司package code裡。

想想,應該可以註冊個Notify CallBack function在Pei phase結束之前自動呼叫她,實驗結果是可以的。以下是我的作法,在S3 Pei init 的路徑上加上  


(*PeiServices)->NotifyPpi(PeiServices, mTest);

2016年5月2日 星期一

UEFI : SMM Kernel Code 重點整理: (一) Protocols


首先定義SMM driver和一般DXE driver:


DXE drivers
  regular DXE phase drivers that loads into system memory by DXE core driver.
SMM drivers  
  SMM Drivers are launched once, directly into SMRAM during SMM phase initialization.
SMM/DXE combined drivers
  Combination of drivers that loaded twice: as DXE driver and as SMM driver.

簡單介紹SMM Driver在做什麼

2016年3月17日 星期四

ATA : 硬碟密碼

在Bios底下常會看到兩種密碼可以設定, Bios密碼 / HDD(硬碟)密碼

這邊討論的是HDD 密碼, follow by ATA spec,首先,簡介如下

HDD User Password and HDD Master Password:
There are two levels of the HDD Password, the HDD User Password and the HDD master Password. If both levels of HDD Password have been registered, you can access the HDD by entering either of them.

以下兩個Identify table, 分別是設了ATA password (ATAIDSP.TXT)和未被設ATA password(ATAID.TXT) 時硬碟的identify傳回值

2016年1月14日 星期四

Hook my own interrupt vector in DOS

因為工作上需要驗證中斷的tool, 所以把塵封已久的Watcom DOS程式拿出來改。以下是一個基本的掛中斷、呼叫中斷、移除中斷的範例
// Author: Martin Lee  

 #include <stdio.h>
 #include <conio.h>
 #include <dos.h>

 #define getvect(n) _dos_getvect(n)

 #define setvect(n,v) {\
   _disable();\
   _dos_setvect(n,v);\
   _enable();\
 }

 #define HOOKVECTOR 0x7F

 int sig;

 void interrupt  (*origin_int)();

 void interrupt handle_7Fh(void)
 {
     sig=1;
     //_chain_intr( origin_int); // not execute original vector
 }

 void hook_int(void)
 {
     origin_int = getvect(HOOKVECTOR);
     setvect (HOOKVECTOR, handle_7Fh);
 }

 void restore_int(void)
 {
     setvect(HOOKVECTOR,origin_int);
 }

 void main()
 {
     sig = 0;

     hook_int();

     printf("Before int 7fh, sig = %d\n", sig);

     __asm  int 7Fh    
   
     printf("After int 7fh, sig = %d\n", sig);
       
     restore_int();
   
 }

----------------------執行結果-----------------------------
Before int 7fh, sig = 0
After int 7fh, sig = 1


2016年1月3日 星期日

C# : 測試程式執行的時間 (Time measurement)

using System.Diagnostics; // Stopwatch
using System.Threading; // Thread.Sleep

static void Main(string[] args)
{
    Stopwatch stopWatch = new Stopwatch();
    
    stopWatch.Start();
    Thread.Sleep(1000);
    stopWatch.Stop();

    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
        ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);

    Console.WriteLine("RunTime " + elapsedTime);
    Console.ReadLine();
}


Reference:
https://msdn.microsoft.com/zh-tw/library/system.diagnostics.stopwatch(v=vs.110).aspx