2009-08-07 13 views
9

Ispirato da questa domandaCome avviene realmente un syscall su linux?

How can I force GDB to disassemble?

e correlati a questo uno

What is INT 21h?

Come avviene una chiamata di sistema in realtà sotto linux? cosa succede quando viene eseguita la chiamata, fino a quando non viene richiamata la vera routine del kernel?

+0

+1, domanda interessante! –

+0

la domanda di implementazione di syscall: http://stackoverflow.com/questions/499188/how-is-the-system-call-in-linux-implemented – nik

+0

votare me stesso per chiudere. anzi è duplicato (non è comparso sulla ricerca come ho usato syscall) –

risposta

8

Supponendo che stiamo parlando di X 86:

  1. Il ID of the system call è depositato nel registro EAX
  2. gli argomenti richiesti dalla chiamata di sistema sono depositati nella locations dictated by the system call. Ad esempio, alcune chiamate di sistema prevedono che il loro argomento risieda nel registro EBX. Altri possono aspettarsi che la loro discussione sia in cima alla pila.
  3. È stato richiamato un interrupt INT 0x80.
  4. Il kernel di Linux gestisce la chiamata di sistema identificata dall'ID nel registro EAX, depositando i risultati in posizioni predeterminate.
  5. Il codice chiamante utilizza qualsiasi risultato.

I può essere un po 'arrugginita a questo, è stato pochi anni ...

+0

Se ricordo bene, dal momento che il kernel ha il suo stack, nessun programma userspace può mettere qualcosa su di esso, quindi tutti gli argomenti devono essere passati attraverso i registri. – Benno

+0

Davvero? Ricordo vagamente che il mio professore ha menzionato che Linux aveva delle macro per mappare gli indirizzi userspace in kernelspace ... Potrei sbagliarmi. –

+3

INT 0x80 viene utilizzato solo quando le istruzioni SYSCALL/SYSENTER non sono disponibili, IIRC. –

3

Fondamentalmente, è molto semplice: qualche parte in memoria si trova una tabella in cui ciascun numero syscall e l'indirizzo del corrispondente conduttore è memorizzato (vedere http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S per la versione x86)

Il gestore di interrupt INT 0x80 quindi estrae gli argomenti dai registri, li mette nello stack (kernel) e chiama il gestore syscall appropriato.

7

Le risposte fornite sono corrette ma vorrei aggiungere che ci sono più meccanismi per accedere alla modalità kernel. Ogni kernel recente mappa la pagina "vsyscall" nello spazio degli indirizzi di ogni processo. Contiene poco più del più efficiente metodo trap di syscall.

Ad esempio, su un normale sistema a 32 bit potrebbe contenere:


0xffffe000: int $0x80 
0xffffe002: ret 

Ma sul mio 64 bitsystem ho accesso al modo metodo più efficiente utilizzando le istruzioni syscall/SYSENTER


0xffffe000: push %ecx 
0xffffe001: push %edx 
0xffffe002: push %ebp 
0xffffe003:  mov %esp,%ebp 
0xffffe005:  sysenter 
0xffffe007: nop  
0xffffe008: nop  
0xffffe009: nop  
0xffffe00a: nop  
0xffffe00b: nop  
0xffffe00c: nop  
0xffffe00d: nop  
0xffffe00e:  jmp 0xffffe003 
0xffffe010: pop %ebp 
0xffffe011: pop %edx 
0xffffe012: pop %ecx 
0xffffe013: ret  

Questa pagina di vsyscall mappa anche alcune chiamate di sistema che possono essere eseguite senza un interruttore di contesto. So certo gettimeofday, tempo e getcpu sono mappati lì, ma immagino getpid potrebbero rientrare in là altrettanto bene.

Problemi correlati