GNU/Linux >> Tutoriales Linux >  >> Linux

pila de kernel y pila de espacio de usuario

  1. ¿Cuál es la diferencia entre la pila del kernel y la pila del usuario?

En resumen, nada, además de usar una ubicación diferente en la memoria (y, por lo tanto, un valor diferente para el registro del puntero de pila) y, por lo general, diferentes protecciones de acceso a la memoria. Es decir. cuando se ejecuta en modo de usuario, la memoria del kernel (parte de la cual es la pila del kernel) no será accesible incluso si está asignada. Viceversa, sin que el código del kernel lo solicite explícitamente (en Linux, a través de funciones como copy_from_user() ), la memoria del usuario (incluida la pila del usuario) no suele ser accesible directamente.

  1. ¿Por qué se usa [una] pila de kernel separada?

Separación de privilegios y seguridad. Por un lado, los programas de espacio de usuario pueden hacer que su pila (puntero) sea lo que quieran y, por lo general, no existe un requisito arquitectónico para tener uno válido. Por lo tanto, el kernel no puede confiar el puntero de la pila del espacio del usuario sea válido ni utilizable y, por lo tanto, requerirá un conjunto bajo su propio control. Diferentes arquitecturas de CPU implementan esto de diferentes maneras; Las CPU x86 cambian automáticamente los punteros de pila cuando se producen cambios de modo de privilegio, y los valores que se usarán para diferentes niveles de privilegio son configurables, mediante código privilegiado (es decir, solo el kernel).

  1. Si se declara una variable local en una ISR, ¿dónde se almacenará?

En la pila del núcleo. El kernel (kernel de Linux, es decir) no conecte los ISR directamente a las puertas de interrupción de la arquitectura x86 sino que delega el envío de interrupciones a un mecanismo común de entrada/salida de interrupciones del núcleo que guarda el estado de registro anterior a la interrupción antes de llamar a los controladores registrados. La propia CPU, cuando envía una interrupción, puede ejecutar un privilegio y/o un cambio de pila, y el núcleo lo usa/configura para que el código de entrada de interrupción común ya pueda depender de la presencia de una pila de núcleo.
Dicho esto, las interrupciones que ocurren mientras se ejecuta el código del kernel simplemente (continuarán) utilizando la pila del kernel en ese momento. Esto puede, si los controladores de interrupción tienen rutas de llamadas profundamente anidadas, provocar desbordamientos de pila (si se interrumpe una ruta de llamada profunda del kernel y el controlador provoca otra ruta profunda; en Linux, el código RAID del sistema de archivos/software interrumpido por el código de red con iptables activo es se sabe que se activa en kernels más antiguos no optimizados... la solución es aumentar el tamaño de la pila del kernel para tales cargas de trabajo).

  1. ¿Cada proceso tiene su propia pila de kernel?

No solo cada proceso, cada hilo tiene su propia pila de kernel (y, de hecho, también su propia pila de usuario). Recuerde que la única diferencia entre procesos y subprocesos (para Linux) es el hecho de que múltiples subprocesos pueden compartir un espacio de direcciones (formando un proceso).

  1. ¿Cómo se coordina el proceso entre estas dos pilas?

En absoluto, no es necesario. La programación (cómo/cuándo se ejecutan diferentes subprocesos, cómo se guarda y restaura su estado) es tarea del sistema operativo y los procesos no necesitan preocuparse por esto. A medida que se crean subprocesos (y cada proceso debe tener al menos un subproceso), el kernel crea pilas de kernel para ellos, mientras que las pilas de espacio de usuario se crean/proporcionan explícitamente mediante cualquier mecanismo que se utilice para crear un subproceso (funciones como makecontext() o pthread_create() permitir que la persona que llama especifique una región de memoria que se usará para la pila del subproceso "secundario"), o heredada (mediante la clonación de memoria en acceso, generalmente llamada "copia en escritura" / COW, al crear un nuevo proceso).
Dicho esto, el proceso puede influir en la programación de sus subprocesos y/o influir en el contexto (estado, entre eso está el puntero de pila del hilo). Hay varias formas de hacerlo:señales UNIX, setcontext() , pthread_yield() / pthread_cancel() , ... - pero esto se está desviando un poco de la pregunta original.


Mi respuesta se recopila de otras preguntas SO con mis cosas.

What's the difference between kernel stack and user stack?

Como programador del kernel, sabe que el kernel debe estar restringido de programas de usuario erróneos. Supongamos que mantiene la misma pila para el kernel y el espacio del usuario, luego una simple falla de segmento en la aplicación del usuario bloquea el kernel y necesita reiniciarse.

Hay una "pila de kernel" por CPU como ISR Stack y una "pila de kernel" por proceso. Hay una "pila de usuario" para cada proceso, aunque cada subproceso tiene su propia pila, incluidos los subprocesos de usuario y kernel.

http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html

Why kernel stack is used?

Entonces, cuando estamos en modo kernel, el tipo de mecanismo de pila es necesario para tratar con llamadas a funciones, variables locales similares al espacio del usuario.

http://www.kernel.org/doc/Documentation/x86/kernel-stacks

If a local variable is declared in an ISR, where it will be stored?

Se almacenará en la pila ISR (IRQSTACKSIZE). El ISR se ejecuta en una pila de interrupciones separada solo si el hardware lo admite. De lo contrario, los marcos de la pila ISR se empujan a la pila del subproceso interrumpido.

El espacio del usuario no sabe y, francamente, no le importa si la interrupción se sirve en la pila del kernel del proceso actual o en una pila ISR separada. Como las interrupciones vienen por CPU, la pila ISR tiene que ser por CPU.

 Does each process has its own kernel stack ?

Sí. Cada proceso tiene su propia pila de kernel.

 Then how the process coordinates between both these stacks?

La respuesta de @FrankH me parece genial.


Linux
  1. Aprenda la diferencia entre los comandos "su" y "su -" en Linux

  2. Usuarios y Grupos

  3. ¿Obtener tiempo de usuario y kernel de un proceso en ejecución?

  4. ¿Cómo asignar un búfer del kernel de Linux al espacio del usuario?

  5. Evite que el usuario escriba un espacio accidental entre rm y comodín

Comandos Pushd y Popd en Linux

Comando id de Linux - Imprimir información de ID de usuario e ID de grupo

Kernel de Linux y sus funciones

Crear y configurar un usuario en MSSQL

AWK y nombres de archivo con espacio en él.

¿Cuál es la diferencia entre el espacio de usuario y el espacio del kernel?