Предыстория
Перед новогодними праздниками в RAID массиве «зеркало» состоящем из двух дисков Kingston SKC2500M8/250G отказал один. Логи ядра не сохранились. При попытке записи на диск система «висла» и переставала отвечать.
Первое предположение было на программный сбой, так как SMART дисков сообщал об 1 % износе. Мои диски имели два слота с прошивками: "заводскую" прошивку "S7780101" (с покупки) и обновленную версию "S7780102" (обновлял с использованием Kingston SSD Manager или nvme-cli после покупки):
nvme fw-log /dev/nvme0
Firmware Log for device:nvme0
afi : 0x11
frs1 : 0x3230313038373753 (S7780102)
frs2 : 0x3130313038373753 (S7780101)
Переключил контроллер на "заводскую" прошивку и запустил тесты с записью, но ситуация не поменялась. Как потом выяснил, перепутал NVMe диск по невнимательности и усталости после рабочего дня, переключение осуществил на исправном диске, а тестил отказавший.
Замечательная статья "Solid state drive/NVMe" от сообщества Arch Linux, рассказывает как посмотреть доступные слоты в контроллере, как обновлять прошивку в слоте, как переключался между ними в рантайме.
Проблема с программным сбоем не подтвердилась. Разобрал ПК и перешел к визуальному осмотру. На большей части поверхности диска с платой обнаружились подтеки от термопрокладки. Диск был очищен спиртом изопропиловым, термопрокладка замененена. После этих манипуляций диск снова в строю и прекрасно себя чувствует.
Казалось бы, на этом историю можно заканчивать, но мой интерес пал на новую прошивку предоставленную Kingston на своих серверах, которую успел обнаружить.
Предыстория 2. Kingston SSD Manager
До истории со сбоем, после покупки и установки дисков в ПК, обновил диски с вендорским ПО "Kingston SSD Manager". При обновлении захватил сетевые пакеты и проанализировал куда обращается ПО.
Первый запрос:
https://media.kingston.com/support/downloads/ssd-rules-latest.zip.
В архиве CVS файл со списком актуальных прошивок.
Следующее обращение было к этой прошивке:
https://media.kingston.com/support/downloads/S7780102-210429.zip;
sha256: d4c316347c2f50c01ee053c12d36f530dfd554fa8db1b173ade543595694dbec.
С данной версией прекрасно работает nvme-cli и позволяет обновлять прошивку дисков.
Сейчас на сервере она недоступна, но есть новая версия:
https://media.kingston.com/support/downloads/S7780102-240402.zip;
sha256: 1355a473cf150d7ad13425c315236d5a42199d2adfc55cd991f93d11fa549e57.
Release notes сообщает, что это та же версия на которую уже обновил диски. ПО Kingston SSD Manager не предлагало мне обновиться, это тоже проверил. Дополнительно заметил, что nvme-cli уже не позволяет обновиться с новой версией прошивки. Это и побудило мой интерес разобраться что к чему.
Пояснение: старой версией - называю версию из архива "S7780102-210429.zip", соответсвенно новой - "S7780102-240402.zip". "Заводской" версии "S7780101" у меня нет.
Попробую разобраться чем отличается старый образ от нового.
Исследование новой прошивки
Размер старой прошивки: 1315840, новой: 1315984. Разница в 144 байта.
Визуальный осмотр нового образа показывает наличие упоминания вендора "KINGSTON" в начале файла:
xxd -g 1 ./S7780102.bin | head -25
00000000: 4b 49 4e 47 53 54 4f 4e 20 20 20 20 20 20 80 10 KINGSTON ..
00000010: 82 11 46 b5 e8 00 28 fd 10 4f 17 01 b8 84 55 39 ..F...(..O....U9
00000020: c9 17 39 59 4c 32 d7 68 e0 a2 33 f4 b5 06 10 91 ..9YL2.h..3.....
00000030: 85 a4 32 9a 41 06 1b 81 44 a1 f9 1b 5d 47 09 2c ..2.A...D...]G.,
00000040: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
00000050: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
00000060: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
00000070: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00000080: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
00000090: 84 11 46 b5 49 00 28 fd 10 4f 16 01 b8 84 55 29 ..F.I.(..O....U)
000000a0: a6 05 39 59 4f 20 c3 48 e0 a7 36 f4 f5 06 10 91 ..9YO .H..6.....
000000b0: c5 a4 32 9a 40 06 1b 81 44 a1 f9 1b 5e 47 09 2c ..2.@...D...^G.,
000000c0: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
000000d0: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
000000e0: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
000000f0: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00000100: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
00000110: 82 11 46 b5 e8 00 28 fd 10 4f 17 01 b8 84 55 39 ..F...(..O....U9
00000120: c9 17 39 59 4c 32 d7 68 e0 a2 33 f4 b5 06 10 91 ..9YL2.h..3.....
00000130: 85 a4 32 9a 41 06 1b 81 44 a1 f9 1b 5d 47 09 2c ..2.A...D...]G.,
00000140: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
00000150: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
00000160: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
00000170: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00000180: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
Так же обратил внимание что в старом файле начиная с адреса 0x113200 идет последовательность заполненная "0x00".
Рассмотрим что у нас в конце нового файла:
xxd -g 1 ./S7780102.bin | tail -24
00141310: 82 11 46 b5 e8 00 28 fd 10 4f 17 01 b8 84 55 39 ..F...(..O....U9
00141320: c9 17 39 59 4c 32 d7 68 e0 a2 33 f4 b5 06 10 91 ..9YL2.h..3.....
00141330: 85 a4 32 9a 41 06 1b 81 44 a1 f9 1b 5d 47 09 2c ..2.A...D...]G.,
00141340: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
00141350: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
00141360: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
00141370: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00141380: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
00141390: 82 11 46 b5 e8 00 28 fd 10 4f 17 01 b8 84 55 39 ..F...(..O....U9
001413a0: c9 17 39 59 4c 32 d7 68 e0 a2 33 f4 b5 06 10 91 ..9YL2.h..3.....
001413b0: 85 a4 32 9a 41 06 1b 81 44 a1 f9 1b 5d 47 09 2c ..2.A...D...]G.,
001413c0: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
001413d0: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
001413e0: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
001413f0: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00141400: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
00141410: 82 11 46 b5 e8 00 28 fd 10 4f 17 01 b8 84 55 39 ..F...(..O....U9
00141420: c9 17 39 59 4c 32 d7 68 e0 a2 33 f4 b5 06 10 91 ..9YL2.h..3.....
00141430: 85 a4 32 9a 41 06 1b 81 44 a1 f9 1b 5d 47 09 2c ..2.A...D...]G.,
00141440: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
00141450: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
00141460: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
00141470: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00141480: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
Части данных в диапазоне адресов 0x141390 - 0x14140F и 0x141410 - 0x141480 одинаковые. Можно сделать вывод, что используемый алгоритм работает с блоками в 128 байт и для блоков не используется обратная связь.
Еще можно заметить что последовательности 0x141390 - 0x14140F и 0x141410 - 0x141480 соответствуют последовательности 0x10 - 0x8F в части содержащихся данных:
xxd -g 1 ./S7780102.bin | head -9
00000000: 4b 49 4e 47 53 54 4f 4e 20 20 20 20 20 20 80 10 KINGSTON ..
00000010: 82 11 46 b5 e8 00 28 fd 10 4f 17 01 b8 84 55 39 ..F...(..O....U9
00000020: c9 17 39 59 4c 32 d7 68 e0 a2 33 f4 b5 06 10 91 ..9YL2.h..3.....
00000030: 85 a4 32 9a 41 06 1b 81 44 a1 f9 1b 5d 47 09 2c ..2.A...D...]G.,
00000040: f1 1b 64 28 8e 3f ab 6b ac 8b f4 ea 76 e7 e7 82 ..d(.?.k....v...
00000050: e4 32 f9 7d 67 35 a9 f5 7f ad 3e a1 08 55 53 33 .2.}g5....>..US3
00000060: 00 6b 48 57 91 47 4e 88 c7 da 31 b5 89 b9 1f 6e .kHW.GN...1....n
00000070: e1 82 7e 20 a0 c6 16 98 e2 53 1c c2 12 ec fd e7 ..~ .....S......
00000080: 55 db d6 e2 1d ec 73 95 b5 bb f0 fd 88 63 32 c6 U.....s......c2.
По адресу 0x0E имеем значение 0x80 что соответствует 128, а по адресу 0x0F - значение 0x10.
Делаю первое предположение, первые 16 байт содержат наименование вендора и указание на адрес 0x10 с длиной ключа в 128 байт. Это как раз соотносится с различием в размере файлов. С адреса 0x90 начинается тело прошивки, там последовательность данных начинает отличатся от озвученных ранее.
Пробую применить XOR к данным по блокам в 128 байт начиная с адреса 0x90 и до конца файла - первый аргумент, и ключем с данными по адресу 0x10 с длиной 128 байт - второй аргумент.
На выходе получаю файл с контрольной суммой sha256: 8eafb35b14b568806b901159a953e9f40e10dfafd2e1cd09d3910b76ef3cb9b4. Что полностью соответствует старой версии прошивки.
Вендор изменил формат прошивки и он стал нестандартным, поэтому nvme-cli и соответсвенно контроллер диска NVMe отказывается ее принимать и записывать в слот.
Итого
Разобрался с новым форматом вендора для предоставляемых прошивок.
Вернул возможность обновления прошивок под ОС GNU/Linux с инструментом nvme-cli.
Удовлетворил свое любопытство и смог наглядно подтвердить что "новая" прошивка действительно соответствует уже развернутой.
Бонус: репа с готовым скриптом unpack-kngstn-ssd-fw.
rseleven Автор
Спасибо @Exosphere за помощь с публикацией!