bloggerads

顯示具有 AHCI ; SATA ; ATA ; IDE 標籤的文章。 顯示所有文章
顯示具有 AHCI ; SATA ; ATA ; IDE 標籤的文章。 顯示所有文章

2017年5月7日 星期日

NVMe : Compare to AHCI

這篇列出AHCI / NVMe的差異


PCIe 2.0: 5GT/s    4Gb/s      500MB/s
PCIe 3.0: 8GT/s    8Gb/s      1GB/s

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 給硬碟。

能夠在作業系統底下Access碟機,以硬碟廠的角度可以提供FAE做初期的檢測(看Smart table / 下一些Vendor Specific的command來判斷FTL/GC出了什麼樣的問題)當然還有最重要的update FW

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年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傳回值

2015年8月20日 星期四

SATA : PMP (Port Multiplier)

這份spec常常被人遺忘,但她又確確實實定義在AHCI和SATA裡,先不論市場的接受度如何,相信做碟機相關技術的朋友都很好奇這個是什麼。

首先先看看spec所給的架構圖:


2014年11月7日 星期五

ATA: Security Erase flow

ATA 清理硬碟的command有兩種:
  1. Trim command: 06h
  2. Security Erase command: F4h
最安全的方式是對碟機下security erase command, 才可以保證把舊硬碟送人後資料不會被扒出來。

這邊介紹security erase command flow, 往往市面上的軟體都需要熱插拔碟機,但這邊提供的方法不需要,因此可以適用在PCIe AHCI SSD上

步驟如下:

1. 用ATA Set feature command通知碟機將Comreset 轉成Hardware reset (因為開機Bios會對你的碟機下Security freeze lock讓碟機變成state machine:frozen state。如果不這樣做就得先熱插拔碟機才能讓碟機回到state machine:not frozen, 才可以下security erase)

下法就是透過Set feature command (EFh), feature=0x90 and count=0x06,來disable software setting preservation
這樣之後我們下的Comreset才會被轉成 hardware reset, 讓碟機回到not frozen state


2. 接著透過 port reset 或 HBA reset 發出 COMRESET

3. 下security erase command之前要先設定密碼 (也就是提升權限才能下這個command,最後security erase也會一併erase掉這個密碼)

就是以下這三步驟:
  1. SECURITY SET PASSWORD: F1h
  2. SECURITY_ERASE_PREPARE: F3h
  3. SECURITY_ERASE_UNIT: F4h
通常SSD幾秒內就完成碟機的erase(基本上還是要看碟機廠商怎麼做),傳統轉盤的碟機就會比較久甚至有些是天荒地老的久XD.

2014年6月27日 星期五

ATA overview

想要寫一支Driver來控制硬碟發送ATA command,必須了解三份Spec
  1. ATA (AT Attachment): 這是一份軟體的spec,定義了command的種類
  2. AHCI or IDE : 這是controller的spec, 說明如何控制controller發出ATA command給碟機
  3. SATA :定義HW(phy)的行為,如power management及一些encoding/decoding, Link規則...等等 
這邊列舉一些常見的ATA command, 並以我開發的tool, 下圖,來介紹一些常見的command。



  • 25h: Read DMA ext: 傳統的Read
  • 35h: Write DMA ext: 傳統的Write
  • 60h: Read FDMA Queued :這就是 NCQ read
  • 61h: Write FDMA Queued :NCQ write
  • ECh: Identify : 這個command帶有512Byte的table,用來提供host查詢碟機的能力
  • E0h: Standby Immediately: 用於斷碟機電前, host發此命令告訴碟機
  • EFh: Set feature: host可以透過這個command來開啟碟機一些能力,如Partial/Slumber...
  • 06h: Data Set Management :這就是Trim command,用來告訴碟機哪些LBA是無效的資料請碟機刪掉。這個command對SSD尤其重要,若沒有這個command, SSD firmware 裡的GC(Garbage Collection)將不會回收一些無效的LBA而導致硬碟用久後效能低落
  • 92h: Download Microcode: 碟機廠家用此command來update 碟機內部的firmware


2014年5月24日 星期六

SATA Power Management

SATA PHY有四種state, 需要注意回到PHYRDY的時間有沒有follow spec
  1. PHYRDY
  2. Partial:  <10us
  3. Slumber: <10ms
  4. DevSleep: <20ms
發動的時機有兩種: HIPM / DIPM,一個是Host主動發起,一個是device主動發。

想知道這個碟機有support什麼樣的power management能力可以看Identify table

 Word 76, bit 9: Support HIPM
 Word 76, bit 14: Support Device auto slumber
 Word 78, bit 3: Support DIPM
 Word 78, bit 8: Support DEVSLP
 Word 79, bit 3: Enable DIPM
 Word 79, bit 8: Enable DEVSLP

以下是控制AHCI controller來做HIPM/DIPM實驗:

HIPM:

  Partial:
  • PxCMD &= (~CMD_ASP) //mute bit 27
  • PxCMD |= CMD_ALPE //set bit 26
  • PxSCTL.IPM =0 // mute bit 11~8

 Slumber:
  • PxCMD |= CMD_ALPE | CMD_ASP //set bit 26 & bit 27
  • PxSCTL.IPM =0 // mute bit 11~8

發個ATA command來trigger, 然後Check PxSSTS.IPM 就知道有沒有成功


DIPM:

 發ATA command(Set Feature, EFh) 開啟碟機這項功能


2014年4月26日 星期六

IDE (Integrated Drive Electronics) controller

IDE是早期用來控制碟機的spec, 目前已完全被AHCI所取代。

Q: 為什麼還是要學IDE protocol呢?
A: 因為Intel目前為止的設計,還是保留著支援IDE的彈性,在一些老系統(如xp)也只有IDE driver。通常都會讓使用者自行透過Bios選項將AHCI controller切換成IDE controller,這時Driver/Bios的控制硬碟方式就要改成IDE,所以還是有學習的價值。

Q: Why not default use IDE in modern PC?
A: IDE原理是控制IO register去下ATA command,除了速度慢以外。最大問題是他的設計是古老的思維而限制住他未來擴充的彈性,因此在2003年Intel release AHCI 用以取代IDE。

+ 本文開始 +

spec請參考以下這三分。古老的spec設計通常都比較簡單易懂
  1. PCI IDE Controller Specification Revision  1.0    3/4/94
  2. Programming Interface for Bus Master IDE Controller Revision  1.0     5/16/94
  3. Information Technology - AT Attachment - 8 ATA/ATAPI Command Set 
一個IDE controller規定了四個channel, 基本上有兩種mode, Compatibility and Native。

Compatibility mode:
  • 固定的IO register(Primary cmd/ctrl = 0x1f0~0x1f7/0x3f6, Secondary cmd/ctrl = 0x170~0x177/0x376)位址和固定的IRQ(14, 15)。
Native mode:
  • 由系統來assign: Primary cmd/ctrl = bar#0/bar#1, Secondary cmd/ctrl = bar#2/bar#3, 
需要注意的是control register 的位址是 ctrl port + 2

Q: 如何知道現在這個IDE是Compatibility or Native?
A: 在PCI header, Base-Class(09h), Sub-Class(0Ah), Interface:(0Bh) 定義了class code, 如果programmable indicator 不是fixed,operating mode可由程式來填入改變

Programmable Indicator: Indicate if controller support both mode (1), or fixed mode(0)
Operating Mode: Determine mode (0: compatibility, 1: native) 
Q: 如何找到硬碟插在哪個channel上並且發送ATA command?
A: 可以透過設定device register的bit 4, 然後看status是否回0x50來判斷channel上是否有device, 


接著請參考ATA spec定義的欄位,填寫要發的 command


Q: Bus Master code怎麼寫?
A: Bar#4 給定了Bus Master IO base address, 剩下的部分請參考圖,和原文spec step by step, 照做就可以把code寫出來了。


注意Command Register的Bit 3(read/write control), 下read command 時 bit3要設為 1, write command 時 bit3設為 0
programming bus master IDE, 請參考以下原文
3.1. Standard Programming Sequence
To initiate a bus master transfer between memory and an IDE DMA slave device, the following steps are required:

1) Software prepares a PRD Table in system memory. Each PRD is 8 bytes long and consists of an address pointer to the starting address and the transfer count of the memory buffer to be transferred. In any given PRD Table, two consecutive PRDs are offset by 8-bytes and are aligned on a 4-byte boundary.


2) Software provides the starting address of the PRD Table by loading the PRD Table Pointer Register . The direction of the data transfer is specified by setting the Read/Write Control bit. Clear the Interrupt bit and Error bit in the Status register.


3) Software issues the appropriate DMA transfer command to the disk device.


4) Engage the bus master function by writing a '1' to the Start bit in the Bus Master IDE Command Register for the appropriate channel.


5) The controller transfers data to/from memory responding to DMA requests from the IDE device.


6) At the end of the transfer the IDE device signals an interrupt.


7) In response to the interrupt, software resets the Start/Stop bit in the command register. It then reads the controller status and then the drive status to determine if the transfer completed


successfully.




2014年4月5日 星期六

AHCI (Advanced Host Controller Interface)

AHCI是PC架構下常見的儲存裝置控制器,透過AHCI我們可以將ATA command以SATA的形式發送給device。

一個AHCI controller最多可以implement 32個port,AHCI spec厲害的地方是定義了NCQ command。也就是host可以先發送最多32個command給device, 由device來決定要先做哪個command。近年來拜NAND flash快速發展所賜, 配上NCQ command,硬碟終於可以跑到接近SATA 3所定義的物理極速600MB/s。請參考下面這張TOSHIBA 120G的SSD跑分


焦點拉回spec,AHCI在PC架構上是一個PCI 或PCIe controller, 他的class code是Rx[B:9]=0x010601。

MMIO base address定義在PCI CFG header就Bar#4,在開機時,Bios會依照AHCI spec要求assign 一個align to 8KB的MMIO的base address。access MMIO address 可以看到General Host Control Registers(0~0xFF) + port0~31 (每個port range為0x80)這兩大部分


從GHC registers我們可以知道這個controller的能力如這個AHCI controller implement哪些port可以讓software使用,發生中斷的原因以及透過這些register做Global host reset。

至於對某個port上的硬碟發command最主要是透過port control registers來辦到。透過port的register我們也可以發port reset這種局部reset來命令此port的SATA phy重新link。

Q: 如何對port發command?
A: 首先先把記憶體宣告好,把要發的command以 command FIS型態填在宣告的記憶體上,如果是帶資料的command則還需要把PRD Table描述好,並將其指到一個準備傳送或接收資料的記憶體位址(注意必須是Word aligned)。最後去set PxCI,command就可以發到碟機了。

最後附上精心製作的AHCI register表,祝大家都可以寫出屬於自己的AHCI driver


Overall Registers layout

PRDT layout



2014年3月5日 星期三

SATA Spec

1. 介紹SATA的四個Layer:


•Application Layer:  
  • Overall  ATA  command  execution

•Transport Layer:  
  • Placing control information and data to be transferred between the host and device in a packet/frame (FIS)

•Link Layer:  
  • Taking data from the constructed  frames, encoding  or  decoding each byte using 8b/10b, and inserting control characters such that the 10-bit stream of data may be decoded correctly

•Physical Layer: 
  • Transmitting and receiving the encoded information as a serial data stream on the wire
2. Primitive
    用來控制和提供串列線路的狀態,由4個Byte所組成

3. BURST:  
  • OOB signaling is a pattern of ALIGNP primitives or Dwords composed of D24.3 characters and idle time and is used to initialize the Serial ATA interface (由特定的Primitive或4個D24.3所組成)
4. OOB信號:
  • COMRESET (Originate from Host)/ COMINIT (Originate from Device)
  • COMWAKE (for both host & device)
  • Consists of 6 bursts with different time gap

5. Speed negotiation:



6. SATA FIS:





2013年12月23日 星期一

Differential signaling, 差分/動信號

電磁學有一章節專門討論傳輸線,有一種傳輸線叫做雙線式傳輸線目前廣泛用在電子信號傳輸,如SATA的TX/RX, PCIe的DQS, clock, USB...等等

這種差分信號的好處是可以抗雜訊,但是設計上就較複雜因為晶片要有能力把信號載到射頻上。

因為是射頻的信號,因此要提到特徵阻抗(Characteristic impedance)這個東西,特徵阻抗是電場和磁場的一個比值,單位是歐姆,他和傳輸線的材質/尺寸相關。若不是高頻使用的傳輸線,則傳輸線上的每一點特徵阻抗都會有差異,造成信號的反射(衰減)。

以SATA為例(下圖),SATA傳輸線的特徵阻抗為100Ohm+/-10%,如果信號不好通常就是調整眼圖(Eye Pattern)的參數Emphasis (pre-emphasis / de-emphasis)和Amplitude。
  • Emphasis是信號high, low互相轉換時的斜率
  • Amplitude是信號的振幅
下圖介紹眼圖裡面SNR, Jitter等名詞
圖片出處 (Eye Diagram Basics: Reading and applying eye diagrams)