In che modo Linux gestisce una partizione separata / di avvio?


11

Sono interessato a conoscere come Linux gestisce le partizioni di avvio separate. In realtà non mi interessa farlo, ma vorrei sapere come funziona sotto il cofano.

Considera un disco rigido sda, che ha due partizioni sda1e sda2. Diciamo che sda2è la rootpartizione /che contiene il sistema operativo Linux.

La mia comprensione è che il bootloader GRUB2è montato su /boot. Quando la directory si /boottrova su una partizione separata sda2, tuttavia, come è possibile che ciò avvenga prima che /venga effettivamente montato?

In che modo /bootavviene in questo caso l'interazione tra BIOS, record di avvio principale e GRUB (o i file )? È che i dati /bootnon sono effettivamente montati sul /filesystem in questa fase iniziale?

Nota: questa domanda riguarda il montaggio della partizione di root, ma non discute una partizione di avvio separata.

Risposte:


18

Ecco il problema nella tua comprensione:

La mia comprensione è che il bootloader GRUB2, è montato su / boot.

GRUB non è "montato" all'avvio. GRUB è installato a /boot, ed è caricato dal codice nel Master Boot Record. Ecco una panoramica semplificata del moderno processo di avvio, ipotizzando una distribuzione GNU / Linux con un MBR / BIOS (non GPT / UEFI):

  1. Il BIOS si carica.
  2. Il BIOS carica il piccolo frammento di codice presente nel Master Boot Record.
  3. GRUB non si adatta a 440 byte, la dimensione del Master Boot Record. Pertanto, il codice caricato in realtà analizza solo la tabella delle partizioni, trova la /bootpartizione (che credo sia determinata quando si installa GRUB nel Master Boot Record) e analizza le informazioni del filesystem. Carica quindi Stage 2 GRUB. (È qui che entra in gioco la semplificazione.)
  4. Stage 2 GRUB carica tutto ciò di cui ha bisogno, inclusa la configurazione di GRUB, quindi presenta un menu (o meno, a seconda della configurazione dell'utente).
  5. È stata scelta una sequenza di avvio. Ciò può avvenire tramite un timeout, dall'utente selezionando una voce di menu o avviando un elenco di comandi.
  6. La sequenza di avvio inizia l'esecuzione. Questo può fare una serie di cose, ad esempio caricare un kernel, eseguire il chainloading su un altro bootloader, ma supponiamo che la sequenza di avvio sia GNU / Linux standard.
  7. GRUB carica il kernel Linux.
  8. GRUB carica il ramdisk iniziale .
  9. Il ramdisk iniziale si monta /sotto /new_root(possibilmente sbloccandolo crittograficamente), avvia udev, inizia riprendi da scambio, ecc.
  10. Il ramdisk iniziale utilizza l' pivot_rootutilità per impostare /new_rootcome reale /.
  11. initinizia. Le partizioni vengono montate, i demoni vengono avviati e il sistema si avvia.

Notare come il kernel viene caricato solo al passaggio 7. Per questo motivo , non esiste alcun concetto di montaggio fino al passaggio 7 . Questo è il motivo /bootper cui deve essere nuovamente montato al punto 9, anche se GRUB lo ha già utilizzato.

Può anche essere utile guardare la sezione GRUB 2 della pagina Wikipedia su GRUB.


Hai bloccato la mia confusione esattamente. Questo è proprio quello che stavo cercando. Quindi inizialmente /bootnon si riferisce a una directory montata sulla partizione di root?
jII

@jesterII fantastico! in tal caso, ti dispiacerebbe accettare questa risposta facendo clic sul segno di spunta proprio sotto le frecce di voto?
Strugee,

7
Il codice MBR non può analizzare un filesystem. Carica l'immagine principale di grub dai settori inutilizzati che seguono l'MBR prima della prima partizione e quel codice comprende come trovare e montare la partizione / boot per trovare i file di configurazione di grub, i moduli aggiuntivi e i tuoi kernel. Anche pivot_root è stato considerato un trucco sporco ed è stato sostituito con il run-initquale elimina tutti i file in initramfs, quindi si avvia nel file system di root.
psusi,

Il processo di avvio moderno dovrebbe ora essere il processo di avvio Legacy in quanto UEFIsempre più popurlar ;-) @strugee
Kiwy

1
@strugee, dopo una discussione sulla mailing list util-linux sembra che il mio ricordo fosse leggermente fuori: hanno smesso di consentire pivot_root sui rootfs reali, quindi è per questo che nessuno lo usa più durante l'avvio. Systemd lo usa allo spegnimento, tuttavia, non per tornare all'inizrd originale (che si rimuove quando si passa alla radice reale), ma per passare a uno appena caricato. Vedi marc.info/?l=util-linux-ng&m=139100788306216&w=2
psusi

6

Domanda 1

La mia comprensione è che il bootloader GRUB2, è montato su / boot. Quando la directory / boot si trova su una partizione separata sda2, tuttavia, come è possibile che ciò avvenga prima che / sia effettivamente montato?

Non penso che tu stia capendo proprio qui. Dalla pagina Wikipedia di GNU GRUB :

estratto

Quando un computer è acceso, il BIOS del computer trova il dispositivo di avvio principale configurato (in genere il disco rigido del computer) e carica ed esegue il programma di avvio iniziale dal record di avvio principale (MBR). L'MBR è il primo settore del disco rigido e ha il numero 0 (il conteggio dei settori inizia da 0). Per molto tempo, la dimensione di un settore è stata di 512 byte, ma dal 2009 ci sono dischi rigidi disponibili con una dimensione del settore di 4096 byte, chiamati dischi di formato avanzato . A partire da ottobre 2013, tali dischi rigidi sono ancora accessibili in settori a 512 byte, utilizzando l' emulazione 512e .

Nella versione 2 di GRUB si verifica quanto segue:

estratto

Avvio del computer

All'accensione, si verifica quanto segue:

  • L'hardware si inizializza, imposta la CPU in modalità reale (nessuna memoria virtuale) e passa alla posizione fissa 0xFFFF0 (cablata nei circuiti della CPU)
  • Viene quindi eseguito il codice BIOS memorizzato in una ROM o memoria flash mappata in quella posizione.
  • Il codice BIOS esamina i dati di configurazione del BIOS per vedere qual è il dispositivo di avvio. Questi dati di configurazione del BIOS possono in genere essere modificati premendo alcune sequenze di tasti speciali subito dopo l'accensione, provocando l'esecuzione del programma di configurazione del BIOS. Tra le altre cose, in genere è possibile selezionare qui il dispositivo di avvio.
  • Il codice BIOS carica l'MBR del dispositivo di avvio nella RAM. Ricorda che un MBR è di soli 512 byte! I dati caricati sono ovviamente il programma e i dati che grub-install ha creato e scritto in modo dinamico quando è stato eseguito il programma grub-install.
  • Il codice BIOS passa all'indirizzo iniziale dell'MBR caricato (ovvero il codice Grub viene eseguito per la prima volta dall'accensione).
  • Il codice MBR di Grub carica un singolo settore il cui indirizzo è cablato nel blocco MBR. Quindi passa in rassegna le coppie (indirizzo, len) in quel settore caricando tutti i dati dal disco in memoria (cioè carica il contenuto del file /boot/grub/core.imgo la sua copia "incorporata"). Il codice MBR passa quindi al codice caricato, ovvero "esegue" il programma core.img.
  • Come descritto nella sezione "Installazione di Grub", questo trucco per incorporare gli indirizzi di blocco del disco core.imgnon elaborato consente di archiviare nello spazio che non si trova in una partizione e che non è mai stato formattato come file system ("incorporamento"). E in questo caso, se core.imgviene modificato, purché la nuova versione sia "incorporata" nella stessa posizione, non è necessario aggiornare il codice MBR.
  • In alternativa, è possibile core.imgche si trovi all'interno di un vero filesystem e che Grub legga il core.imgcontenuto del file senza avere un driver per quel filesystem. Tuttavia, in questo caso, se core.imgviene modificato, al primo blocco del file potrebbe essere assegnato un nuovo indirizzo sul disco; se ciò accade, l'MBR deve essere aggiornato per puntare a questa nuova posizione. Tuttavia, come di core.imgsolito viene aggiornato eseguendo grub-install, questo di solito non è un problema.
  • Si noti che teoricamente, se si core.imgtrova su un dispositivo diverso dall'MBR e viene aggiunto un nuovo hardware, il record MBR generato da Grub potrebbe non essere in grado di caricare correttamente il core.imgfile; l'id dispositivo su cui si trova il primo settore di core.imgè cablato nell'MBR, non cercato. Tuttavia non esiste una soluzione per questo; non è possibile incorporare l'equivalente del comando Grub "search" nell'MBR a 512 byte. Tuttavia, questo problema non è probabile; normalmente core.imgè incorporato sullo stesso dispositivo dell'MBR. E una volta core.imgcaricato, può usare search.mod per trovare tutti gli altri /boot/grubfile ed è quindi immune ai riarrangiamenti hardware.
  • Il core.imgcodice eseguito ora inizializza tutti i moduli che sono integrati (collegati in core.img); uno di questi moduli sarà un driver di filesystem in grado di leggere il filesystem su cui /boot/grubrisiede la directory .
  • Registra inoltre un set di comandi integrati: set, unset, ls, insmod.
  • Se è stato collegato un "file di configurazione" core.img, questo viene quindi passato a un parser di script incorporato molto semplice per l'elaborazione. I comandi di scripting nel file di configurazione possono solo invocare comandi integrati o collegati. Scenari semplici (ad esempio l'avvio di un tipico computer desktop da un'unità locale) non richiedono file di configurazione; questa funzione viene utilizzata per cose come l'avvio tramite pxe, remote nfs o quando si /boot/grubtrova su un dispositivo LVM.
  • Core.imgora carica il file in “/boot/grub/normal.mod”modo dinamico dal disco e passa alla sua funzione di immissione. Si noti che questo passaggio richiede l'impostazione del driver del file system appropriato (ovvero incorporato).

     ss del processo di avvio

NOTA: quando vedi il tipico menu di GRUB2 in cui selezioni il sistema operativo / kernel da avviare, /boot/gruba questo punto fai riferimento alla directory di sistema .

                                         ss di grub tui

Riferimenti


Qualcuno dovrebbe correggere quella voce di Wikipedia perché è sbagliata. La fase 1 / 1.5 / 2 è applicabile solo a grub legacy. Sono stati completamente eliminati nella riscrittura di grub2 e non troverete alcun riferimento a tali termini nella documentazione ufficiale di grub 2.
psusi,

@psusi - grazie per il chiarimento. Ero un po 'confuso quando li vidi menzionati anche lì, poiché avevo sentito lo stesso, che l'1 / 1.5 / 2 erano spariti. Non saprei a chi chiedere di modificare gli articoli di Wikipedia, non mi sentirei qualificato per modificare un post del genere. Forse avvisare il team di GRUB2 sarebbe la prossima cosa migliore?
slm

@psusi - ecco il rif. agli stadi eliminati. documenti per GRUB2: gnu.org/software/grub/manual/grub.html ... "I file di immagine (vedi Immagini) che compongono GRUB sono stati riorganizzati; Fase 1, Fase 1.5 e Fase 2 non sono più."
slm

6

A Linux (il kernel) non importa quante partizioni di avvio hai. Caricamento del kernel dal disco è il lavoro del bootloader (ad esempio grub, grub2, lilo) e questi strumenti, inoltre, non si preoccupano il numero di posizioni un kernel potrebbe trovarsi. Si preoccupano solo della posizione specifica.

Ad esempio, la mia partizione di avvio è /dev/md1, che è un mirror RAID mdadm supportato dalle partizioni fisiche /dev/sde1e /dev/sdf1. Posso montarli singolarmente se volevo e come tale tecnicamente conta avere due partizioni di avvio, anche se dovrebbero contenere gli stessi dati.

Avere due partizioni per / boot per me è un problema di disponibilità, ma potrebbero ugualmente essere diverse / partizioni di boot. Il prossimo passo è sapere come fa il bootloader? Ecco come:

menuentry 'Linux 3.10.17 (sde) kernel-3.10.17-g' {
        root=hd0,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3
        initrd /boot/initrd-3.10.17-g
}

menuentry 'Linux 3.10.17 (sdf) kernel-3.10.17-g' {
        root=hd1,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3 
        initrd /boot/initrd-3.10.17-g
}

Questo è un estratto da una grub2configurazione e noterai che le uniche differenze sono root=hd0,1e root=hd1,1che stabiliscono quale partizione di avvio fa riferimento a quella voce.


Ora ti accompagno attraverso uno stivale in modo da poter capire cosa sta succedendo qui.

  • Il BIOS legge l'MBR dal volume di avvio e passa al bootloader
  • Il bootloader (ad es. grub2) È configurato per sapere quale dispositivo e partizione contiene il kernel. Grub2 accede direttamente a questa partizione e carica il kernel in memoria.
  • Il tuo bootloader salta quindi nel kernel e il kernel avvia il tuo computer.

Il bootloader non si preoccupa di quante partizioni di avvio hai, si preoccupa solo di dove si trovano e devi comunicarle tali informazioni.

Al kernel non importa quante partizioni di avvio hai, perché non ha mai bisogno di vederle (devi solo averlo disponibile per aggiungere nuovi kernel, per esempio).

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.