2

我有一个旧硬盘驱动器,我打算稍微摆弄一下。我要做的第一件事是以不同的速度旋转电机。

问题是:

  1. 有没有一种通用的方法可以做到这一点,还是取决于硬盘型号?
  2. 我在哪里可以找到可以发送到 HDD 控制器以控制电机速度的命令列表?

我实际上找到了一个功能,它显然会使电机减速,这里是:

/* spin-down a disk */
static void spindown_disk(const char *name)
{
  struct sg_io_hdr io_hdr;
  unsigned char sense_buf[255];
  char dev_name[100];
  int fd;

  dprintf("spindown: %s\n", name);

  /* fabricate SCSI IO request */
  memset(&io_hdr, 0x00, sizeof(io_hdr));
  io_hdr.interface_id = 'S';
  io_hdr.dxfer_direction = SG_DXFER_NONE;

  /* SCSI stop unit command */
  io_hdr.cmdp = (unsigned char *) "\x1b\x00\x00\x00\x00\x00";

  io_hdr.cmd_len = 6;
  io_hdr.sbp = sense_buf;
  io_hdr.mx_sb_len = (unsigned char) sizeof(sense_buf);

  /* open disk device (kernel 2.4 will probably need "sg" names here) */
  snprintf(dev_name, sizeof(dev_name), "/dev/%s", name);
  if ((fd = open(dev_name, O_RDONLY)) < 0) {
    perror(dev_name);
    return;
  }

  /* execute SCSI request */
  if (ioctl(fd, SG_IO, &io_hdr) < 0) {
    char buf[100];
    snprintf(buf, sizeof(buf), "ioctl on %s:", name);
    perror(buf);

  } else if (io_hdr.masked_status != 0) {
    fprintf(stderr, "error: SCSI command failed with status 0x%02x\n",
            io_hdr.masked_status);
    if (io_hdr.masked_status == CHECK_CONDITION) {
      phex(sense_buf, io_hdr.sb_len_wr, "sense buffer:\n");
    }
  }

  close(fd);
}

虽然我并不真正了解实际命令发送到控制器的位置,也不知道如何控制速度,但我没有看到任何 rpm 规格。

4

1 回答 1

4

你无法控制硬盘的转速,这是一件好事。如果可以,您将不可避免地破坏数据。

头部漂浮在通常称为“空气轴承”的地方。简而言之,这是一个弹簧机构将磁头压在磁盘表面上,由于磁盘的旋转在磁盘的运行速度下达到平衡,因此具有明确定义的力和来自气流的空气冲击。当磁盘关闭时,另一个弹簧机构迅速将磁头拉到一种“停放位置”。

如果您可以以任意速度运行驱动器,则磁头会在表面上刮擦。不好!

至于在上面的代码段中实际命令的发送位置,它是ioctl以下行中的调用/* execute SCSI request */
如果您对使用旧硬盘感兴趣(请注意,您很可能会破坏它!),请查看该hdparm工具及其源代码。hdparm让您可以调整数十个参数,例如省电模式、缓存或声音管理……几乎所有磁盘驱动器都支持。
在该工具的源代码中,您还可以找到完整的设备命令列表。

于 2014-02-20T15:40:52.983 回答