Le altre due risposte (al momento della stesura) parlano di interruzioni e IDT. Questo è corretto, tuttavia, su una moderna CPU Intel-esque, non ci sono meno di tre modi per chiamare un kernel.
Metodo n. 1: interrompe.
Questo è spiegato sopra. Si imposta una voce nella tabella del descrittore di interrupt / vettore di interrupt, quindi si esegue un interrupt di software per accedere al kernel.
Il vantaggio principale di questo metodo è che un kernel tipico deve essere in grado di gestire comunque gli interrupt e funziona su hardware arcaico.
Metodo n. 2: chiama gate.
Un gate di chiamata è un tipo speciale di selettore di segmento. Il target della chiamata deve essere caricato nella tabella dei descrittori di segmento globale o locale (rispettivamente GDT e LDT). Se esegui quindi un'istruzione di chiamata remota utilizzando il gate di chiamata come segmento (l'offset della chiamata viene ignorato), ciò consente di chiamare un codice più privilegiato. Le porte di chiamata sono estremamente flessibili; l'architettura IA-32 ha quattro livelli di privilegi e call gates ti consente di chiamare qualsiasi livello.
Non credo che Linux abbia mai usato le porte di chiamata, ma lo ha fatto Windows 95. I servizi del kernel Win95 ( krnl386.exe
e kernel.dll
) erano effettivamente eseguiti in modalità utente (anello 3). Il livello di privilegio più alto (anello 0) è stato utilizzato solo per i driver e un microkernel che ha eseguito solo la commutazione di processo. La chiamata ai driver è stata effettuata utilizzando le porte di chiamata. Ciò ha consentito al codice legacy a 16 bit (di cui ce n'era molto!) Di utilizzare i driver Win95 semplicemente usando una chiamata remota standard, proprio come facevano sempre.
La protezione inadeguata della tabella dei descrittori globali è stata la causa di numerosi exploit di Windows 95, che sono riusciti a installare le proprie porte di chiamata scrivendo sulla memoria.
Metodo n. 3: SYSCALL / SYSRET e SYSENTER / SYSEXIT
Queste sono due serie di istruzioni, inventate indipendentemente da AMD e Intel, ma essenzialmente fanno la stessa cosa. SYSCALL / SYSRET è arrivato per primo ed era solo AMD, SYSENTER / SYSEXIT era Intel, ma AMD lo implementa ora. Quindi descriverò SYSENTER / SYSEXIT.
A differenza delle porte di chiamata, SYSENTER può essere utilizzato solo per trasferire all'anello 0 e può trasferire solo in una posizione. Tuttavia, ha il vantaggio di avere una latenza estremamente bassa perché, diversamente da una chiamata o interruzione, non tocca lo stack.
Il percorso di trasferimento viene impostato utilizzando tre registri specifici del modello: uno per le informazioni sul segmento e uno per il puntatore dell'istruzione e il puntatore dello stack del codice del kernel. Poiché nulla viene "inserito" nello stack, il codice della modalità utente è responsabile del dire al kernel dove tornare passando il puntatore dell'istruzione return e il puntatore dello stack nei registri. Il kernel è responsabile del ripristino del puntatore dello stack e l'istruzione SYSEXIT ripristina il puntatore dell'istruzione.
Ulteriori informazioni sulle istruzioni SYSENTER e SYSEXIT.