2009-08-07 15 views
9

Inspirado por esta pregunta¿Cómo ocurre realmente un syscall en Linux?

How can I force GDB to disassemble?

y relacionados con éste

What is INT 21h?

¿Cómo se produce una llamada al sistema en realidad bajo Linux? ¿Qué sucede cuando se realiza la llamada, hasta que se invoca la rutina real del kernel?

+0

+1, pregunta interesante! –

+0

la pregunta de implementación de syscall: http://stackoverflow.com/questions/499188/how-is-the-system-call-in-linux-implemented – nik

+0

votando yo mismo para cerrar. de hecho es duplicado (no apareció en la búsqueda como usé syscall) –

Respuesta

8

Suponiendo que estamos hablando de 86:

  1. El ID of the system call se deposita en el registro EAX
  2. Los argumentos necesarios por la llamada al sistema se depositan en el locations dictated by the system call. Por ejemplo, algunas llamadas al sistema esperan que su argumento resida en el registro EBX. Otros pueden esperar que su argumento esté en la parte superior de la pila.
  3. Se invoca una interrupción INT 0x80.
  4. El núcleo de Linux da servicio a la llamada al sistema identificada por la ID en el registro EAX, depositando los resultados en ubicaciones predeterminadas.
  5. El código de llamada hace uso de cualquier resultado.

Puede que sea un poco oxidado en esto, ha sido un par de años ...

+0

Si mal no recuerdo, dado que el kernel tiene su propia pila, ningún programa de espacio de usuario puede poner algo en ella, por lo que todos los argumentos deben pasarse a través de los registros. – Benno

+0

¿De verdad? Recuerdo vagamente a mi profesor que mencionaba que Linux tenía algunas macros para mapear direcciones de espacio de usuario en el espacio del kernel ... Podría estar equivocado. –

+3

INT 0x80 solo se usa cuando las instrucciones SYSCALL/SYSENTER no están disponibles, IIRC. –

3

Básicamente, es muy simple: En algún lugar de la memoria se encuentra una mesa en la que cada número de llamada al sistema y la dirección del manejador correspondiente se almacena (vea http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S para la versión x86)

El controlador de interrupción INT 0x80 simplemente saca los argumentos de los registros, los coloca en la pila (kernel) y llama al controlador de syscall apropiado.

7

Las respuestas dadas son correctas, pero me gustaría agregar que hay más mecanismos para ingresar al modo kernel. Cada núcleo reciente mapea la página "vsyscall" en el espacio de direcciones de cada proceso. Contiene poco más que el método de captura de syscall más eficiente.

Por ejemplo, en un sistema regular de 32 bits podría contener:


0xffffe000: int $0x80 
0xffffe002: ret 

Pero en mi 64 bitsystem tengo acceso a la forma del método más eficiente el uso de las instrucciones 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  

Esta página vsyscall también mapea algunas llamadas al sistema que se pueden realizar sin un cambio de contexto. Sé cierta gettimeofday, tiempo y getcpu se asignan allí, pero me imagino GETPID podrían caber allí igual de bien.

Cuestiones relacionadas