【问题标题】:Read a single sector from a disk从磁盘读取单个扇区
【发布时间】:2010-12-17 16:57:30
【问题描述】:

我正在尝试直接从磁盘读取单个特定扇区。我目前已经没有什么想法了,任何如何去做的建议都会很棒!

【问题讨论】:

  • 您可以使用 dd 来完成此操作,或者您可以编写一个 c 程序并使用 write sys 调用。

标签: linux io kernel


【解决方案1】:

尝试从 CLI 执行类似的操作:

# df -h .
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              27G   24G  1.6G  94% /
# dd bs=512 if=/dev/sda2 of=/tmp/sector200 skip=200 count=1
1+0 records in
1+0 records out

来自man 4 sd

FILES
   /dev/sd[a-h]: the whole device
   /dev/sd[a-h][0-8]: individual block partitions

如果您想在程序中执行此操作,只需将来自man 2 ... 的系统调用(如open, lseek,read)与dd 示例中的参数结合使用。

【讨论】:

  • 鉴于当今磁盘的大小,请使用lseek64()#define _FILE_OFFSET_BITS 64 以确保off_t 是64 位类型。
  • 能否请您提供一些特定于 c 编程语言的函数来读写磁盘扇区?
【解决方案2】:

我不确定最好的编程方法是什么,但在 Linux 命令行中,您可以将 dd 命令与磁盘的原始设备结合使用以直接从磁盘读取。

您需要 sudo 这个命令才能访问原始磁盘设备(例如 /dev/rdisk0)。

例如,下面将从disk0顶部900个块的偏移处读取单个512字节块,并将其输出到stdout。

sudo dd if=/dev/rdisk0 bs=512 skip=900 count=1

请参阅 dd 手册页以获取有关 dd 参数的更多信息。

【讨论】:

  • 磁盘设备在 Linux 下通常不称为 /dev/rdisk0,你可能想要 /dev/sda 之类的东西
  • 是否跳过/搜索让我进入物理扇区或逻辑块?
  • 这实际上并没有为我在屏幕上打印任何东西,直到我将它传送到 hexdump 中,例如sudo dd if=/dev/sda bs=512 skip=900 count=1 | hexdump -C
【解决方案3】:

在 C 中,它类似于以下内容...它需要 root 权限。如果您想读取单个扇区,我认为您需要使用 O_DIRECT 打开文件。否则你会得到一个页面。我不确定读取是否需要对齐的缓冲区,但它是用于写入的。

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SECTOR_SIZE 512

int main(int argc, char *argv[]) {
        int offset = 0;
    int length = 5;
    int rc = -1;

    char *sector = aligned_alloc(SECTOR_SIZE, SECTOR_SIZE);
    memset(sector, 0, SECTOR_SIZE);
    /* replace XXX with the source block device */
    int fd=open("/dev/XXX", O_RDWR | O_DIRECT);

    lseek(fd, offset, SEEK_SET);
    for (int i = 0; i < length; i++) {
        rc = read(fd, sector, SECTOR_SIZE);
        if (rc < 0)
            printf("sector read error at offset = %d + %d\n %s", offset, i, strerror(errno));
        printf("Sector: %d\n", i);
        for (int j = 0; j < SECTOR_SIZE; j++) {
            printf("%x", sector[i]);
            if ((j + 1) % 16 == 0)
                printf("\n");
        }
    }
    free(sector);
    close(fd);
}

【讨论】:

    【解决方案4】:

    其他人几乎涵盖了它。你需要

    • 访问磁盘的设备文件(要么是 root,要么最好更改它的权限)

    • 使用文件 IO 函数从所述磁盘读取扇区 =(通常)512 字节的块。

    【讨论】:

    • 能否请您提及一些特定的 c 编程语言函数,用于在扇区上读写
    【解决方案5】:

    另一种选择是使用hdparm

    例如-

    hdparm --read-sector 16782858 /dev/sda
    

    【讨论】:

      猜你喜欢
      • 2020-02-03
      • 2020-10-11
      • 2013-11-20
      • 2023-03-23
      • 2013-06-04
      • 2014-04-30
      • 2019-12-05
      • 1970-01-01
      • 2017-12-04
      相关资源
      最近更新 更多