Il kernel ha una funzione main ()? [chiuso]


52

Sto imparando i driver di dispositivo e la programmazione del kernel. Secondo il libro di Jonathan Corbet, non c'è alcuna main()funzione nei driver di dispositivo.

Quindi ho due domande:

  • Perché non abbiamo bisogno di una main()funzione nei driver di dispositivo?
  • Il kernel stesso ha una main()funzione?

Qualcuno può spiegarmelo?


1
Anche richiesto dallo stesso utente qui: stackoverflow.com/q/18266063/827263
Keith Thompson

@KeithThompson ... Sì ... Solo perché non ho ricevuto risposta quello che voglio, quindi l'ho chiesto qui.
Qualcuno il

@Shadur ... comunque adesso sta per chiudere ... E non ho il privilegio di migrare quello ...
qualcuno

Questo avrebbe dovuto essere chiuso al contrario, questo ha molte più viste :-)
Ciro Santilli 23 改造 中心 法轮功 六四 事件

Risposte:


82

Nei programmi di spazio utente, main()è il punto di ingresso al programma che viene chiamato dal codice di inizializzazione libc quando viene eseguito il binario. Il codice del kernel non ha il lusso di fare affidamento su libc, in quanto la stessa libc si affida all'interfaccia syscall del kernel per l'allocazione della memoria, l'I / O, la gestione dei processi ecc.

Detto questo, l'equivalente di main()nel codice del kernel è start_kernel(), che viene chiamato dal bootloader dopo aver caricato l'immagine del kernel, l'ha decompressa in memoria e ha impostato l'hardware e il paging della memoria essenziali. start_kernel()esegue la maggior parte dell'installazione del sistema e alla fine genera il processo di init.

Il punto di ingresso ai moduli del kernel Linux è una funzione init che viene registrata con il kernel chiamando la module_init()macro. La funzione init del modulo registrata viene quindi chiamata dal codice del kernel attraverso la do_initcalls()funzione durante l'avvio del kernel.


11
Grazie per aver riconosciuto il vero scopo del mainmetodo in C. (È un malinteso fin troppo comune a cui il sistema operativo fa una chiamata diretta main, il che non è il caso e lo è ancora meno nel caso del C ++.) I ' Ti darei un altro voto se potessi solo per quello.
un CVn

1
@Thomas ... Grazie per questa eccellente risposta ....
Qualcuno

17

Il kernel non ha una mainfunzione. mainè un concetto del linguaggio C. Il kernel è scritto in C e assembly. Il codice di ingresso del kernel è scritto dall'assembly.

La sequenza di avvio è organizzata come segue:

  1. Il BIOS di solito carica un caricatore di avvio da un dispositivo di blocco di avvio. Un popolare boot loader in questo momento è grub.
  2. Grub carica un'immagine del kernel in ram, possibile con un dispositivo root iniziale ( initrd). Quindi viene eseguito il codice ad un certo indirizzo.
  3. L'immagine del kernel ha alcuni moduli del kernel, ad esempio: moduli del filesystem, driver di dispositivo. L'immagine del kernel usa il modulo filesystem per montare il filesystem root. Ora il kernel può caricare ed eseguire tutti i moduli del kernel dal disco.
  4. Il kernel esegue le attività di inizializzazione. Ad esempio: attraversare il bus PCI e trovare tutti i dispositivi PCI, inizializzare tutti i driver di dispositivo.
  5. Alla fine il kernel crea il processo 0 e il processo 1 (il initprocesso), cambia il contesto della CPU dall'anello 0 all'anello 3 e avvia il processo di inizializzazione (l'id del processo è 1). Ora l'avvio del kernel è terminato!
  6. Il initprogramma esegue tutti gli script init. Tutti i servizi sono stati avviati. Shell si chiama. Gli utenti possono accedere.

La mainfunzione è una funzione C. In realtà il metodo principale non è il punto di ingresso dei programmi C. Il runtime C chiama molte funzioni prima main. GCC ha una funzionalità estesa: costruttori. Le funzioni dichiarate "costruttore" vengono chiamate prima main.

Per esempio:

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 

Questa macro proviene dal progetto qemu.


Il metodo principale è il metodo ac. In realtà il metodo principale non è la voce del programma C. Il runtime ha chiamato molti metodi prima del metodo principale.
Edward Shen,

bene, il bios di solito carica un boot loader e quel boot loader carica un'immagine del kernel (e possibilmente un initrd). Il codice del kernel è nell'immagine del kernel, non initrd
Stéphane Chazelas,

GCC ha una funzionalità estesa: costruttore. La dichiarazione del metodo "costruttore" viene chiamata prima del metodo principale. Ad esempio: / * Questo non dovrebbe essere usato direttamente. Utilizzare invece block_init ecc. * / #define module_init (funzione, tipo) \ static void _attribute __ ((costruttore)) do_qemu_init ## function (void) {\ register_module_init (funzione, tipo); \}
Edward Shen,

1
initrd.img NON È l'immagine del kernel. È un insieme di moduli caricati dal kernel all'avvio. Le immagini del kernel di solito hanno nomi che iniziano con "vmlinuz" ma differiscono da distro a distro.
Riccioli d'oro

3
Questa risposta è piena zeppa di "tutto è un PC / Linux / i86" e si avvia in quel modo e il kernel è in quel modo ... Perché tutti pensano che sia l'unico modo possibile al mondo?
Jens,

9

Esiste una funzione main () in arch / x86 / boot / main.c per preparare il sistema a passare dalla modalità reale a quella protetta, ma altre architetture non hanno un codice simile. C'è una bella panoramica su come funziona l'avvio del kernel Linux 2.6.x sulla piattaforma x86. Vale davvero la pena leggerlo.

Secondo il documento HOWTO fare lo sviluppo del kernel Linux , il kernel Linux è

un ambiente C indipendente, senza fare affidamento sulla libreria C standard, quindi alcune parti dello standard C non sono supportate.

cosa significa secondo lo standard C BTW

È definito dall'implementazione se è necessario un programma in un ambiente indipendente per definire una funzione 'principale'.

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.