Это кросспост моей статьи CPIO под микроскопом. Описание этого формата будет нам необходимо при рассмотрении вопроса создания RamFS. В статье приводятся примеры из HEX-редактора, так что удобнее, на мой взгляд, читать ее через браузер.
CPIO - это достаточно старый (1992 год), но в то же время очень удобный вариант архива. Он достаточно прост, и, возможно поэтому, получил широкое распространение. Например данный формат используют RPM, initramfs ядра Linux, а также установщик архивов "pax" от Apple.
Данный архив позволяет собирать любое число файлов, директори и других объектов файловой системы (символических ссылок и т.д.) в единый поток байт.
Давайте на примерах рассмотрим формат этого архива.
Каждый объект файловой системы в таком архиве состоит из заголовка с базовыми метаданными, за которым следует полный путь к объекту и содержимое этого объекта. Заголовок содержит набор целочисленных значений, которые во много повторяют поля структуры stat(2) файлов в *nix системах. Конец архива помечается специальной записью (аналогичной остальным) названием 'TRAILER!!!'.
Заголовок формата записи имеет следующую структуру:
Здесь предполагается, что тип unsigned short имеет размер 16 бит.
c_magic
Целочисленное значение, равное 070707 (в восьмеричной СС), или 0x71c7 (в шестнадцатеричной СС). Используется для определения порядка байт (little-endian vs big-endian).
c_dev,c_ino
Номера устройства и инода (inode) с диска. Соответствуют значениям, выдаваемым утилитой stat. Если значение inode больше 65535, то старшие разряды будут утеряны.
c_mode
Поле одновременно определяет права доступа и тип объекта:
0170000 Маскирует биты типа файла
0140000 Сокет
0120000 Символическая ссылка. Для символических ссылок, тело ссылки будет содержать путь к файлу, на который та ссылается.
0100000 Обычный файл
0060000 Специальное блочное устройство
0040000 Каталог
0020000 Специальное символьное устройство
0010000 Именованный канал(named pipe) или очередь(FIFO).
0004000 SUID
0002000 SGID
0001000 Sticky bit.
0000777 Младшие 9 бит определяют права доступа к объекту. Соответствует значению, выдаваемому утилитой stat.
c_uid,c_gid
Идентификаторы пользователя и группы владельца файла.
c_nlink
Количество ссылок на этот файл. Для каталогов значение этого поля всегда не меньше 2.
c_rdev
Только для специальных символьных и блочных устройств. Поле содержит ассоциированный номер устройства. Для всех остальных типов файлов значение данного поля должно быть нулевым.
c_mtime
Время последнего изменения файла. Формат соответствует количеству секунд, прошедшего с начала эпохи UNIX. 32-битное целое записывается как массив двух 16-битных целых: сначала старшие разряды, потом младшие.
c_namesize
Длина строки полного пути к файлу включая терминальный NULL.
c_filesize
Размер файла.
Сразу за заголовком помещается полный путь к объекту. Если длина строки пути не выравнена по границе слова (2 байта), то в конец добавляется еще один NULL. Затем помещается содержимое файла. Если размер содержимого файла также оказывается на выравнен по границе слова, то добавляется NULL.
Создадим простой каталог:
Здесь testl.txt - это символическая ссылка на файл test.txt.
Содержимое файла test.txt:
Затем создадим архив:
и откроем получившийся архив в любимом hex-редакторе.
У меня этот архив выглядит так:
Ну что ж, давайте разбираться.
0x71c7 = 070707 - начало заголовка. И мы уже можем сказать, что порядок байт при создании архива - little-endian.
0x0809 - это c_dev - номер устройства на котором находится файл.
0x349a - это c_ino - inode. В данном случае как раз старшие разряды были утеряны.
0x41fd = 0040775 - c_mode. То есть заголовок описывает каталог с правами доступа 0775.
0x01f4 = 500 - c_uid.
0x01f4 = 500 - c_gid.
0x0002 - c_nlink. На каждый каталог существует как минимум две ссылки (. и ..)
0x0000 - c_rdev.
0x4e8c и 0x3109 - это старший и младший разряды 32-битного значения времени модификации файла. 0x31094e8c = 1317810441.
0x000a - длина имени каталога.
0x00000000 - у каталога нет тела.
Далее идет название каталога.
Затем сразу следует заголовок следующей записи. Не будем подробно на ней останавливаться - только заметим некоторые отличия:
c_mode: 0x34a2 = 0100664 - показывает. что это обычный файл с правами доступа 664.
0x0000001e - размер содержимого файла.
В остальном запись похожа не описание каталога.
Далее идет запись символической ссылки. Содержимое символической ссылки - название файла, на который она указывает.
Ссылки по теме:
Описание утилиты CPIO
Описание формата CPIO
CPIO - это достаточно старый (1992 год), но в то же время очень удобный вариант архива. Он достаточно прост, и, возможно поэтому, получил широкое распространение. Например данный формат используют RPM, initramfs ядра Linux, а также установщик архивов "pax" от Apple.
Данный архив позволяет собирать любое число файлов, директори и других объектов файловой системы (символических ссылок и т.д.) в единый поток байт.
Давайте на примерах рассмотрим формат этого архива.
Каждый объект файловой системы в таком архиве состоит из заголовка с базовыми метаданными, за которым следует полный путь к объекту и содержимое этого объекта. Заголовок содержит набор целочисленных значений, которые во много повторяют поля структуры stat(2) файлов в *nix системах. Конец архива помечается специальной записью (аналогичной остальным) названием 'TRAILER!!!'.
Формат Файла
На данный момент самым распространенным является старый формат записей файла CPIO. Именно его описание и будет приведено.Заголовок формата записи имеет следующую структуру:
struct header_old_cpio { unsigned short c_magic; unsigned short c_dev; unsigned short c_ino; unsigned short c_mode; unsigned short c_uid; unsigned short c_gid; unsigned short c_nlink; unsigned short c_rdev; unsigned short c_mtime[2]; unsigned short c_namesize; unsigned short c_filesize[2]; };
Здесь предполагается, что тип unsigned short имеет размер 16 бит.
c_magic
Целочисленное значение, равное 070707 (в восьмеричной СС), или 0x71c7 (в шестнадцатеричной СС). Используется для определения порядка байт (little-endian vs big-endian).
c_dev,c_ino
Номера устройства и инода (inode) с диска. Соответствуют значениям, выдаваемым утилитой stat. Если значение inode больше 65535, то старшие разряды будут утеряны.
c_mode
Поле одновременно определяет права доступа и тип объекта:
0170000 Маскирует биты типа файла
0140000 Сокет
0120000 Символическая ссылка. Для символических ссылок, тело ссылки будет содержать путь к файлу, на который та ссылается.
0100000 Обычный файл
0060000 Специальное блочное устройство
0040000 Каталог
0020000 Специальное символьное устройство
0010000 Именованный канал(named pipe) или очередь(FIFO).
0004000 SUID
0002000 SGID
0001000 Sticky bit.
0000777 Младшие 9 бит определяют права доступа к объекту. Соответствует значению, выдаваемому утилитой stat.
c_uid,c_gid
Идентификаторы пользователя и группы владельца файла.
c_nlink
Количество ссылок на этот файл. Для каталогов значение этого поля всегда не меньше 2.
c_rdev
Только для специальных символьных и блочных устройств. Поле содержит ассоциированный номер устройства. Для всех остальных типов файлов значение данного поля должно быть нулевым.
c_mtime
Время последнего изменения файла. Формат соответствует количеству секунд, прошедшего с начала эпохи UNIX. 32-битное целое записывается как массив двух 16-битных целых: сначала старшие разряды, потом младшие.
c_namesize
Длина строки полного пути к файлу включая терминальный NULL.
c_filesize
Размер файла.
Сразу за заголовком помещается полный путь к объекту. Если длина строки пути не выравнена по границе слова (2 байта), то в конец добавляется еще один NULL. Затем помещается содержимое файла. Если размер содержимого файла также оказывается на выравнен по границе слова, то добавляется NULL.
Примеры различных архивов.
Теперь давайте возьмем микроскоп. Я в качестве микроскопа возьму Bless. Не скажу, что мне этот hex-редактор очень нравится, но название того, который мне нравится я забыл.Создадим простой каталог:
cpio_test | + test.txt | + testl.txt
Здесь testl.txt - это символическая ссылка на файл test.txt.
Содержимое файла test.txt:
Simple example of cpio usage.
Затем создадим архив:
$ find cpio_test | cpio -ov > example.cpio
и откроем получившийся архив в любимом hex-редакторе.
У меня этот архив выглядит так:
0000 | C7 71 09 08 9A 34 FD 41 F4 01 F4 01 02 00 00 00 | .q...4.A........ 0010 | 8C 4E 09 31 0A 00 00 00 00 00 63 70 69 6F 5F 74 | .N.1......cpio_t 0020 | 65 73 74 00 C7 71 09 08 A2 34 B4 81 F4 01 F4 01 | est..q...4...... 0030 | 01 00 00 00 8C 4E 09 31 13 00 00 00 1E 00 63 70 | .....N.1......cp 0040 | 69 6F 5F 74 65 73 74 2F 74 65 73 74 2E 74 78 74 | io_test/test.txt 0050 | 00 00 53 69 6D 70 6C 65 20 65 78 61 6D 70 6C 65 | ..Simple example 0060 | 20 6F 66 20 63 70 69 6F 20 75 73 61 67 65 2E 0A | of cpio usage.. 0070 | C7 71 09 08 9C 34 FF A1 F4 01 F4 01 01 00 00 00 | .q...4.......... 0080 | 8C 4E 1A 2F 14 00 00 00 08 00 63 70 69 6F 5F 74 | .N./......cpio_t 0090 | 65 73 74 2F 74 65 73 74 6C 2E 74 78 74 00 74 65 | est/testl.txt.te 00A0 | 73 74 2E 74 78 74 C7 71 00 00 00 00 00 00 00 00 | st.txt.q........ 00B0 | 00 00 01 00 00 00 00 00 00 00 0B 00 00 00 00 00 | ................ 00C0 | 54 52 41 49 4C 45 52 21 21 21 00 00 00 00 00 00 | TRAILER!!!......
Ну что ж, давайте разбираться.
0x71c7 = 070707 - начало заголовка. И мы уже можем сказать, что порядок байт при создании архива - little-endian.
0x0809 - это c_dev - номер устройства на котором находится файл.
0x349a - это c_ino - inode. В данном случае как раз старшие разряды были утеряны.
0x41fd = 0040775 - c_mode. То есть заголовок описывает каталог с правами доступа 0775.
0x01f4 = 500 - c_uid.
0x01f4 = 500 - c_gid.
0x0002 - c_nlink. На каждый каталог существует как минимум две ссылки (. и ..)
0x0000 - c_rdev.
0x4e8c и 0x3109 - это старший и младший разряды 32-битного значения времени модификации файла. 0x31094e8c = 1317810441.
0x000a - длина имени каталога.
0x00000000 - у каталога нет тела.
Далее идет название каталога.
Затем сразу следует заголовок следующей записи. Не будем подробно на ней останавливаться - только заметим некоторые отличия:
c_mode: 0x34a2 = 0100664 - показывает. что это обычный файл с правами доступа 664.
0x0000001e - размер содержимого файла.
В остальном запись похожа не описание каталога.
Далее идет запись символической ссылки. Содержимое символической ссылки - название файла, на который она указывает.
Ссылки по теме:
Описание утилиты CPIO
Описание формата CPIO
Комментариев нет:
Отправить комментарий