¿Cuál es la diferencia entre el espacio del kernel y el espacio del usuario? ¿El espacio del núcleo, los hilos del núcleo, los procesos del núcleo y la pila del núcleo significan lo mismo? Además, ¿por qué necesitamos esta diferenciación?
143
Respuestas:
La respuesta realmente simplificada es que el núcleo se ejecuta en el espacio del núcleo y los programas normales se ejecutan en el espacio del usuario. El espacio de usuario es básicamente una forma de sandboxing: restringe los programas de usuario para que no puedan meterse con la memoria (y otros recursos) propiedad de otros programas o del núcleo del sistema operativo. Esto limita (pero generalmente no elimina por completo) su capacidad para hacer cosas malas como estrellar la máquina.
El kernel es el núcleo del sistema operativo. Normalmente tiene acceso completo a toda la memoria y hardware de la máquina (y todo lo demás en la máquina). Para mantener la máquina lo más estable posible, normalmente solo desea que el código más confiable y probado se ejecute en modo kernel / espacio kernel.
La pila es solo otra parte de la memoria, por lo que, naturalmente, está segregada junto con el resto de la memoria.
fuente
La memoria de acceso aleatorio (RAM) se puede dividir lógicamente en dos regiones distintas a saber -. El espacio del núcleo y el espacio de usuario ( Las direcciones físicas de la memoria RAM no están realmente divididos sólo las direcciones virtuales , todo ello ejecutado por la MMU )
El núcleo se ejecuta en la parte de la memoria que tiene derecho a él. Los procesos de los usuarios normales no pueden acceder directamente a esta parte de la memoria, mientras que el núcleo puede acceder a todas las partes de la memoria. Para acceder a alguna parte del núcleo, los procesos de usuario tienen que usar el sistema de llamadas predefinido, es decir
open
,read
,write
etc. Además, lasC
funciones de la biblioteca comoprintf
llamada de la llamada al sistemawrite
a su vez.Las llamadas al sistema actúan como una interfaz entre los procesos del usuario y los procesos del núcleo. Los derechos de acceso se colocan en el espacio del kernel para evitar que los usuarios se equivoquen con el kernel, sin saberlo.
Entonces, cuando ocurre una llamada al sistema, se envía una interrupción de software al kernel. La CPU puede entregar el control temporalmente a la rutina asociada de manejo de interrupciones. El proceso del kernel que fue interrumpido por la interrupción se reanuda después de que la rutina de manejo de interrupciones termina su trabajo.
fuente
El espacio del kernel y el espacio virtual son conceptos de memoria virtual ... no significa que Ram (su memoria real) esté dividida en kernel y espacio de usuario. Cada proceso recibe memoria virtual que se divide en kernel y espacio de usuario.
Al decir "La memoria de acceso aleatorio (RAM) se puede dividir en dos regiones distintas, a saber: el espacio del núcleo y el espacio del usuario". Está Mal.
y con respecto a "espacio de kernel vs espacio de usuario"
Cuando se crea un proceso y su memoria virtual se divide en espacio de usuario y espacio de kernel, donde la región de espacio de usuario contiene datos, código, pila, montón del proceso y kernel-space contiene cosas como la tabla de páginas para el proceso , estructuras de datos del núcleo y código del núcleo, etc. Para ejecutar el código de espacio del núcleo, el control debe cambiar al modo de núcleo (usando la interrupción de software 0x80 para llamadas al sistema) y la pila de núcleo se comparte básicamente entre todos los procesos que se ejecutan actualmente en el espacio de núcleo.
fuente
Los anillos de CPU son la distinción más clara
En modo protegido x86, la CPU está siempre en uno de los 4 anillos. El kernel de Linux solo usa 0 y 3:
Esta es la definición más dura y rápida de kernel vs userland.
¿Por qué Linux no usa los anillos 1 y 2? Anillos de privilegio de CPU: ¿ Por qué no se usan los anillos 1 y 2 ?
¿Cómo se determina el anillo actual?
El anillo actual se selecciona mediante una combinación de:
tabla de descriptores globales: una tabla en memoria de entradas GDT, y cada entrada tiene un campo
Privl
que codifica el anillo.La instrucción LGDT establece la dirección en la tabla de descriptores actual.
Ver también: http://wiki.osdev.org/Global_Descriptor_Table
el segmento registra CS, DS, etc., que apuntan al índice de una entrada en el GDT.
Por ejemplo,
CS = 0
significa que la primera entrada del GDT está actualmente activa para el código de ejecución.¿Qué puede hacer cada anillo?
El chip de la CPU está construido físicamente para que:
el anillo 0 puede hacer cualquier cosa
ring 3 no puede ejecutar varias instrucciones y escribir en varios registros, especialmente:
no puede cambiar su propio anillo! De lo contrario, podría configurarse para sonar 0 y los anillos serían inútiles.
En otras palabras, no se puede modificar el descriptor de segmento actual , que determina el anillo actual.
no puede modificar las tablas de página: ¿Cómo funciona la paginación x86?
En otras palabras, no puede modificar el registro CR3, y la paginación misma evita la modificación de las tablas de página.
Esto evita que un proceso vea la memoria de otros procesos por razones de seguridad / facilidad de programación.
no puede registrar manejadores de interrupciones. Estos se configuran escribiendo en ubicaciones de memoria, lo que también se evita mediante paginación.
Los controladores se ejecutan en el anillo 0 y romperían el modelo de seguridad.
En otras palabras, no puede usar las instrucciones LGDT y LIDT.
no puede hacer instrucciones IO como
in
yout
, y por lo tanto tener accesos arbitrarios de hardware.De lo contrario, por ejemplo, los permisos de archivo serían inútiles si algún programa pudiera leer directamente desde el disco.
Más precisamente, gracias a Michael Petch : en realidad es posible que el sistema operativo permita instrucciones de E / S en el anillo 3, esto en realidad está controlado por el segmento de estado de la tarea .
Lo que no es posible es que el anillo 3 se dé permiso para hacerlo si no lo tenía en primer lugar.
Linux siempre lo rechaza. Ver también: ¿Por qué Linux no usa el cambio de contexto de hardware a través del TSS?
¿Cómo hacen la transición los programas y sistemas operativos entre anillos?
cuando se enciende la CPU, comienza a ejecutar el programa inicial en el anillo 0 (bueno, pero es una buena aproximación). Puede pensar que este programa inicial es el núcleo (pero normalmente es un gestor de arranque que luego llama al núcleo aún en el anillo 0 ).
cuando un proceso de userland quiere que el kernel haga algo por él, como escribir en un archivo, utiliza una instrucción que genera una interrupción como
int 0x80
osyscall
para señalar el kernel. x86-64 Linux syscall hello world ejemplo:compilar y ejecutar:
GitHub aguas arriba .
Cuando esto sucede, la CPU llama a un controlador de devolución de llamada de interrupción que el núcleo registró en el momento del arranque. Aquí hay un ejemplo concreto de metal desnudo que registra un controlador y lo usa .
Este controlador se ejecuta en el anillo 0, que decide si el núcleo permitirá esta acción, realiza la acción y reinicia el programa de usuario en el anillo 3. x86_64
cuando
exec
se utiliza la llamada al sistema (o cuando se inicia/init
el núcleo ), el núcleo prepara los registros y la memoria del nuevo proceso de usuario, luego salta al punto de entrada y cambia la CPU para que suene 3Si el programa intenta hacer algo malo como escribir en un registro prohibido o en una dirección de memoria (debido a la paginación), la CPU también llama a algún controlador de devolución de llamada del núcleo en el anillo 0.
Pero dado que el país de usuario era travieso, el núcleo podría matar el proceso esta vez, o darle una advertencia con una señal.
Cuando el kernel se inicia, configura un reloj de hardware con cierta frecuencia fija, que genera interrupciones periódicamente.
Este reloj de hardware genera interrupciones que ejecutan el anillo 0 y le permite programar qué procesos de usuario y tierra se activarán.
De esta manera, la programación puede ocurrir incluso si los procesos no realizan ninguna llamada al sistema.
¿Cuál es el punto de tener múltiples anillos?
Hay dos ventajas principales de separar el kernel y el userland:
¿Cómo jugar con eso?
He creado una configuración de metal desnudo que debería ser una buena manera de manipular los anillos directamente: https://github.com/cirosantilli/x86-bare-metal-examples
Desafortunadamente, no tuve la paciencia para hacer un ejemplo de tierra de usuario, pero fui tan lejos como la configuración de paginación, por lo que la tierra de usuario debería ser factible. Me encantaría ver una solicitud de extracción.
Alternativamente, los módulos del kernel de Linux se ejecutan en el anillo 0, por lo que puede usarlos para probar operaciones privilegiadas, por ejemplo, leer los registros de control: ¿Cómo acceder a los registros de control cr0, cr2, cr3 desde un programa? Obteniendo falla de segmentación
Aquí hay una configuración conveniente de QEMU + Buildroot para probarlo sin matar a su host.
La desventaja de los módulos del kernel es que otros kthreads se están ejecutando y podrían interferir con sus experimentos. Pero, en teoría, puede hacerse cargo de todos los controladores de interrupciones con su módulo de kernel y poseer el sistema, ese sería un proyecto interesante en realidad.
Anillos negativos
Si bien los anillos negativos no se mencionan realmente en el manual de Intel, en realidad hay modos de CPU que tienen capacidades adicionales que el anillo 0 en sí mismo, por lo que son una buena opción para el nombre de "anillo negativo".
Un ejemplo es el modo de hipervisor utilizado en la virtualización.
Para más detalles ver:
BRAZO
En ARM, los anillos se denominan niveles de excepción, pero las ideas principales siguen siendo las mismas.
Existen 4 niveles de excepción en ARMv8, comúnmente utilizados como:
EL0: userland
EL1: kernel ("supervisor" en terminología ARM).
Se ingresó con la
svc
instrucción (SuperVisor Call), anteriormente conocida comoswi
ensamblaje unificado anterior , que es la instrucción utilizada para realizar llamadas al sistema Linux. Hola ejemplo de ARMv8 mundial:hola s
GitHub aguas arriba .
Pruébelo con QEMU en Ubuntu 16.04:
Aquí hay un ejemplo concreto de metal desnudo que registra un controlador SVC y realiza una llamada SVC .
EL2: hipervisores , por ejemplo Xen .
Entró con la
hvc
instrucción (llamada HyperVisor).Un hipervisor es para un sistema operativo, lo que un sistema operativo es para el usuario.
Por ejemplo, Xen le permite ejecutar múltiples sistemas operativos, como Linux o Windows, en el mismo sistema al mismo tiempo, y aísla los sistemas operativos entre sí por seguridad y facilidad de depuración, al igual que Linux lo hace para los programas de usuario.
Los hipervisores son una parte clave de la infraestructura de la nube actual: permiten que varios servidores se ejecuten en un solo hardware, manteniendo el uso del hardware siempre cerca del 100% y ahorrando mucho dinero.
AWS, por ejemplo, usó Xen hasta 2017, cuando su traslado a KVM fue noticia .
EL3: otro nivel más. TODO ejemplo.
Entró con la
smc
instrucción (llamada en modo seguro)El modelo de referencia de arquitectura ARMv8 DDI 0487C.a - Capítulo D1 - El modelo del programador de nivel de sistema AArch64 - La figura D1-1 ilustra esto maravillosamente:
La situación de ARM cambió un poco con el advenimiento de ARMv8.1 Virtualization Host Extensions (VHE) . Esta extensión permite que el núcleo se ejecute en EL2 de manera eficiente:
VHE se creó porque las soluciones de virtualización del kernel en Linux, como KVM, han ganado terreno sobre Xen (ver, por ejemplo, el movimiento de AWS a KVM mencionado anteriormente), porque la mayoría de los clientes solo necesitan máquinas virtuales Linux, y como se pueden imaginar, todo en un solo proyecto, KVM es más simple y potencialmente más eficiente que Xen. Entonces, el kernel de Linux host actúa como el hipervisor en esos casos.
Observe cómo ARM, tal vez debido al beneficio de la retrospectiva, tiene una mejor convención de nomenclatura para los niveles de privilegio que x86, sin la necesidad de niveles negativos: 0 es el más bajo y 3 el más alto. Los niveles más altos tienden a crearse con más frecuencia que los más bajos.
El EL actual se puede consultar con la
MRS
instrucción: ¿cuál es el modo de ejecución actual / nivel de excepción, etc.?ARM no requiere que todos los niveles de excepción estén presentes para permitir implementaciones que no necesitan la función para guardar el área del chip. ARMv8 "Niveles de excepción" dice:
QEMU, por ejemplo, por defecto es EL1, pero EL2 y EL3 se pueden habilitar con opciones de línea de comando: qemu-system-aarch64 entrando en el1 al emular un encendido de a53
Fragmentos de código probados en Ubuntu 18.10.
fuente
El espacio del kernel y el espacio del usuario es la separación de las funciones privilegiadas del sistema operativo y las aplicaciones de usuario restringidas. La separación es necesaria para evitar que las aplicaciones del usuario saqueen su computadora. Sería malo que cualquier programa de usuario antiguo pudiera comenzar a escribir datos aleatorios en su disco duro o leer la memoria del espacio de memoria de otro programa de usuario.
Los programas de espacio de usuario no pueden acceder a los recursos del sistema directamente, por lo que el núcleo del sistema operativo maneja el acceso en nombre del programa. Los programas de espacio de usuario suelen realizar tales solicitudes al sistema operativo a través de llamadas del sistema.
Los hilos del kernel, los procesos, la pila no significan lo mismo. Son construcciones análogas para el espacio del núcleo como sus contrapartes en el espacio del usuario.
fuente
Cada proceso tiene sus propios 4 GB de memoria virtual que se asigna a la memoria física a través de tablas de páginas. La memoria virtual se divide principalmente en dos partes: 3 GB para el uso del proceso y 1 GB para el uso del Kernel. La mayoría de las variables que crea se encuentran en la primera parte del espacio de direcciones. Esa parte se llama espacio de usuario. La última parte es donde reside el núcleo y es común para todos los procesos. Esto se denomina espacio del núcleo y la mayor parte de este espacio se asigna a las ubicaciones iniciales de la memoria física donde se carga la imagen del núcleo en el momento del arranque.
fuente
El tamaño máximo del espacio de direcciones depende de la longitud del registro de direcciones en la CPU.
En sistemas con registros de direcciones de 32 bits, el tamaño máximo del espacio de direcciones es de 2 32 bytes, o 4 GiB. Del mismo modo, en sistemas de 64 bits, se pueden direccionar 2 64 bytes.
Dicho espacio de direcciones se denomina memoria virtual o espacio de direcciones virtuales . En realidad, no está relacionado con el tamaño físico de RAM.
En las plataformas Linux, el espacio de direcciones virtuales se divide en espacio de kernel y espacio de usuario.
Una constante específica de la arquitectura llamada límite de tamaño de tarea , o
TASK_SIZE
, marca la posición donde se produce la división:el rango de direcciones de 0 a
TASK_SIZE
-1 se asigna al espacio del usuario;el resto de
TASK_SIZE
hasta 2 32 -1 (o 2 64 -1) se asigna al espacio del núcleo.En un sistema particular de 32 bits, por ejemplo, se podrían ocupar 3 GiB para espacio de usuario y 1 GiB para espacio de kernel.
Cada aplicación / programa en un sistema operativo tipo Unix es un proceso; cada uno de ellos tiene un identificador único llamado Identificador de proceso (o simplemente ID de proceso , es decir, PID). Linux proporciona dos mecanismos para crear un proceso: 1. la
fork()
llamada al sistema, o 2. laexec()
llamada.Un hilo de kernel es un proceso ligero y también un programa en ejecución. Un solo proceso puede consistir en varios subprocesos que comparten los mismos datos y recursos pero que toman diferentes rutas a través del código del programa. Linux proporciona una
clone()
llamada al sistema para generar hilos.Ejemplos de usos de los hilos del kernel son: sincronización de datos de RAM, ayuda al planificador a distribuir procesos entre CPU, etc.
fuente
Brevemente: Kernel se ejecuta en Kernel Space, el espacio del kernel tiene acceso completo a toda la memoria y recursos, puede decir que la memoria se divide en dos partes, parte para el núcleo y parte para el propio proceso del usuario, (espacio del usuario) ejecuta programas normales, usuario space no puede acceder directamente al kernel space, por lo que solicita al kernel que use recursos. por syscall (llamada de sistema predefinida en glibc)
hay una declaración que simplifica los diferentes " El espacio del usuario es solo una carga de prueba para el núcleo " ...
Para ser muy claro: la arquitectura del procesador permite que la CPU funcione en dos modos, el modo Kernel y el modo de usuario , las instrucciones de hardware permiten cambiar de un modo a otro.
la memoria se puede marcar como parte del espacio del usuario o del espacio del núcleo.
Cuando la CPU se ejecuta en modo de usuario, la CPU puede acceder solo a la memoria que está en el espacio de usuario, mientras que la CPU intenta acceder a la memoria en el espacio del núcleo, el resultado es una "excepción de hardware", cuando la CPU se ejecuta en modo de núcleo, la CPU puede acceder directamente tanto al espacio del kernel como al espacio del usuario ...
fuente
El espacio del kernel significa que el kernel solo puede tocar un espacio de memoria. En Linux de 32 bits, es 1G (de 0xC0000000 a 0xffffffff como dirección de memoria virtual). Cada proceso creado por el núcleo también es un subproceso del núcleo, por lo que para un proceso, hay dos pilas: una pila en el espacio de usuario para este proceso y otra en el núcleo espacio para hilo del núcleo.
la pila del núcleo ocupaba 2 páginas (8k en 32 bits de Linux), incluye una task_struct (aproximadamente 1k) y la pila real (aproximadamente 7k). Este último se utiliza para almacenar algunas variables automáticas o parámetros de llamada de función o dirección de función en funciones del núcleo. Aquí está el código (Processor.h (linux \ include \ asm-i386)):
__get_free_pages (GFP_KERNEL, 1)) significa asignar memoria como 2 ^ 1 = 2 páginas.
Pero la pila de procesos es otra cosa, su dirección es inferior a 0xC0000000 (Linux de 32 bits), su tamaño puede ser bastante mayor, se utiliza para las llamadas de función de espacio de usuario.
Entonces, aquí hay una pregunta para la llamada al sistema, se está ejecutando en el espacio del kernel pero fue llamada por proceso en el espacio del usuario, ¿cómo funciona? ¿Linux pondrá sus parámetros y dirección de función en la pila del núcleo o en la pila de procesos? Solución de Linux: todas las llamadas al sistema se activan por la interrupción del software INT 0x80. Definido en la entrada S (linux \ arch \ i386 \ kernel), aquí hay algunas líneas, por ejemplo:
fuente
Por Sunil Yadav, sobre Quora:
fuente
EN el espacio del núcleo corto es la porción de memoria donde se ejecuta el kernel de Linux (1 GB de espacio virtual superior en el caso de Linux) y el espacio del usuario es la porción de memoria donde se ejecuta la aplicación del usuario (3 GB de memoria virtual inferior en el caso de Linux). quiero saber más ver el enlace que figura a continuación :)
http://learnlinuxconcepts.blogspot.in/2014/02/kernel-space-and-user-space.html
fuente
Intentando dar una explicación muy simplificada
La memoria virtual se divide en el espacio del kernel y el espacio del usuario. El espacio del núcleo es esa área de memoria virtual donde se ejecutarán los procesos del núcleo y el espacio del usuario es esa área de memoria virtual donde se ejecutarán los procesos del usuario.
Esta división es necesaria para las protecciones de acceso a la memoria.
Cada vez que un gestor de arranque inicia un kernel después de cargarlo en una ubicación en la RAM, (en un controlador basado en ARM normalmente) debe asegurarse de que el controlador esté en modo supervisor con FIQ e IRQ deshabilitados.
fuente
Kernel Space y User Space son espacios lógicos.
La mayoría de los procesadores modernos están diseñados para ejecutarse en diferentes modos privilegiados. Las máquinas x86 pueden ejecutarse en 4 modos privilegiados diferentes.
Y una instrucción de máquina particular se puede ejecutar cuando está en / sobre un modo privilegiado particular.
Debido a este diseño, está brindando protección al sistema o protegiendo el entorno de ejecución.
Kernel es un fragmento de código que administra su hardware y proporciona abstracción del sistema. Por lo tanto, debe tener acceso para todas las instrucciones de la máquina. Y es la pieza de software más confiable. Entonces debería ser ejecutado con el más alto privilegio. Y el nivel de anillo 0 es el modo más privilegiado. Entonces Ring Level 0 también se llama Kernel Mode .
La aplicación de usuario es una pieza de software que proviene de un proveedor externo, y no puede confiar completamente en ellas. Alguien con intención maliciosa puede escribir un código para bloquear su sistema si tuviera acceso completo a todas las instrucciones de la máquina. Por lo tanto, la aplicación debe tener acceso a un conjunto limitado de instrucciones. Y Ring Level 3 es el modo menos privilegiado. Entonces, toda su aplicación se ejecuta en ese modo. Por lo tanto, ese Nivel de timbre 3 también se llama Modo de usuario .
Nota: No obtengo los niveles de anillo 1 y 2. Básicamente son modos con privilegios intermedios. Por lo tanto, es posible que el código del controlador del dispositivo se ejecute con este privilegio. AFAIK, linux usa solo Ring Level 0 y 3 para la ejecución del código del kernel y la aplicación del usuario respectivamente.
Por lo tanto, cualquier operación que ocurra en modo kernel puede considerarse como espacio kernel. Y cualquier operación que ocurra en modo de usuario puede considerarse como espacio de usuario.
fuente
La respuesta correcta es: no existe el espacio del kernel y el espacio del usuario. El conjunto de instrucciones del procesador tiene permisos especiales para establecer elementos destructivos como la raíz del mapa de la tabla de páginas o acceder a la memoria del dispositivo de hardware, etc.
El código del kernel tiene los privilegios de nivel más alto y el código de usuario el más bajo. Esto evita que el código de usuario bloquee el sistema, modifique otros programas, etc.
En general, el código del kernel se mantiene en un mapa de memoria diferente al del usuario (al igual que los espacios de usuario se guardan en mapas de memoria diferentes entre sí). Aquí es de donde provienen los términos "espacio del núcleo" y "espacio del usuario". Pero esa no es una regla difícil y rápida. Por ejemplo, dado que el x86 requiere indirectamente que sus controladores de interrupción / captura estén asignados en todo momento, parte (o algunos SO todos) del núcleo debe asignarse al espacio del usuario. Nuevamente, esto no significa que dicho código tenga privilegios de usuario.
¿Por qué es necesaria la división kernel / user? Algunos diseñadores no están de acuerdo en que sea, de hecho, necesario. La arquitectura de microkernel se basa en la idea de que las secciones de código con los privilegios más altos deben ser lo más pequeñas posible, con todas las operaciones importantes realizadas en código con privilegios de usuario. Tendría que estudiar por qué podría ser una buena idea, no es un concepto simple (y es famoso por tener ventajas y desventajas).
fuente
La memoria se divide en dos áreas distintas:
Los procesos que se ejecutan en el espacio del usuario tienen acceso solo a una parte limitada de la memoria, mientras que el núcleo tiene acceso a toda la memoria. Los procesos que se ejecutan en el espacio del usuario tampoco tienen acceso al espacio del kernel. Los procesos de espacio de usuario solo pueden acceder a una pequeña parte del núcleo a través de una interfaz expuesta por el núcleo: el sistema llama. Si un proceso realiza una llamada al sistema, se envía una interrupción de software al núcleo, que luego envía el controlador de interrupciones apropiado y continúa su trabajo después de que el controlador haya terminado.
fuente
En Linux hay dos espacios, el primero es el espacio del usuario y otro es el espacio del núcleo. el espacio de usuario consta de solo una aplicación de usuario que desea ejecutar. Como el servicio kernal, hay gestión de procesos, gestión de archivos, manejo de señales, gestión de memoria, gestión de subprocesos, y muchos servicios están presentes allí. si ejecuta la aplicación desde el espacio de usuario, esa aplicación interactúa solo con el servicio kernal. y ese servicio es interactuar con el controlador del dispositivo que está presente entre el hardware y el núcleo. El principal beneficio del espacio kernal y la separación del espacio de usuario es que podemos garantizar la seguridad mediante el virus.bcaz de todas las aplicaciones de usuario presentes en el espacio de usuario, y el servicio está presente en el espacio kernal. Es por eso que Linux no afecta el virus.
fuente