L'en-tête vmlinux contient-il la longueur de l'image du kernel?

J'essaie de désassembler un file composé qui se compose de plusieurs parties, dont l'un est un kernel non compressé pris en sandwich entre plusieurs autres files. J'essaie de find la longueur exacte de la partie kernel qui s'avère difficile.

Y a-t-il une indication dans l'en-tête vmlinux de la quantité de données que le bootloader est censé lire avant l'exécution ou est-il supposé que tout le contenu du file vmlinux doit être chargé au handoff du bootloader?

La réponse rapide est "non", mais si c'est une image ELF alors avec un peu de piratage, vous pouvez find le kernel. Voir le hack readelf ci-dessous.

Le bootloader est responsable de connaître le format du file dans lequel résident le kernel et le système de files racine. Cela inclut la connaissance de la taille du file kernel, quel que soit le fomat. Sur PowePC et Blackfin, le bootloader est chargé de décompresser le kernel entier s'il est compressé, et de l'écrire dans son location final dans la RAM. Sur ARM, le kernel pourrait être auto-décompressé et le bootloader n'a plus qu'à copyr le file du kernel brut dans un endroit pratique en RAM et démarrer l'exécution.

Si le kernel se décompresse automatiquement, les symboles qui indiquent la taille du file compressé du kernel peuvent ou non se find quelque part dans le code de décompression au début du file, selon l'algorithm de décompression utilisé, mais vous n'avez aucun moyen savoir où sans une carte d'éditeur de liens pour la construction du kernel spécifique. Certes, le bootloader n'a aucun moyen de savoir.

Le code du kernel non compressé lui-même est encadré par deux symboles, _stext et _end dont les adresses sont le début et la fin du kernel lui-même, mais n'incluent pas l'étendue de tout initramfs inclus si un initramfs a été lié au binary du kernel. L'étendue des initramfs est définie par l'éditeur de liens dans deux symboles du kernel, __initramfs_start et __initramfs_end . Les chargeurs de démarrage n'ont généralement pas la capacité de lire la table des symboles du kernel (c'est dans le file System.map ), et sans cette fonctionnalité, ils n'auraient aucun moyen de savoir où se __initrams_end symboles _end et __initrams_end dans le file du kernel. C'est-à-dire que la position des symboles n'est pas un décalage fixe par rapport au début du file binary. Il est déterminé au moment du lien et peut varier en fonction de la configuration du build du kernel.

Pour un kernel non compressé au format ELF, vous pouvez probablement identifier le début du file vmlinux en recherchant l'en-tête ELF ( 177 ELF dans le file od -c du file composé). Vous pouvez alors readelf -e ou objdump -h sur le rest du file à partir de ce point pour find la section avec le décalage de file le plus élevé ( .shstrtab ). Ajoutez la taille de section à ce décalage et cela vous amène à la fin de vmlinux. J'ai testé cette méthode en utilisant un vmlinux PPC non dépouillé et j'ai obtenu une taille qui correspondait exactement à la taille du file vnlinux autonome. Après décapage du kernel cette méthode a donné un résultat qui était de 1283 octets de less que la taille de l'image dénudée.

Les systèmes embarqués utilisent généralement un file fomat tel que mkimage pour mkimage le kernel, les rootfs, l'arborescence des périphériques et d'autres composants. U-boot par exemple est mkimage aware, donc il sait où le kernel binary commence et se termine dans le file mkimage et il sait si le kernel est compressé ou non et à quelle adresse RAM pour écrire le file du kernel.