Nel contesto di Linux, il boot loader è responsabile di alcune attività predefinite. Poiché questa domanda è contrassegnata con il braccio, penso che l'avvio di ARM potrebbe essere una risorsa utile. Nello specifico, il boot loader era/è responsabile dell'impostazione di un ATAG
elenco che descrive la quantità di RAM, una riga di comando del kernel e altri parametri. Uno dei parametri più importanti è il tipo di macchina . Con alberi dei dispositivi , viene passata un'intera descrizione del tabellone. Ciò rende impossibile l'avvio di un Linux ARM standard senza codice per impostare i parametri come descritto.
I parametri consentono un generico Linux per supportare più dispositivi. Ad esempio, un kernel Debian ARM può supportare centinaia di diversi tipi di schede. Uboot o un altro boot loader può determinare dinamicamente queste informazioni o può essere hardcoded per la scheda.
Potresti anche dare un'occhiata alla pagina delle informazioni sul bootloader qui su stack overflow.
Un sistema di base potrebbe essere in grado di impostare ATAGS
e copia NOR flash su SRAM. Tuttavia, di solito è un po' più complesso di così. Linux richiede l'installazione della RAM, quindi potrebbe essere necessario inizializzare un controller SDRAM. Se usi NAND flash, devi gestire i blocchi difettosi e la copia potrebbe essere un po' più complesso di memcpy()
.
Linux ha spesso alcuni bug di driver latenti in cui un driver presupporrà che un orologio sia inizializzato. Ad esempio, se Uboot inizializza sempre un orologio Ethernet per una particolare macchina, il driver Linux Ethernet potrebbe aver trascurato di impostare questo orologio. Questo può essere particolarmente vero con gli alberi dell'orologio.
Alcuni sistemi richiedono formati di immagine di avvio non supportati da Linux; ad esempio un'intestazione speciale che può inizializzare immediatamente l'hardware; come configurare il devices
da cui leggere il codice iniziale. Inoltre, spesso c'è dell'hardware che dovrebbe essere configurato immediatamente; un caricatore di avvio può farlo rapidamente, mentre la normale struttura di Linux può ritardarlo in modo significativo, con conseguenti conflitti di I/O, ecc.
Da una prospettiva pragmatica, è più semplice utilizzare un boot loader. Tuttavia, non c'è nulla che ti impedisca di alterare il sorgente di Linux per avviarlo direttamente da esso; anche se potrebbe essere come incollare il boot loader codice direttamente all'inizio di Linux.
Vedi anche:confronto tra Coreboot, Uboot e Wikipedia. Barebox è un boot loader meno conosciuto, ma ben strutturato e moderno per ARM. RedBoot viene utilizzato anche in alcuni sistemi ARM; Le partizioni RedBoot sono supportate nell'albero del kernel.
Un boot loader è un programma per computer che carica il sistema operativo principale o l'ambiente di runtime per il computer dopo il completamento degli autotest.
^ Dall'articolo di Wikipedia
Quindi in pratica il bootloader sta facendo proprio quello che volevi:copiare i dati dal flash nella memoria operativa. È davvero così semplice.
Se vuoi saperne di più sul boostrapping del sistema operativo, ti consiglio vivamente di leggere l'articolo collegato. La fase di avvio consiste, oltre ai test, anche nel controllo delle periferiche e in altre cose. Saltarli ha senso solo su dispositivi embedded molto semplici, ed è per questo che i loro bootloader sono ancora più semplici:
Alcuni sistemi integrati non richiedono una sequenza di avvio evidente per iniziare a funzionare e, quando accesi, possono semplicemente eseguire programmi operativi archiviati nella ROM.
La stessa fonte
Perché non possiamo caricare direttamente il kernel nella RAM dalla memoria flash senza bootloader? Se lo carichiamo cosa accadrà? In effetti, il processore non lo supporterà, ma perché stiamo seguendo la procedura?
Bartek, Artless e Felipe danno tutti parti dell'immagine.
Ogni tipo di processore integrato (ad esempio 386EX, Coretex-A53, EM5200) farà qualcosa automaticamente quando viene resettato o acceso. A volte quel qualcosa è diverso a seconda che l'alimentazione venga riavviata o il dispositivo venga ripristinato. Alcuni processori incorporati ti consentono di modificare quel qualcosa in base alle tensioni applicate ai diversi pin quando il dispositivo viene alimentato o resettato.
Indipendentemente da ciò, c'è una quantità limitata di qualcosa che un processore può fare, a causa dello spazio fisico sul processore richiesto per definire quel qualcosa , che si tratti di FLASH su chip, microcodice di istruzione o qualche altro meccanismo.
Questo limite significa che qualcosa è
- scopo fisso, fa una cosa il più velocemente possibile.
- limitato per portata e capacità, in genere carica un piccolo blocco di codice (spesso pochi kilobyte o meno) in una posizione di memoria fissa ed esegue dall'inizio del codice caricato.
- non modificabile.
Quindi ciò che fa un processore in risposta al ripristino o al ciclo di spegnimento non può essere modificato e non può fare molto, e non vogliamo che copi automaticamente centinaia di megabyte o gigabyte in memoria che potrebbero non esistere o potrebbero non essere inizializzati, e che potrebbe richiedere molto tempo.
Quindi...
Abbiamo impostato un piccolo programma che è più piccolo della dimensione minima consentita su tutti i dispositivi che utilizzeremo. Quel programma è archiviato ovunque si trovi qualcosa ha bisogno che lo sia.
A volte il piccolo programma è U-Boot. A volte anche U-Boot è troppo grande per il caricamento iniziale, quindi il piccolo programma a sua volta carica U-Boot.
Il punto è che qualunque cosa venga caricata dal qualcosa , è modificabile come necessario per un particolare sistema. Se è U-Boot, ottimo, altrimenti sa dove caricare il sistema operativo principale o dove caricare U-Boot (o qualche altro bootloader).
U-Boot (parlando di bootloader in generale) configura quindi un set minimo di dispositivi, memoria, impostazioni del chip, ecc., per consentire il caricamento e l'avvio del sistema operativo principale. L'init del sistema operativo principale si occupa di qualsiasi configurazione o inizializzazione aggiuntiva.
Quindi la sequenza è:
- Accensione o ripristino del processore
- Qualcosa carica il codice di avvio iniziale (o il bootloader incorporato in stile U-Boot)
- Codice di avvio iniziale (potrebbe non essere necessario)
- U-Boot (o altro bootloader incorporato generico)
- Init Linux
Il bootloader primario è solitamente integrato nel silicio ed esegue il caricamento del primo codice USER che verrà eseguito nel sistema.
Il bootloader esiste perché non esiste un protocollo standardizzato per caricare il primo codice, poiché dipende dal chip. A volte il codice può essere caricato tramite una porta seriale, una memoria flash o persino un disco rigido. È la funzione del bootloader per individuarlo.
Una volta che il codice utente è stato caricato ed eseguito, il bootloader non viene più utilizzato e la correttezza dell'esecuzione del sistema è responsabilità dell'utente.
Nella catena Linux incorporata, il bootloader principale installerà ed eseguirà il file Uboot. Quindi Uboot troverà il kernel Linux e lo caricherà.