Snažím se rozebrat složený soubor, který se skládá z několika částí, z nichž jedna je nekomprimované jádro vložené mezi několik dalších souborů. Snažím se najít přesnou délku části jádra, což se ukazuje jako obtížné.
Je v hlavičce vmlinux nějaký údaj o tom, kolik dat má bootloader přečíst před spuštěním, nebo se předpokládá, že veškerý obsah souboru vmlinux se má načíst při předání z bootloaderu?
Přijatá odpověď:
Rychlá odpověď je „ne“, ale pokud se jedná o obrázek ELF, pak s trochou hackování můžete pravděpodobně najít jádro. Viz readelf
hackovat níže.
Zavaděč je zodpovědný za to, aby znal formát jakéhokoli souboru, ve kterém se nachází jádro a kořenový souborový systém. To zahrnuje znalost velikosti souboru jádra, v jakémkoli formátu. Na PowePC a Blackfin je zavaděč zodpovědný za dekomprimaci celého jádra, pokud je komprimováno, a za jeho zapsání na konečné umístění v RAM. Na ARM by se jádro mohlo samo dekomprimovat a bootloader potřebuje pouze zkopírovat nezpracovaný soubor jádra na vhodné místo v RAM a spustit provádění.
Pokud se jádro samo dekomprimuje, pak symboly, které označují velikost komprimovaného souboru jádra, mohou nebo nemusí být někde v dekompresním kódu na začátku souboru, v závislosti na použitém dekompresním algoritmu, ale nemáte možnost vědět, kde bez mapy linkeru pro konkrétní sestavení jádra. Bootloader to rozhodně nemá jak vědět.
Samotný nekomprimovaný kód jádra je ohraničen dvěma symboly, _stext
a _end
jejichž adresy jsou začátkem a koncem samotného jádra, ale nezahrnují rozsah jakýchkoli zahrnutých initramfs, pokud byl initramfs propojen s binárním souborem jádra. Rozsah initramfs je nastaven linkerem ve dvou symbolech jádra, __initramfs_start
a __initramfs_end
. Bootloadery obecně nemají schopnost číst tabulku symbolů jádra (je v System.map
soubor) a bez této schopnosti by neměli žádný způsob, jak zjistit, kde je _end
a __initrams_end
symboly jsou v souboru jádra. To znamená, že pozice symbolů není pevným posunem od začátku binárního souboru. Je určeno v době propojení a může se lišit v závislosti na konfiguraci sestavení jádra.
U nekomprimovaného jádra ve formátu ELF můžete pravděpodobně identifikovat začátek souboru vmlinux vyhledáním hlavičky ELF (177 E L F
v od -c
výpis složeného souboru). Poté můžete zadat readelf -e
nebo objdump -h
na zbývající části souboru od tohoto bodu, abyste našli sekci s nejvyšším posunem souboru (.shstrtab
). Přidejte velikost sekce k tomuto offsetu a tím se dostanete na konec vmlinux. Testoval jsem tuto metodu pomocí neizolovaného PPC vmlinux a dostal jsem velikost, která přesně odpovídala velikosti samostatného souboru vnlinux. Po odstranění jádra tato metoda poskytla výsledek, který byl o 1283 bajtů menší než velikost odstraněného obrázku.
Vestavěné systémy obvykle používají formát souboru, jako je mkimage
k zabalení jádra, rootfs, stromu zařízení a dalších komponent. U-boot například zná mkimage, takže ví, kde binární soubor jádra začíná a končí v souboru mkimage a ví, zda je jádro komprimované nebo ne a na jakou adresu RAM má soubor jádra zapsat.