Perché abbiamo bisogno di un bootloader separato dal nostro programma applicativo nei microcontrollori?


28

Perché è necessario un programma separato nella stessa memoria di programma flash di un microcontrollore, in particolare STM32F103, che si chiama bootloader?

Cosa c'è di speciale in questo per tenerlo separato dal programma applicativo principale?

In generale, un bootloader di un sistema basato su microprocessore (ad esempio PowerPC MPC8270) fa lo stesso lavoro di un microcontrollore (diciamo ARM STM32F103) o sta facendo fondamentalmente lavori diversi l'uno dall'altro e tuttavia entrambi sono chiamati 'bootloader' ?


2
lo stesso motivo per cui hai singoli chip e parti e non una gigantesca struttura monolitica
Emobe

Non Basta inserire il programma con gli interruttori e le luci sulla console del computer.
Hot Licks

1
A rigor di termini non è necessario un programma bootloader separato su un microcontrollore. Ma spesso scegliamo di averne uno per le funzioni di utilità aggiuntive che offre. Se queste funzioni non sono necessarie, non desiderate, è possibile rimuovere il bootloader. Il bootloader del microcontrollore viene in genere utilizzato per masterizzare un nuovo programma in flash. A volte può essere utilizzato per funzioni di debug, alcuni punti di interruzione del supporto e altre funzioni utili. Su un microcomputer, in genere il bootloader carica i programmi dalla memoria di massa e sarà necessario lì.
ghellquist

Risposte:


55

Un bootloader su un microcontrollore è responsabile dell'aggiornamento del firmware principale su un canale di comunicazione diverso dall'intestazione di programmazione. Ciò è utile per l'aggiornamento del firmware sul campo su BLE, UART, I2C, schede SD, USB, ecc. Sarebbe estremamente scomodo richiedere ai clienti di acquistare programmatori solo per aggiornare il firmware sui propri dispositivi.

Il motivo per cui il bootloader è tenuto separato è per affidabilità. Il bootloader e il codice dell'applicazione sono collocati in sezioni separate di flash, in modo che il codice dell'applicazione possa essere cancellato e riscritto dal bootloader senza modificare nulla relativo al codice del bootloader.

Se il bootloader e l'applicazione fossero mantenuti insieme, il codice del bootloader dovrebbe essere copiato nella RAM prima di poter essere eseguito, poiché qualsiasi aggiornamento del firmware cancellerebbe il codice del bootloader in flash. Se l'alimentazione venisse interrotta con il codice del bootloader nella RAM e il flash cancellato, il dispositivo verrebbe bloccato.


3
La nostra è la stessa ragione. Sono nello stesso flash ma il bootloader è flash cancellato-allineato e abbastanza intelligente da cancellare il flash solo più in alto dei suoi stessi indirizzi.
Giosuè, il

3
In alcuni casi, l'intestazione di programmazione del microprocessore potrebbe in realtà essere inaccessibile senza dover smontare lo chassis del prodotto, quindi essere in grado di riprogrammarlo sul bus di comunicazione senza hardware aggiuntivo è un fattore chiave per l'affidabilità.
John Go-Soco,

6
@ alt-rose Il bootloader e il programma applicativo sono programmi compilati separatamente, ognuno con il proprio codice di avvio e main()funzione. All'accensione il codice di avvio del bootloader viene eseguito e chiama il bootloader main(). Il programma bootloader verifica la presenza di un programma applicativo valido, quindi passa al codice di avvio del programma applicativo che chiama il programma applicativo main(). Il codice di avvio di ciascun programma inizializza l'ambiente di runtime C per il rispettivo programma (ovvero inizializza variabili, stack, ecc.) E in genere nessuno dei due programmi main()ritorna mai al codice di avvio.
kkrambo,

1
@ alt-rose: allo stesso modo in cui la CPU ottiene l'indirizzo iniziale del bootloader - non è così. Al contrario, la CPU specifica quale verrà utilizzato come indirizzo iniziale del bootloader e il bootloader specifica quale verrà utilizzato come indirizzo iniziale del programma applicativo.
MSalters

4
@kkrambo Anche se comunemente vero, non c'è alcun requisito (né fatto universalmente vero) che un bootloader sia scritto in C o in un linguaggio derivato da C con maina.
Yakk,

26
  1. In modo che il processo di caricamento possa recuperare da errori. Supponiamo che ci sia un errore di comunicazione o che l'alimentazione si disconnetta durante un aggiornamento. Se il boot loader fosse parte dell'applicazione che stavi aggiornando, l'utente non sarebbe in grado di riprovare senza utilizzare hardware speciale per eseguire il reflash del boot loader.

  2. Alcuni microcontrollori non possono eseguire il codice dalla RAM. Se il boot loader si mescolasse con il resto del software, allora non saresti in grado di aggiornare il tuo software perché non puoi cancellare le pagine di flash che stai attualmente eseguendo. Il problema è innanzitutto masterizzare il nuovo codice nella seconda metà di Flash, quindi saltare ad esso. Il nuovo codice si copia quindi nella prima metà del flash. Ovviamente il rovescio della medaglia è che il flash di masterizzazione di solito è lento e ora che devi farlo due volte il processo di caricamento potrebbe richiedere fino al doppio del tempo. Inoltre, questa soluzione alternativa limita le dimensioni dell'applicazione in modo che non siano superiori alla metà del flash totale.

  3. Caricatori di avvio ben scritti cercano di verificare l'esistenza di codice valido sul dispositivo prima di provare a eseguirlo. Se il boot loader e l'altro codice fossero mescolati insieme, come potevi essere sicuro che la tua routine di validazione avrebbe funzionato se tutto il codice non fosse stato caricato?

  4. Autenticazione. I caricatori di avvio sicuri provano a verificare che l'applicazione caricata corrisponda a una firma digitale prima dell'esecuzione. Ma se il boot loader e l'altro codice sono stati mescolati insieme, non è possibile controllare ciò che viene eseguito sul dispositivo perché una volta che l'utente carica un nuovo codice non è possibile controllare ciò che accade all'avvio.


4
Come esempio del punto 2, alcuni microcontrollori potrebbero non avere nemmeno RAM accessibile all'avvio: ad esempio, Raspberry Pi utilizza la sua GPU per caricare il bootloader da una scheda SD, che quindi abilita il processore ARM e la memoria.
ErikF,

11

Sono generalmente lì per consentirti di aggiornare il tuo programma applicativo principale.

Hai bisogno di un codice che sappia come cancellare e riprogrammare parte del flash interno, che non può essere il programma principale in quanto quando viene cancellato da solo non sarebbe in grado di riprogrammare.


9

Il bootloader consente all'MCU di comunicare con qualcos'altro per accettare un nuovo programma, archiviarlo ed eseguirlo dopo un ripristino. Se non disponevi di un bootloader, è necessario un programmatore per accedere alla memoria e mettere in atto il programma.


2
È praticamente tutto. L'MCU può ottenere il codice solo tramite uno speciale sottosistema di programmazione (come AVRICE o JTAG) o avendo già un bootloader in flash. È una decisione dell'applicazione quanto sia complesso il bootloader, ad esempio alcuni sistemi possono caricare il codice dal WiFi. Su MCU di fascia molto bassa come un ATTiny, un bootloader (e pin seriali) sono un grosso sovraccarico, quindi usi sempre un programmatore.
Rich

7

Oltre alle altre risposte corrette su come consentire la riprogrammazione del firmware principale dal bootloader, un altro vantaggio della separazione del bootloader è che è possibile separare logicamente le attività "esegui una volta all'avvio" dal codice necessario durante il runtime. Quindi, dopo che il bootloader ha terminato le sue attività di configurazione iniziale, il firmware principale può eliminare il bootloader con tutto il suo codice non più necessario dalla memoria, risparmiando spazio RAM significativo. È possibile raggiungere questo obiettivo in altri modi, ma la suddivisione del bootloader / firmware rende molto più facile su molte architetture.


1
Su un microcontrollore, il codice molto probabilmente non è mai nella RAM, quindi non può essere sfrattato. Naturalmente puoi scartare i dati del bootloader dalla RAM.
Ben Voigt,

@BenVoigt, dipende dal microcontrollore. Alcuni (principalmente quelli con flash NOR) ti consentono di eseguire direttamente il flash, ma altri (di solito con il flash NAND, che sta diventando più comune) richiedono l'esecuzione di RAM. A volte non c'è nemmeno alcun flash integrato e devi copiare il codice da un chip flash esterno nella SRAM locale prima di poter eseguire qualsiasi cosa.
Nate S - Ripristina Monica l'

2

La risposta breve è perché il software è fantastico.

Potresti avere tutto ciò che il bootloader è "hardware puro". Ma è molto, molto, molto più facile avere i compiti che il bootloader deve essere scritto come software, quindi interpretato dall'hardware.

Queste attività possono comportare la configurazione dell'hardware per l'esecuzione del software "reale" (ad esempio, su un Raspberry Pi (tramite @ErikF)), con un protocollo per sostituire il programma "reale" prima che venga eseguito (controllare un pin, se quel pin è impostato, quindi esegue il riflash del programma reale) o addirittura imposta l'ambiente software per il programma "reale".

Su un software con meno micro-scala, quando si esegue un eseguibile, il caricatore di applicazioni sposta cose come il caricamento di parti dei dati in memoria, a volte corregge gli indirizzi, imposta argomenti su contenuti principali o di altro genere, ruota le librerie fornite dal sistema operativo e quindi passa all'inizio del _maincodice. Alcune di queste cose possono essere fatte da un bootloader.

In un microcontrollore, alcune delle attività svolte da un bootloader potrebbero essere suddivise nel programma. Il compilatore per la tua piattaforma potrebbe inserire automaticamente il codice "setup" in ogni eseguibile.

Ma averlo nel bootloader significa che lo stesso compilatore potrebbe funzionare su hardware diverso, in quanto il bootloader può "nascondere" la differenza tra le piattaforme.

Per finire, il fatto che un lampo del programma principale non rischi il bootloader (e la possibilità di eseguire il reflash del programma principale), e avere un bootloader non banale è una cosa abbastanza grande.


-1

Una risposta che non è stata trattata è la necessità di separare le preoccupazioni a causa delle limitazioni del linguaggio C.

Generalmente i bootloader sono scritti in un mix di Assembly e C, con il primissimo stadio di boot in Assembly.

Questo viene fatto per impostare alcune cose come:

  • allocare lo stack C.
  • leggendo il puntatore dello stack nel registro
  • leggere il contatore del programma nel registro
  • dichiarazione di vettori di reset
  • caricamento del secondo stadio (initramfs) nella RAM.

Questa è un'approssimazione molto approssimativa dei passi fatti e sto descrivendo il processo di avvio ARM, è di nuovo diverso per x86 e altre architetture.

Tuttavia, il motivo principale rimane lo stesso: l'allocazione della pila C deve essere eseguita dall'assemblaggio.


Perché il downvote? Questo è sia pertinente che accurato.
BitShift

-1

Una parte della domanda a cui non è stata finora data risposta è la differenza tra bootloader su microcontrollori e sistemi a microprocessore.

Microcontroller

La maggior parte dei microcontrollori ha una memoria ROM integrata che contiene il proprio codice di programma. La modifica di questo codice richiede in genere un dispositivo programmatore che si collega all'interfaccia di programmazione del microcontrollore (ad es. ISP su ATMega). Ma queste interfacce di programmazione spesso non sono molto comode da usare, rispetto ad altre interfacce, poiché potrebbero non essere prontamente disponibili in un determinato contesto. Ad esempio, mentre quasi tutti i computer dispongono di porte USB, l'interfaccia SPI necessaria per ISP è molto più rara e altre interfacce come l'interfaccia PID utilizzata su ATXMega sono supportate solo da hardware di programmazione dedicato.

Quindi, ad esempio, se si desidera aggiornare il software da un normale computer senza alcun hardware esterno, è possibile utilizzare un bootloader che legge da un diverso tipo di interfaccia (ad esempio RS232, USB o RS232 su USB come su Arduino) per programmare il dispositivo su interfacce comuni.

Detto questo, se non hai bisogno di questa funzionalità il bootloader è completamente opzionale. Il microcontrollore può ancora eseguire il suo codice completamente senza il bootloader.

microprocessore

Su un microprocessore le cose sono leggermente diverse. Mentre la maggior parte dei microprocessori presenta una ROM abbastanza grande per un bootloader, quelle ROM non sono abbastanza grandi da contenere un sistema operativo completo. Quindi lo scopo del bootloader è di inizializzare l'hardware, cercare un sistema operativo avviabile, caricarlo ed eseguirlo. Quindi il bootloader è fondamentale per ogni singolo avvio.

Sui sistemi x86 / x64 questo bootloader è il BIOS o UEFI (sostanzialmente una versione più recente di un BIOS).

A volte potresti persino avere più bootloader in esecuzione in una catena. Ad esempio se hai un sistema a doppio avvio con Windows e Linux potresti finire con il seguente:

  • BIOS / UEFI si avvia e trova GRUB installato. Quindi carica GRUB (= Grand Unified Bootloader)
  • GRUB trova una specie di Linux e il Bootloader di Windows. L'utente seleziona il Bootloader di Windows.
  • Il bootloader di Windows si avvia e trova Windows 7 e Windows 10 installati. L'utente seleziona Windows 10.
  • Windows 10 infine si avvia.

Quindi in questo caso c'erano tre software che possono essere considerati un bootloader. Sia GRUB che Windows Bootloader sono per lo più lì per offrire all'utente un'opzione di selezione di avvio più comoda di quella che il BIOS / UEFI darebbe loro. Consente inoltre l'avvio di più sistemi operativi dallo stesso disco rigido o anche dalla stessa partizione.

TLDR

Quindi, mentre in entrambi i sistemi il bootloader fa cose simili (aiutando l'utente a scegliere quale codice avviare) entrambi differiscono notevolmente per come lo realizzano e cosa fanno esattamente.


Sebbene sia utile distinguere i sistemi con memoria non volatile (ROM o flash) ad accesso casuale sufficiente per contenere l'intero programma da quelli che devono eseguire codice dalla RAM, esistono microcontrollori di entrambi i tipi e microprocessori di entrambi i tipi.
supercat

Naturalmente la differenza tra un microcontrollore e un microprocessore non è un confine rigido e alcuni microcontrollori si comportano più come un microprocessore e viceversa. Ecco perché ho preso AtMega / Arduino e x86 / x64 come esempi, perché si comportano in questo modo.
Dakkaron,

"I microprocessori dispongono di una ROM sufficientemente grande per un bootloader ... Sui sistemi x86 / x64 questo bootloader è il BIOS o UEFI" No. BIOS o UEFI sono archiviati nella memoria flash off-chip. La ROM on-chip è per funzioni di livello anche inferiore, come l'inizializzazione del microcodice.
Ben Voigt,

@Dakkaron: vorrei tracciare la linea tra un microprocessore e un microcontrollore in base al fatto che il chip sia progettato per essere utilizzabile per scopi non banali senza nient'altro sul bus degli indirizzi. L'8031 non si qualificherebbe, tranne per il fatto che è funzionalmente 8051 (che è sicuramente un microcontrollore) che non è specificato come avente qualcosa di utile nella ROM interna, ma sarebbe altrimenti progettato per essere interamente utilizzabile dalla memoria interna). Qualcosa come un RCA / CDP 1802 non si qualificherebbe anche se può essere usato per pilotare un'etichetta LED ...
supercat

... senza RAM e ROM esterne, perché i progetti RAMless / ROMless sono limitati a compiti banali. Qualcosa di simile a un TMS 32050 che, se ricordo, ha un bootloader e qualche migliaio di parole di 16 bit di RAM internamente si qualificherebbe come un microcontrollore; sebbene molte applicazioni richiederebbero di aggiungere più RAM, se connessa tramite UART a un altro sistema potrebbe servire a molti scopi senza nulla sul suo bus di memoria.
supercat
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.