2012-08-10 31 views
6

Estoy aprendiendo sobre Linux kernel pero no entiendo cómo cambiar de modo de usuario a modo kernel en Linux. ¿como funciona? ¿podría darme algún consejo o darme algún enlace para referirse a él o algún libro sobre esto? muchas gracias!¿Cómo pasar del modo de usuario al modo kernel?

+0

¿Cuál es el contexto de su pregunta? ¿Estás preguntando sobre mecanismos de CPU específicos en una CPU específica o en general? ¿Hay algún problema que estés tratando de resolver? –

Respuesta

11

La única forma de una aplicación de espacio de usuario puede iniciar de manera explícita un interruptor al modo kernel durante el funcionamiento normal es al hacer una llamada al sistema, como open, read, etc. write

Cada vez que una aplicación de usuario llama a estas API llamada al sistema con los parámetros apropiados, se activa una interrupción/excepción de software (SWI).

Como resultado de este SWI, el control de la ejecución del código salta de la aplicación del usuario a una ubicación predefinida en la Tabla de vectores de interrupción [IVT] proporcionada por el sistema operativo.

Este IVT contiene una dirección para la rutina del manejador de excepciones SWI, que realiza todos los pasos necesarios para cambiar la aplicación del usuario al modo kernel y comenzar a ejecutar las instrucciones del kernel en nombre del proceso del usuario.

+2

No del todo. En x86, cualquier excepción que se origine en el modo de usuario transferirá el control al controlador de excepción apropiado en el SO, en modo kernel. –

+0

Es cierto. Tan pronto como publiqué mi respuesta, quise editarla, lo que refleja que es el caso cuando la aplicación del usuario quiere cambiar explícitamente al modo kernel. Sin embargo, tuve problemas para hacerlo debido a problemas de red. Lo he editado ahora para reflejar esto. –

+0

@AmarnathRevanna ¿Cómo sabe el sistema operativo que de hecho ha cambiado al modo kernel al realizar el mantenimiento de un SWI? ¿Hay un registro/bit de hardware específico que realiza un seguimiento del modo para ser supervisor (anillo 0)/usuario (anillo 3) y se actualiza en un SWI? Básicamente, lo que afirma el cambio al modo de usuario a kernel en el nivel de hardware. – Shyam

0

Acabo de leer esto, y es un recurso bastante bueno. Explica el modo de usuario y el modo kernel, por qué ocurren los cambios, qué tan caros son y da una lectura relacionada interesante.

http://www.codinghorror.com/blog/2008/01/understanding-user-and-kernel-mode.html

Aquí es un breve extracto:

Kernel Mode

en modo kernel, el código que se ejecuta tiene acceso completo y sin restricciones al hardware subyacente. Puede ejecutar cualquier instrucción de CPU y hacer referencia a cualquier dirección de memoria. El modo kernel generalmente se reserva para las funciones más confiables y de nivel más bajo del sistema operativo. Los bloqueos en modo núcleo son catastróficos; detendrán toda la PC.

modo de usuario

en modo de usuario, el código que se ejecuta no tiene capacidad para acceder directamente a la memoria del hardware o de referencia. El código que se ejecuta en modo de usuario debe delegar en las API del sistema para acceder al hardware o la memoria. Debido a la protección que brinda este tipo de aislamiento, los bloqueos en el modo de usuario siempre son recuperables. La mayor parte del código que se ejecuta en su computadora se ejecutará en modo de usuario.

1

Para pasar del modo de usuario al modo kernel, debe realizar una llamada al sistema.

Si solo quiere ver lo que está sucediendo bajo el capó, vaya a TLDP is your new friend y vea el código (está bien documentado, no necesita conocimientos adicionales para comprender un código de ensamblaje).

usted está interesado en:

movl $len,%edx   # third argument: message length 
    movl $msg,%ecx   # second argument: pointer to message to write 
    movl $1,%ebx    # first argument: file handle (stdout) 
    movl $4,%eax    # system call number (sys_write) 
    int  $0x80    # call kernel 

Como se puede ver, una llamada al sistema es sólo un envoltorio alrededor del código de montaje, que lleva a cabo una interrupción (0x80) y como resultado un controlador para esta llamada al sistema sera llamado.

Vamos a engañar un poco y usar un preprocesador C aquí para construir un ejecutable (foo.S es un archivo donde se coloca un código desde el siguiente enlace):

gcc -o foo -nostdlib foo.S 

Run que a través de strace para asegurar que conseguiremos lo que escribimos:

$ strace -t ./foo 
09:38:28 execve("./foo", ["./foo"], 0x7ffeb5b771d8 /* 57 vars */) = 0 
09:38:28 stat(NULL, Hello, world! 
NULL)    = 14 
09:38:28 write(0, NULL, 14)  
Cuestiones relacionadas