Причина "нередактируемости" некоторых атрибутов видимо в том, что начиная со смещения
SMART sector 386 (0x182) идут еще vendor-specific поля, в которых некоторые атрибуты по
непонятной системе дублируются (надо искать документацию для Seagate's HDD). Я нашел
поле, где дублировались часы работы, но установка их одинаковым с основным полем часов
не решила проблему, часы работы сбрасываются при первом же чтении SMART, или
инкременте счетчика часов, или команде 1>N02 в терминале.
При редактировании же исходного SMART (диск TONKA2 80GB, SATA), у меня возвращались к
исходным сбойные атрибуты 197 и 198 (они установились в 0xFFFFFFFF,те (2^32-1) видимо
из-за сбоя SMART). Я нашел последовательность FFFFFFFF по адресу 0x5AA vnd_track, и изменил на
00000000. После этого возврат к 0xFFFFFFFF происходить перестал.
Я писал только один отредактированный SMART сектор, а SMART логи я сбросил ранее. Такие же
атрибуты как start/stop, UDMA CRC error, reallocated sectors, reported uncorrect,
power cycle count - редактировались без проблем. Val, да ставится сам по raw, но на всякий
случай в программе он тоже задается.
Вот такой программой я пользовался
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <sys/types.h>
#define SMART_OFFSET 0x400L
#define ENTRY_SIZE 12
#define RADIX 0 //auto detection base
int main(int argc, char *argv[]) {
/* Variables declarations*/
unsigned short int i;
uint8_t att_entry[ENTRY_SIZE];
uint16_t struct_ver;
uint8_t cmd_id, cmd_val, cmd_worst;
uint32_t cmd_raw;
uint32_t* raw_val;
FILE* vnd_trk;
if(argc < 2) {
printf("SMART sector editor\n");
printf("Usage: smartatt <input_file> [id val worst raw]\n");
exit(EXIT_SUCCESS);
}
vnd_trk = fopen(argv[1],"rb+");
if (vnd_trk == NULL) {
perror(argv[1]);
exit(EXIT_FAILURE);
}
fseek(vnd_trk, SMART_OFFSET, SEEK_SET);
fread(&struct_ver, 2, 1, vnd_trk);
printf("SMART structure version 0x%04x\n", struct_ver);
for (i=1; i <= 42 ; i++) { //42
if (feof(vnd_trk)) {
printf (" Input file too short, stop\n");
break;
}
fread(att_entry, ENTRY_SIZE, 1, vnd_trk);
if (!att_entry[0])
break;
if (argc == 6) {
cmd_id = (uint8_t)strtol(argv[2], NULL, RADIX);
if (cmd_id == att_entry[0]) { //if id equal to cmd line arg
cmd_val = (uint8_t)strtol(argv[3], NULL, RADIX);
cmd_worst = (uint8_t)strtol(argv[4], NULL, RADIX);
cmd_raw = (uint32_t)strtol(argv[5], NULL, RADIX);
raw_val = (uint32_t*)&att_entry[5];
//write val
fseek(vnd_trk, -9, SEEK_CUR);
fwrite(&cmd_val, sizeof(uint8_t), 1, vnd_trk);
//write worst
fwrite(&cmd_worst, sizeof(uint8_t), 1, vnd_trk);
//write raw value
fwrite(&cmd_raw, sizeof(uint32_t), 1, vnd_trk);
fseek(vnd_trk, +3, SEEK_CUR);
//update att entries
att_entry[3] = cmd_val;
att_entry[4] = cmd_worst;
*((uint32_t*)&att_entry[5]) = cmd_raw;
}
}
printf("ID %03d, flags 0x%02x%02x, val %03d, worst %03d, %10u\n",
att_entry[0], att_entry[2], att_entry[1], att_entry[3],
att_entry[4], *((uint32_t*)&att_entry[5]));
}
fclose(vnd_trk);
return 0;
}
Все числа вводятся по правилам Си, те например 077 - восьмеричное, 77 - десятичное,
0x77 шестнадцатеричное (тк RADIX 0)
./smartatt file просмотр атрибутов, file - файл vnd track, с редактируемым SMART сектором по смещению 0x400
./smartatt file id val worst raw - редактирование атрибута id, выставляем параметры val worst raw