【发布时间】:2010-12-17 16:57:30
【问题描述】:
我正在尝试直接从磁盘读取单个特定扇区。我目前已经没有什么想法了,任何如何去做的建议都会很棒!
【问题讨论】:
-
您可以使用 dd 来完成此操作,或者您可以编写一个 c 程序并使用 write sys 调用。
我正在尝试直接从磁盘读取单个特定扇区。我目前已经没有什么想法了,任何如何去做的建议都会很棒!
【问题讨论】:
尝试从 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 位类型。
我不确定最好的编程方法是什么,但在 Linux 命令行中,您可以将 dd 命令与磁盘的原始设备结合使用以直接从磁盘读取。
您需要 sudo 这个命令才能访问原始磁盘设备(例如 /dev/rdisk0)。
例如,下面将从disk0顶部900个块的偏移处读取单个512字节块,并将其输出到stdout。
sudo dd if=/dev/rdisk0 bs=512 skip=900 count=1
请参阅 dd 手册页以获取有关 dd 参数的更多信息。
【讨论】:
sudo dd if=/dev/sda bs=512 skip=900 count=1 | hexdump -C
在 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);
}
【讨论】:
其他人几乎涵盖了它。你需要
访问磁盘的设备文件(要么是 root,要么最好更改它的权限)
使用文件 IO 函数从所述磁盘读取扇区 =(通常)512 字节的块。
【讨论】:
另一种选择是使用hdparm
例如-
hdparm --read-sector 16782858 /dev/sda
【讨论】: