
NetBSD: розбираємо disklabel по байтах
Практичний розбір мітки BSD у NetBSD 11: де зберігається мітка на диску, що означає кожне поле заголовка, як рахується контрольна сума XOR і як створити розділ у hex-редакторі.
Допис у блозі movq.de розбирає BSD disklabel у NetBSD 11 на x86_64. Автор каже, що прийшов із DOS і Linux і майже не звертав уваги на мітки дисків у власних системах OpenBSD. Він хотів з'ясувати, що означає кожен байт, де задокументовано цей формат і яку частину можна правити вручну.
Де зберігається мітка
Пошук документації починається з man disklabel, у розділі SEE ALSO якого вказано disklabel(5). Здебільшого автор читав /usr/include/sys/disklabel.h безпосередньо. Щоб уникнути конфліктів із системами MBR, мітки зберігаються не там, де звична таблиця MBR: невелика програма мовою C, зібрана з libutil, повертає 1 для getlabelsector() і 0 для getlabeloffset(), тобто мітка лежить у другому секторі, за зсувом 512 байтів.
Заголовок поле за полем
Мітка починається з метаданих диска, а завершується масивом розділів. У little-endian видно два магічні числа (d_magic і d_magic2), тип диска 0x0f, тобто logical disk, та ім'я драйвера ld1, а далі йде геометрія: 512 байтів на сектор, 63 сектори на доріжку, 16 доріжок на циліндр, 260 циліндрів і загалом 262144 сектори, тобто 128 MiB. Параметри старого обладнання, як обертання 3600 rpm і часи пошуку, на сучасних x86_64 здебільшого дорівнюють нулю, а MBR із залишками CHS не набагато кращий; значення з hex-дампу збігаються з виводом disklabel ld1.
Таблиця розділів і контрольна сума
Заголовок оголошує d_npartitions, далі йдуть записи по 16 байтів для розділів від a до d. Справді важливі лише три поля: початок, розмір і тип файлової системи. Розділ a має 262144 сектори від зсуву 0 і тип 0x07, тобто 4.2BSD (FFS). Розділ d на x86_64 присутній завжди й описує весь диск, як пояснив розробник NetBSD Мартін Гуземан; c не показується, бо її розмір, зсув і тип нульові.
d_checksum описано як xor даних, включно з розділами. XOR усіх 16-бітних фрагментів мітки дає нуль, що підтверджує узгодженість збереженого значення, адже сама сума є одним із цих фрагментів. Якщо її виключити, виходить 1dc6, як і c61d у дампі. Відповідний код NetBSD, ймовірно, це dkcksum.c у sys/lib/libkern.
Розділ, створений у hex-редакторі
Далі він зробив зворотне: задав розділ i завдовжки 1234 сектори, що починається із сектора 5678, типу ZFS. Дев'ятий запис починається на байті 788, що обчислюється як 512 + 0x94 + (9-1) * 16. Записано p_size, p_offset і p_fstype 0x21, d_npartitions збільшено до 9, а контрольну суму перераховано як 160f.
Після завантаження disklabel ld1 показав новий розділ саме так, як задумано, і попередив, що розділи a та i перекриваються; це очікувано, бо a займає весь диск. Автор зауважує, що додатковий шар над MBR і GPT легко не помічати і що звикнути допомогла лише практична робота.
SiTech — веброзробка з підтримкою AI
Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.