GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:l'intestazione Vmlinux contiene la lunghezza dell'immagine del kernel?

Sto cercando di disassemblare un file composto composto da più parti, una delle quali è un kernel non compresso inserito tra diversi altri file. Sto cercando di trovare la lunghezza esatta della parte del kernel che si sta rivelando difficile.

C'è qualche indicazione nell'intestazione di vmlinux di quanti dati dovrebbe leggere il bootloader prima dell'esecuzione, o si presume che tutto il contenuto del file vmlinux debba essere caricato al momento della consegna dal bootloader?

Risposta accettata:

La risposta rapida è "no", ma se questa è un'immagine ELF, con un po' di hacking puoi probabilmente trovare il kernel. Vedi il readelf hack di seguito.

Il bootloader è responsabile di conoscere il formato di qualsiasi file in cui risiedono il kernel e il filesystem di root. Ciò include conoscere la dimensione del file del kernel, in qualunque formato esso sia. Su PowePC e Blackfin, il bootloader è responsabile della decompressione dell'intero kernel se è compresso e della scrittura nella posizione finale nella RAM. Su ARM, il kernel potrebbe decomprimersi automaticamente e il bootloader deve solo copiare il file del kernel non elaborato in una posizione comoda nella RAM e avviare l'esecuzione.

Se il kernel si decomprime automaticamente, i simboli che indicano la dimensione del file del kernel compresso potrebbero essere o meno da qualche parte nel codice di decompressione all'inizio del file, a seconda dell'algoritmo di decompressione utilizzato, ma non hai modo di sapere dove senza una mappa del linker per la build specifica del kernel. Di certo il bootloader non ha modo di saperlo.

Lo stesso codice del kernel non compresso è racchiuso tra due simboli, _stext e _end i cui indirizzi sono l'inizio e la fine del kernel stesso, ma non includono l'estensione di alcun initramfs incluso, se un initramfs è stato collegato al binario del kernel. L'estensione di initramfs è impostata dal linker in due simboli del kernel, __initramfs_start e __initramfs_end . I bootloader generalmente non hanno la capacità di leggere la tabella dei simboli del kernel (è in System.map file), e senza questa capacità non avrebbero modo di sapere dove si trova _end e __initrams_end i simboli sono nel file del kernel. Cioè, la posizione dei simboli non è un offset fisso dall'inizio del file binario. È determinato al momento del collegamento e può variare a seconda della configurazione della build del kernel.

Per un kernel non compresso in formato ELF puoi probabilmente identificare l'inizio del file vmlinux cercando l'intestazione ELF (177 E L F nel od -c dump del file composto). Puoi quindi fare readelf -e o objdump -h sul resto del file da questo punto per trovare la sezione con l'offset di file più alto (.shstrtab ). Aggiungi la dimensione della sezione a questo offset e questo ti porta alla fine di vmlinux. Ho testato questo metodo utilizzando un vmlinux PPC non spogliato e ho ottenuto dimensioni che corrispondevano esattamente alle dimensioni del file vnlinux standalone. Dopo aver rimosso il kernel, questo metodo ha prodotto un risultato inferiore di 1283 byte rispetto alla dimensione dell'immagine rimossa.

Correlati:condivisione di un'immagine VirtualBox ... clonare, esportare o copiare?

I sistemi embedded di solito usano un formato di file come mkimage per impacchettare il kernel, rootfs, l'albero dei dispositivi e altri componenti. U-boot, ad esempio, è a conoscenza di mkimage, quindi sa dove inizia e finisce il binario del kernel all'interno del file mkimage e sa se il kernel è compresso o meno e a quale indirizzo RAM scrivere il file del kernel.


Linux
  1. Perché il file di traduzione Bash non contiene tutti i testi di errore?

  2. Linux:cosa implica il layout della memoria del kernel virtuale in Dmesg?

  3. Modifica la versione del kernel su un server cloud Linux utilizzando la modalità di ripristino

  4. Come funziona internamente copy_from_user dal kernel di Linux?

  5. Cosa significa __init nel codice del kernel di Linux?

Introduzione al file system Linux

È possibile avviare il kernel Linux senza creare un'immagine initrd?

Dov'è il file di intestazione <conio.h> su Linux? Perché non riesco a trovare <conio.h>?

In che modo il kernel Linux determina l'ordine delle chiamate __init?

L'emulatore non riesce a trovare la stringa 'Linux version ' nel file immagine del kernel

In che modo Linux carica l'immagine "initrd"?