Содержит ли заголовок vmlinux длину образа ядра?

Содержит ли заголовок vmlinux длину образа ядра?

Я пытаюсь разобрать составной файл, состоящий из нескольких частей, одна из которых представляет собой несжатое ядро, зажатое между несколькими другими файлами. Я пытаюсь найти точную длину части ядра, что оказывается сложным.

Есть ли в заголовке vmlinux какое-либо указание на то, какой объем данных должен быть прочитан загрузчиком перед выполнением, или предполагается, что все содержимое файла vmlinux должно быть загружено при передаче от загрузчика?

решение1

Быстрый ответ - "нет", но если это образ ELF, то с помощью взлома вы, вероятно, сможете найти ядро. Смотрите хак readelfниже.

Загрузчик отвечает за знание формата любого файла, в котором находятся ядро ​​и корневая файловая система. Это включает в себя знание размера файла ядра, в каком бы формате он ни был. На PowePC и Blackfin загрузчик отвечает за распаковку всего ядра, если оно сжато, и запись его в свое конечное местоположение в ОЗУ. На ARM ядро ​​может быть самораспаковывающимся, и загрузчику нужно только скопировать необработанный файл ядра в удобное место в ОЗУ и начать выполнение.

Если ядро ​​самораспаковывающееся, то символы, указывающие размер сжатого файла ядра, могут быть или не быть где-то в коде распаковки в начале файла, в зависимости от используемого алгоритма распаковки, но вы не можете узнать, где именно, без карты компоновщика для конкретной сборки ядра. Конечно, загрузчик не может знать.

Сам несжатый код ядра заключен в скобки между двумя символами, _stextи _endадреса которых являются началом и концом самого ядра, но не включают в себя объем любого включенного initramfs, если initramfs был связан с двоичным файлом ядра. Объем initramfs устанавливается компоновщиком в двух символах ядра, __initramfs_startи __initramfs_end. Загрузчики, как правило, не имеют возможности читать таблицу символов ядра (она находится в файле System.map), и без этой возможности они не смогли бы узнать, где находятся символы _endи __initrams_endв файле ядра. То есть положение символов не является фиксированным смещением от начала двоичного файла. Оно определяется во время компоновки и может меняться в зависимости от конфигурации сборки ядра.

Для несжатого ядра в формате ELF вы, вероятно, можете определить начало файла vmlinux, посмотрев заголовок ELF ( 177 E L Fв od -cдампе составного файла). Затем вы можете выполнить readelf -eили objdump -hдля оставшейся части файла с этой точки, чтобы найти раздел с наибольшим смещением файла ( .shstrtab). Добавьте размер раздела к этому смещению, и это приведет вас к концу vmlinux. Я протестировал этот метод с использованием несжатого PPC vmlinux и получил размер, который точно соответствовал размеру автономного файла vnlinux. После стирания ядра этот метод дал результат, который был на 1283 байта меньше размера срезанного образа.

Встроенные системы обычно используют формат файла, например, mkimageдля упаковки ядра, rootfs, дерева устройств и других компонентов. Например, U-boot распознает mkimage, поэтому он знает, где начинается и заканчивается двоичный файл ядра внутри файла mkimage, и знает, сжато ли ядро ​​или нет, и по какому адресу ОЗУ записывать файл ядра.

Связанный контент