代码之家  ›  专栏  ›  技术社区  ›  Kornel

如何在Mac OS X中检测SSD?

  •  9
  • Kornel  · 技术社区  · 15 年前

    是否有可靠、快速、确定的方法(即。 一个基准测试)来检查系统驱动器Mac OS X是否为固态驱动器?

    Device Characteristics 属于 IOAHCIBlockStorageDevice 包含此信息。如何以编程方式阅读它?


    match = IOBSDNameMatching(kIOMasterPortDefault,0,"disk0s2");
    IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iterator);
    while(entry = IOIteratorNext(iterator)) {
       do {
         entry = IORegistryEntryGetParentEntry(nextMedia, kIOServicePlane, &entry);
         dict = IORegistryEntryCreateCFProperty(nextMedia, 
                CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, 0);
         [dict objectForKey:CFSTR(kIOPropertyMediumTypeKey)];
       } 
       while(!dict && entry); 
    }
    

    编辑: Here's complete source code . 我已经验证了它与Intel SSD和OCZ Vertex一起工作。

    3 回复  |  直到 4 年前
        1
  •  5
  •   Georg Schölly Crazy Developer    11 年前

    如果你想得到这样的信息,你最好的猜测是IOKit。

    伊奥雷格 命令行工具或 .


    #import "TWDevice.h"
    
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <errno.h>
    #include <paths.h>
    #include <sys/param.h>
    #include <IOKit/IOKitLib.h>
    #include <IOKit/IOBSD.h>
    #include <IOKit/storage/IOMedia.h>
    #include <CoreFoundation/CoreFoundation.h>
    #include <IOKit/Kext/KextManager.h>
    
    
    @implementation TWDevice
    
    @synthesize name, devicePath, size, blockSize, writable, icon;
    
    + (NSArray *)allDevices {
        // create matching dictionary
        CFMutableDictionaryRef classesToMatch;
        classesToMatch = IOServiceMatching(kIOMediaClass);
        if (classesToMatch == NULL) {
            [NSException raise:@"TWError" format:@"Classes to match could not be created"];
        }
    
        // get iterator of matching services
        io_iterator_t mediaIterator;
        kern_return_t kernResult;
        kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
                                                                          classesToMatch,
                                                                          &mediaIterator);
    
        if (kernResult != KERN_SUCCESS) {
            [NSException raise:@"TWError" format:@"Matching services did not succed."];
        }
    
        // iterate over all found medias
        io_object_t nextMedia;
        NSMutableArray *detectedDevices = [NSMutableArray array];
        while (nextMedia = IOIteratorNext(mediaIterator)) {
            NSMutableDictionary *properties;
            kernResult = IORegistryEntryCreateCFProperties(nextMedia,
                                                                                      (CFMutableDictionaryRef *)&properties,
                                                                                      kCFAllocatorDefault, 0);
    
            if (kernResult != KERN_SUCCESS) {
                [NSException raise:@"TWError" format:@"Getting properties threw error."];
            }
    
            // is it a whole device or just a partition?
            if ([[properties valueForKey:@"Whole"] boolValue] &&
                ![[properties valueForKey:@"RAID"] boolValue]) {
                TWDevice *device = [[[TWDevice alloc] init] autorelease];
    
                device.devicePath = [NSString stringWithFormat:@"%sr%@", _PATH_DEV, [properties valueForKey:@"BSD Name"]];
                device.blockSize = [[properties valueForKey:@"Preferred Block Size"] unsignedLongLongValue];
                device.writable = [[properties valueForKey:@"Writable"] boolValue];
                device.size = [[properties valueForKey:@"Size"] unsignedLongLongValue];
    
                io_name_t name;
                IORegistryEntryGetName(nextMedia, name);
                device.name = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
    
                …
    
                [detectedDevices addObject:device];
            }
    
            // tidy up
            IOObjectRelease(nextMedia);
            CFRelease(properties);
        }
        IOObjectRelease(mediaIterator);
    
        return detectedDevices;
    }
    
    @end
    
        2
  •  7
  •   Ana Betts    15 年前

    事实上,我认为你应该走基准测试路线,因为它更准确地回答了你的问题——你不需要 真正地

    只需从底层/dev/diskX读取一组随机扇区,如果它满足您的要求,您可以将其视为“快速”驱动器

        3
  •  2
  •   fzwo    5 年前

    这似乎只适用于内部驱动器。我找不到使用IOKit查询三星T5外部usb3ssd的方法,也找不到东芝Canvio usbhddd。不过,我确实在MBP中管理了内部驱动器。

    Disk utility也不认为三星是SSD,因此我认为除了测量实际性能之外,可能没有其他方法。

        4
  •  0
  •   Stephan Eggermont    15 年前