Назад
NetBSD: розбираємо disklabel по байтах
SiTech AI Team3 წთ. საკითხავი

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.

Hex-дамп заголовка disklabel із позначеними полями

Таблиця розділів і контрольна сума

Заголовок оголошує 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 легко не помічати і що звикнути допомогла лише практична робота.

SSiTech

SiTech — веброзробка з підтримкою AI

Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.