2012年7月12日 星期四

分辨HD和SSD (solid state device)

關於如何在BIOS分辨一般硬碟和SSD固態硬碟的方法,一開始就想到,應該是由HDD的INFO去查,在ATA的spec中,有個identify device的指令0xEC,可以識別硬碟的型號等資訊,但是這SPEC可能是在SSD開發前就定好的,應該看哪一個欄位來判斷呢?

如果判斷identify info 有設"Compact Flash" (word 7, 8),那麼只能代表它"有可能"是SSD。
在Google後的結果,並不容易找到答案,也許問硬碟廠商是最快的。找到的是在Linux 下有一個指令可以查,它會回傳rotational,它的作法是判斷identify Word[217]欄位,它原本spec定義的是rotation rate(轉速),它如果設為0x0001,就代表它是SSD,這是現在SSD硬碟廠的作法。下表為ATA8 的定義:

在BIOS要實作這個判斷,也不會很困難,只要找一個硬碟初始化好的點去下硬碟指令,把identify data給讀出來判斷第217 word是否為1即可。

=================================

[轉貼] setmax.c

#include <stdio.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/hdreg.h>

int get_identity (int fd)
{
    int i=0;
    unsigned char args[4+512] = {WIN_IDENTIFY,0,0,1,};
    struct hd_driveid *id = (struct hd_driveid *)&args[4];
    if (ioctl(fd, HDIO_DRIVE_CMD, &args))
    {  
        perror("HDIO_DRIVE_CMD");
        fprintf(stderr,
            "WIN_IDENTIFY failed - trying WIN_PIDENTIFY\n");
        args[0] = WIN_PIDENTIFY;
        if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
            perror("HDIO_DRIVE_CMD");
            fprintf(stderr,
                   "WIN_PIDENTIFY also failed - giving up\n");
            return 0;
        }  
    }
    for (i=0;i<49;i++)
        printf("word[%d] = %d\n", i+206, id->words206_254[i]);
}

int main (void)
{
    int fd = open("/dev/sda", O_RDONLY|O_NONBLOCK);
    get_identity(fd);
    close(fd);
    return 0;
}

//word[217]=5400 的話,根據spec,是轉速。 
  word[217]=1 時是ssd

ref :
  1. 法蘭克的BIOS筆記
  2. Linux & Advanced Storage Interfaces
  3. setmax.c
  4. AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
  5. ATA messages via SCSI layer

沒有留言:

張貼留言