¿Necesitaría un ejecutable un kernel de SO para ejecutarse?

52

Sé que cuando se compila el código fuente, en C ++, la salida del compilador es el código de la máquina (ejecutable) que pensé que eran instrucciones directamente para la CPU. Recientemente estuve leyendo sobre los kernels y descubrí que los programas no pueden acceder directamente al hardware, sino que tienen que pasar por el kernel.

Entonces, cuando compilamos un código fuente simple, digamos con solo un printf() y la compilación produce el código de máquina ejecutable, cada instrucción en este código de máquina se ejecutará directamente desde la memoria (una vez que el sistema operativo haya cargado el código) o cada comando en el código de la máquina deberá pasar por el sistema operativo (kernel) para ser ejecutado?

he leído una pregunta similar . No explicó si el código de máquina que se genera después de la compilación es una instrucción para la CPU directamente o si tendrá que pasar nuevamente por el núcleo para crear la instrucción correcta para la CPU. Es decir, ¿qué sucede después de que el código de la máquina se carga en la memoria? ¿Pasará por el núcleo o hablará directamente con el procesador?

GRANZER
fuente
29
Si estás escribiendo código para un Arduino no necesitas un sistema operativo.
stib
12
printf No es un gran ejemplo. Está definido explícitamente por la especificación C como una función que solo está disponible en implementaciones "alojadas" (es decir, ejecutarse en un kernel, en lugar de "independiente", que puede no requerir una). Y en la mayoría de las plataformas, printf Es solo una función proporcionada por su libc eso hace un montón de cosas en su nombre (que eventualmente incluye un syscall para imprimir en stdout). Realmente no es diferente de llamar libvlc_media_list_add_media o PyObject_GetAttr, salvo que algunos printf La implementación se garantiza enlazable sin agregar extra no estándar -l s.
abarnert
1
¡Esto existe! (No afiliado, solo pensé que era genial) erikyyy.de/invaders
Nonny Moose
9
Esto realmente depende de su definición precisa de los términos "ejecutable", "kernel", "ejecutar", "necesita", "hablar" y "pasar". Sin una definición precisa de esos términos, la pregunta no se puede responder.
Jörg W Mittag
3
@ JörgWMittag: si va a ser pedante, ¿por qué solo está examinando esos términos y solo esta pregunta? El término verdaderamente saliente que debe definirse es "sistema operativo", que se aplica de manera cuestionable a MS-DOS (y entornos similares de tiempo de ejecución de una sola tarea). Si hay algunas personas (mal informadas) que piensan que la PC BIOS es un sistema operativo , entonces está todo en juego? Yo creo que no. El OP usa esas palabras en un contexto que parece razonable (especialmente si no habla inglés) o no técnico.
sawdust

Respuestas:

85

Como alguien que ha escrito programas que se ejecutan sin un sistema operativo, ofrezco una respuesta definitiva.

¿Necesitaría un ejecutable un kernel de SO para ejecutarse?

Eso depende de cómo ese programa fue escrito y construido.
Podría escribir un programa (suponiendo que tenga los conocimientos) que no requiera un sistema operativo en absoluto.
Tal programa se describe como ser único .
Los cargadores de arranque y los programas de diagnóstico son usos típicos de los programas independientes.

Sin embargo, el programa típico escrito y integrado en algún entorno de sistema operativo host se ejecutaría en ese mismo entorno de sistema operativo.
Se requieren decisiones y acciones muy explícitas para escribir y construir un programa independiente.


... la salida del compilador es el código de máquina (ejecutable) que pensé que eran instrucciones directamente para la CPU.

Correcto.

Recientemente estuve leyendo sobre los kernels y descubrí que los programas no pueden acceder directamente al hardware, sino que tienen que pasar por el kernel.

Esa es una restricción impuesta por un modo de CPU que el sistema operativo utiliza para ejecutar programas, y se facilita mediante ciertas herramientas de compilación, como compiladores y bibliotecas.
No es una limitación intrínseca en cada programa escrito.


Entonces, cuando compilemos un código fuente simple, digamos con solo una función printf (), y la compilación produzca el código de máquina ejecutable, cada instrucción en este código de máquina se ejecutará directamente desde la memoria (una vez que el sistema operativo cargue el código en la memoria). ) ¿O será necesario que cada comando en el código de la máquina pase por el sistema operativo (kernel) para ser ejecutado?

Cada instrucción es ejecutada por la CPU.
Una instrucción que no es compatible o ilegal (por ejemplo, el proceso no tiene privilegios suficientes) causará una excepción inmediata, y la CPU ejecutará una rutina para manejar esta condición inusual.

UNA printf () La función no debe ser usada como un ejemplo de "código fuente simple" .
La traducción de un lenguaje de programación de alto nivel orientado a objetos a código de máquina puede no ser tan trivial como usted implica.
Y luego elige una de las funciones más complejas de una biblioteca de tiempo de ejecución que realiza conversiones de datos y I / O.

Tenga en cuenta que su pregunta estipula un entorno con un sistema operativo (y una biblioteca de tiempo de ejecución).
Una vez que el sistema se inicia y el sistema operativo recibe el control de la computadora, se imponen restricciones sobre lo que puede hacer un programa (por ejemplo, el sistema operativo debe realizar la E / S).
Si espera ejecutar un programa independiente (es decir, sin un sistema operativo), no debe iniciar la computadora para ejecutar el sistema operativo.


... ¿Qué sucede después de que el código de máquina se carga en la memoria?

Eso depende del medio ambiente.

Para un programa independiente, se puede ejecutar, es decir, el control se entrega saltando a la dirección de inicio del programa.

Para un programa cargado por el sistema operativo, el programa debe estar vinculado dinámicamente con bibliotecas compartidas de las que depende. El sistema operativo debe crear un espacio de ejecución para el proceso que ejecutará el programa.

¿Pasará por el núcleo o hablará directamente con el procesador?

El código de máquina es ejecutado por la CPU.
Ellos no "ir a través del núcleo" , pero tampoco ellos "hablar con el procesador" .
El código de la máquina (que consta de un código de operación y operandos) es una instrucción a la CPU que se decodifica y se realiza la operación.

Quizás el siguiente tema que debes investigar es Modos de CPU .

sawdust
fuente
2
"Si espera ejecutar un programa independiente (es decir, sin un sistema operativo), no debe iniciar la computadora para ejecutar el sistema operativo". no es del todo correcto. Muchos programas de DOS se cargaron después de DOS y luego se ignoraron por completo los servicios de DOS (directamente mediante bit banging o tal vez llamando directamente a BIOS). Win3.x es un excelente ejemplo que (excepto en algunos casos de esquina interesantes) ignoró que DOS estaba presente. Win95 / 98 / Me hizo esto también. Hay muchos ejemplos de sistemas operativos que admiten programas independientes, muchos de la era de 8/16 bits.
Eric Towers
8
@EricTowers - Por "DOS" ¿Presumiblemente te refieres a MS-DOS (ya que he usado DOS no relacionadas con MS o Intel)? Está citando un "sistema operativo" que ni siquiera coincide con los criterios de mis libros de texto universitarios de 1970 sobre conceptos y diseño de sistemas operativos. Los orígenes de MS-DOS se remontan (a través de Seattle Computer Products) a CP / M, que su autor Gary Kildall explícitamente no llama un sistema operativo. FWIW, un sistema operativo que permite que un programa tome el control del sistema ha fallado en su función básica de administrar los recursos del sistema. "Hay muchos ejemplos de sistemas operativos que admiten programas independientes" - "Apoyo" o incapaz de prevenir?
sawdust
3
Me gusta la terminología "independiente" de GCC. La palabra en inglés tiene todas las connotaciones correctas para el código que se ejecuta sin un sistema operativo, tal vez incluso mejor que "independiente". p.ej. puedes compilar gcc -O2 -ffreestanding my_kernel.c special_sauce.S para hacer un ejecutable que no asuma que ninguna de las bibliotecas normales o el sistema operativo estarán allí. (Por supuesto, normalmente necesitaría un script de enlace para que se vincule de manera útil a un formato de archivo que un cargador de arranque querrá cargar.)
Peter Cordes
4
@PeterCordes "standalone" es el término usado en el estándar C que IMO puede considerarse algo autoritario. Alternativamente, un buen término también es "no alojado" (como está alojado en el sistema operativo)
Jan Dorniak
38

El kernel es "simplemente" más código. Es solo que ese código es una capa que vive entre las partes más bajas de su sistema y el hardware real.

Todo se ejecuta directamente en la CPU, solo hace una transición a través de las capas para hacer cualquier cosa.

Su programa "necesita" el kernel de la misma manera que necesita las bibliotecas estándar de C para utilizar printf comando en el primer lugar.

El código real de su programa se ejecuta en la CPU, pero las ramas que el código hace para imprimir algo en la pantalla pasan por el código de la C printf función, a través de varios otros sistemas e intérpretes, cada uno de los cuales hace su propio procesamiento para trabajar solo cómo hello world! En realidad se imprime en su pantalla.

Digamos que tiene un programa de terminal ejecutándose en un administrador de ventanas de escritorio, ejecutándose en su kernel que a su vez se está ejecutando en su hardware.

Hay mucho más que sigue, pero sea sencillo ...

  1. En tu programa terminal ejecutas tu programa para imprimir hello world!
  2. El terminal ve que el programa ha escrito (a través de las rutinas de salida de C) hello world! a la consola
  3. El programa del terminal sube al administrador de ventanas del escritorio diciendo "Tengo hello world! escrito a mi, puedes ponerlo en posición x, y ¿Por favor?"
  4. El administrador de ventanas del escritorio sube al kernel con "uno de mis programas quiere que su dispositivo de gráficos ponga un poco de texto en esta posición;
  5. El núcleo pasa la solicitud al controlador del dispositivo gráfico, que lo formatea de manera que la tarjeta gráfica pueda entenderlo.
  6. Dependiendo de cómo se conecte la tarjeta gráfica, se debe llamar a otros controladores de dispositivos del kernel para expulsar los datos en buses de dispositivos físicos como PCIe, manejar cosas como asegurarse de que se seleccione el dispositivo correcto y de que los datos puedan pasar a través del puente relevante o convertidores
  7. El hardware muestra cosas.

Esta es una simplificación masiva solo para descripción. Aquí hay dragones.

Efectivamente, todo lo que hace que necesita acceso al hardware, ya sea pantalla, bloques de memoria, bits de archivos o algo por el estilo tiene pasar por algún controlador de dispositivo en el kernel para trabajar exactamente cómo para hablar con el dispositivo correspondiente. Ya sea un controlador de sistema de archivos en la parte superior de un controlador de controlador de disco duro SATA que se encuentra en la parte superior de un dispositivo puente PCIe.

El kernel sabe cómo unir todos estos dispositivos y presenta una interfaz relativamente simple para que los programas hagan cosas sin tener que saber cómo hacer todas estas cosas por sí mismos.

Los administradores de ventanas de escritorio proporcionan una capa que significa que los programas no tienen que saber cómo dibujar ventanas y jugar bien con otros programas que intentan mostrar cosas al mismo tiempo.

Finalmente, el programa de terminal significa que su programa no necesita saber cómo dibujar una ventana, ni cómo comunicarse con el controlador de la tarjeta gráfica del kernel, ni toda la complejidad que tiene que ver con el manejo de los búferes de pantalla y la sincronización de la pantalla y, de hecho, mover el teclado. Líneas de datos a la pantalla.

Todo es manejado por capas sobre capas de código.

Mokubai
fuente
No solo hardware acceso, mayor comunicación Entre Los programas también pasan por el núcleo; Lo que no suele implicar al menos el núcleo es configurar un canal más directo. Sin embargo, para los propósitos de la pregunta, también es posible y practicado en casos mucho más simples condensar todo el código en un solo programa.
Chris Stratton
De hecho, su programa de terminal ni siquiera tiene que estar ejecutándose en la misma máquina que el programa que está escribiendo cosas en él.
jamesqf
Dado que es posible que deba ser explícito en esta pregunta, tenga en cuenta que cuando hablamos de programas que "hablan" entre sí, es metafórico.
user20574
21

Depende del medio ambiente. En muchas computadoras antiguas (y más simples), como la IBM 1401, la respuesta sería "no". Su compilador y enlazador emitieron un "binario" independiente que se ejecutó sin ningún sistema operativo. Cuando su programa dejó de ejecutarse, cargó uno diferente, que también se ejecutó sin sistema operativo.

Se necesita un sistema operativo en entornos modernos porque no está ejecutando solo un programa a la vez. Compartir la (s) núcleo (s) de la CPU, la memoria RAM, el dispositivo de almacenamiento masivo, el teclado, el mouse y la pantalla, entre varios programas a la vez, requiere coordinación. El sistema operativo proporciona eso. Entonces, en un entorno moderno, su programa no puede simplemente leer y escribir el disco o SSD, tiene que pedirle al sistema operativo que lo haga en su nombre. El sistema operativo recibe dichas solicitudes de todos los programas que desean acceder al dispositivo de almacenamiento, implementa cosas como los controles de acceso (no puede permitir que los usuarios normales escriban en los archivos del sistema operativo), los pone en cola en el dispositivo y ordena la información devuelta a los programas (procesos) correctos.

Además, las computadoras modernas (a diferencia de, por ejemplo, la 1401) admiten la conexión de una gran variedad de dispositivos de E / S, no solo los que IBM le vendería en la antigüedad. Tu compilador y enlazador no pueden conocer todas las posibilidades. Por ejemplo, su teclado puede estar conectado a través de PS / 2 o USB. El sistema operativo le permite instalar "controladores de dispositivo" específicos del dispositivo que saben cómo hablar con esos dispositivos, pero presentan una interfaz común para la clase de dispositivo para el sistema operativo. Por lo tanto, su programa, e incluso el sistema operativo, no tienen que hacer nada diferente para obtener pulsaciones de teclas de un teclado USB / PS / 2, o para acceder, por ejemplo, a un disco SATA local frente a un dispositivo de almacenamiento USB vs un almacenamiento que está en algún lugar apagado en un NAS o SAN. Esos detalles son manejados por los controladores de dispositivos para los diferentes controladores de dispositivos.

Para los dispositivos de almacenamiento masivo, el sistema operativo proporciona un controlador de sistema de archivos que presenta la misma interfaz a todos los directorios y archivos, independientemente de dónde y cómo se implemente el almacenamiento. Y nuevamente, el sistema operativo se preocupa por los controles de acceso y la serialización. En general, por ejemplo, el mismo archivo no debe abrirse para que lo escriba más de un programa a la vez sin saltar por algunos aros (pero las lecturas simultáneas generalmente están bien).

Entonces, en un entorno moderno de propósito general, sí, realmente necesita un sistema operativo. Pero incluso hoy en día hay computadoras como los controladores en tiempo real que no son lo suficientemente complicados como para necesitar uno.

En el entorno de Arduino, por ejemplo, no hay realmente un sistema operativo. Claro, hay un montón de código de biblioteca que el entorno de compilación incorpora en cada "binario" que construye. Pero como no hay una persistencia de ese código de un programa a otro, no es un sistema operativo.

Jamie Hanrahan
fuente
10

Creo que muchas respuestas no entienden la pregunta, que se reduce a esto:

Un compilador genera código de máquina. ¿Es este código de máquina ejecutado directamente por una CPU, o es "interpretado" por el núcleo?

Básicamente, La CPU ejecuta directamente el código de máquina. . Sería significativamente más lento hacer que el núcleo ejecute todas las aplicaciones. Sin embargo, hay algunas advertencias.

  1. Cuando un sistema operativo está presente, los programas de aplicación normalmente tienen restricciones para ejecutar ciertas instrucciones o acceder a ciertos recursos. Por ejemplo, si una aplicación ejecuta una instrucción que modifica la tabla de interrupciones del sistema, la CPU saltará a un controlador de excepciones del sistema operativo para que la aplicación ofensiva finalice. Además, las aplicaciones generalmente no tienen permiso para leer / escribir en la memoria del dispositivo. (Es decir, "hablar con el hardware"). El acceso a estas regiones especiales de memoria es la forma en que el sistema operativo se comunica con dispositivos como la tarjeta gráfica, la interfaz de red, el reloj del sistema, etc.

  2. Las restricciones que un sistema operativo coloca en las aplicaciones se logran mediante características especiales de la CPU, como los modos de privilegio, la protección de la memoria y las interrupciones. Aunque cualquier CPU que encuentre en un teléfono inteligente o PC tiene estas características, ciertas CPU no las tienen. Estas CPU sí necesitan núcleos especiales que "interpretan" el código de la aplicación para lograr las funciones deseadas. Un ejemplo muy interesante es el Gigatron , que es una computadora de 8 instrucciones que puedes construir con chips que emula una computadora de 34 instrucciones.

  3. Algunos lenguajes como Java "compilan" a algo llamado Bytecode, que no es realmente un código de máquina. Aunque en el pasado fueron interpretados para ejecutar los programas, en estos días algo llamado Compilación justo a tiempo Normalmente se usa para que terminen ejecutándose directamente en la CPU como código de máquina.

  4. El software de ejecución en una máquina virtual solía requerir que su código de máquina fuera "interpretado" por un programa llamado Hipervisor . Debido a la enorme demanda de máquinas virtuales de la industria, los fabricantes de CPU han agregado funciones como VTx a sus CPU para permitir que la mayoría de las instrucciones de un sistema huésped sean ejecutadas directamente por la CPU. Sin embargo, cuando se ejecuta software diseñado para un incompatible CPU en una máquina virtual (por ejemplo, emulando una NES), el código de la máquina deberá ser interpretado.

Artelius
fuente
1
Aunque el código de bytes de Java normalmente no es el código de la máquina, todavía existen Procesadores Java .
Ruslan
Los hipervisores nunca han sido intérpretes. Por supuesto, la interpretación es necesaria si la máquina virtual es un conjunto de instrucciones que es incompatible con su host, pero para la ejecución de la misma arquitectura, incluso los primeros hipervisores ejecutan código directamente en la CPU (puede confundirse con la necesidad de núcleos paravirtualizados, para CPU sin el soporte necesario hipervisor).
Toby Speight
5

Cuando compila su código, crea el código denominado "objeto" que (en la mayoría de los casos) depende de las bibliotecas del sistema ( printf por ejemplo), entonces su código se envuelve con un enlazador que agregará el tipo de cargador de programas que su sistema operativo particular puede reconocer (por eso no puede ejecutar un programa compilado para Windows en Linux, por ejemplo) y sabe cómo desenvolver su código y ejecutar. Por lo tanto, su programa es como una carne dentro de un sándwich y se puede comer solo como un paquete completo.

Recientemente estuve leyendo sobre Kernels y descubrí que los programas no pueden acceder directamente al hardware, sino que tienen que pasar por el kernel.

Bueno, es a medias la verdad; Si su programa es un controlador en modo kernel, en realidad puede acceder directamente al hardware si sabe cómo "hablar" con el hardware, pero generalmente (especialmente para hardware no documentado o complicado) las personas usan controladores que son bibliotecas del kernel. De esta manera, puede encontrar funciones de la API que saben cómo hablar con el hardware de forma casi humana y sin la necesidad de conocer las direcciones, los registros, la sincronización y muchas otras cosas.

¿Cada instrucción en este código de máquina se ejecutará directamente desde la memoria (una vez que el sistema haya cargado el código en la memoria) o cada comando en el código de la máquina deberá pasar por el sistema operativo (kernel) para ejecutarse?

Bueno, el núcleo es como una camarera, cuya responsabilidad es acompañarte a una mesa y servirte. Lo único que no puede hacer es comer por ti, debes hacerlo tú mismo. Al igual que con su código, el núcleo desempaquetará su programa en una memoria e iniciará su código, que es un código de máquina ejecutado directamente por la CPU. Un kernel solo necesita supervisarlo, lo que se le permite y lo que no se le permite hacer.

no explica si el código de máquina que se genera después de la compilación es una instrucción para la CPU directamente o ¿tendrá que pasar nuevamente por el núcleo para crear la instrucción correcta para la CPU?

El código de máquina que se genera después de la compilación es una instrucción para la CPU directamente. No hay duda de eso. Lo único que debe tener en cuenta es que no todos los códigos en el archivo compilado son códigos reales de la máquina / CPU. Linker envolvió su programa con algunos metadatos que solo el kernel puede interpretar, como una pista, qué hacer con su programa.

¿Qué sucede después de que el código de la máquina se cargue en la memoria? ¿Pasará por el núcleo o hablará directamente con el procesador?

Si su código es simplemente opcodes como la adición de dos registros, entonces será ejecutado directamente por la CPU sin asistencia del núcleo, pero si su código utiliza funciones de las bibliotecas, dichas llamadas serán asistidas por el núcleo, como en el ejemplo con la camarera, si lo desea. para comer en un restaurante te darían una herramienta: tenedor, cuchara (y aún así sus activos), pero lo que harás con ella, - depende de tu "código".

Bueno, solo para evitar las llamas en los comentarios: es un modelo muy simplificado que espero ayude a OP a entender las cosas básicas, pero las buenas sugerencias para mejorar esta respuesta son bienvenidas.

Alex
fuente
3

Entonces, cuando compilamos un código fuente simple, digamos con solo una función printf (), y la compilación produce el código de máquina ejecutable, cada instrucción en este código de máquina se ejecutará directamente desde la memoria (una vez que el código se carga en la memoria). por SO) o ¿cada comando en el código de la máquina todavía tendrá que pasar por el SO (kernel) para ser ejecutado?

Esencialmente, solo las llamadas al sistema van al kernel. Cualquier cosa que tenga que ver con la E / S o la asignación / desasignación de la memoria generalmente da como resultado una llamada al sistema. Algunas instrucciones solo pueden ejecutarse en modo kernel y harán que la CPU active una excepción. Las excepciones provocan un cambio al modo kernel y un salto al código del kernel.

El kernel no procesa cada instrucción en un programa. Simplemente hace las llamadas al sistema y cambia entre programas en ejecución para compartir la CPU.

No es posible realizar la asignación de memoria en modo usuario (sin el núcleo), si accede a la memoria a la que no tiene permiso para acceder, la MMU, programada anteriormente por el núcleo, avisa y provoca una excepción de "falla de segmentación" a nivel de la CPU , que activa el kernel, y el kernel mata el programa.

Hacer E / S en modo usuario (sin el núcleo) no es posible, si accede a puertos de E / S o registros de dispositivos, o direcciones conectadas a dispositivos (uno o ambos necesarios para realizar cualquier E / S), estos activan una excepción de la misma manera.


¿Necesitaría un ejecutable un kernel de SO para ejecutarse?

Depende del tipo de ejecutable.

Los kernels, además de mediar el acceso compartido a la RAM y al hardware, también realizan una función de cargador.

Muchos "formatos ejecutables", como ELF o PE, tienen metadatos en el archivo ejecutable además del código, y el trabajo del cargador para procesarlo. Leer el detalles sangrientos sobre el formato PE de Microsoft para más información.

Estos ejecutables también hacen referencia a las bibliotecas (Windows .dll o objeto compartido de Linux .so archivos) - su código debe ser incluido.

Si su compilador produce un archivo que está destinado a ser procesado por un cargador del sistema operativo, y ese cargador no está allí, no funcionará.

  • ¿Puedes incluir el código que hace el trabajo del cargador?

Por supuesto. Debe convencer al sistema operativo para que de alguna manera ejecute su código en bruto sin procesar ningún metadato. Si su código llama a las API del kernel, aún no funcionará.

  • ¿Qué pasa si no se llama API del kernel?

Si carga este ejecutable de alguna manera desde un sistema operativo (es decir, si permite que se cargue y ejecute un código en bruto), aún estará en modo de usuario. Si su código accede a elementos que están prohibidos en el modo de usuario, a diferencia del modo de kernel, como la memoria no asignada o las direcciones / registros de dispositivos de E / S, se bloqueará con privilegios o violaciones de segmento (nuevamente, las excepciones van al modo de kernel y se manejan allí) y todavía no funcionará.

  • Que pasa si lo ejecutas desde el modo kernel.

Entonces funcionará.


LawrenceC
fuente
Esto no es del todo correcto. El requisito de que el acceso al hardware pase por el kernel, o que incluso ser Un kernel es una decisión de diseño que se toma de manera afirmativa en muchos sistemas hoy, pero también se toma en forma negativa (incluso hasta el día de hoy) en muchos sistemas simples
Chris Stratton
Estoy explicando cómo están las cosas si A) hay un kernel y B) si está ejecutando código en una CPU con modo de usuario / supervisor y una MMU para ayudar a hacer cumplir eso. Sí, hay CPU y microcontroladores sin MMU o modo de usuario / supervisor, y sí, algunos sistemas se ejecutan sin utilizar toda la infraestructura de usuario / supervisor. La primera Xbox de Microsoft fue así: aunque una CPU x86 estándar con modo de usuario / supervisor, por lo que entiendo, nunca dejó el modo de kernel, el juego cargado podía hacer lo que quisiera.
LawrenceC
1
El sistema Macintosh, antes de MacOS X, era un sistema operativo de una propósito general Computadora, que se ejecuta en una CPU de propósito general (familia 68000, PowerPC) con soporte para protección de memoria por décadas (excepto las primeras computadoras basadas en 68000, creo) que nunca usó protección de memoria: cualquier programa podría acceder a cualquier cosa en la memoria.
curiousguy
3

TL; DR No.

El desarrollo de Arduino viene a la mente como un entorno actual donde no hay SO. Confía en mí, en uno de estos bebes No tienes el espacio para un sistema operativo.

Del mismo modo, los juegos para Sega Genesis no tenían un sistema operativo provisto por Sega para llamar. Acaba de crear su juego en el ensamblador 68K, escribiendo directamente en el bare metal.

O donde me corté los dientes, haciendo un trabajo integrado en el Intel 8051. Una vez más, todo lo que tiene es un eprom 2716 con un tamaño de 2k * 8, no tiene espacio para un sistema operativo.

Por supuesto, esto supone un uso muy amplio de la aplicación word. Como pregunta retórica, vale la pena preguntarse si un boceto de Arduino en realidad es una aplicación.

dgnuff
fuente
3

Si bien no quiero dar a entender que las otras respuestas no son correctas por sí mismas, brindan demasiados detalles que, me temo, aún son muy oscuros para usted.

La respuesta básica es que el código se ejecutará directamente en el procesador. Y no, el código de la máquina no "hablará" con nadie, es al revés. El procesador es el componente activo y todo lo que hagas en tu computadora será realizado por ese procesador (estoy simplificando un poco las cosas aquí, pero eso está bien por ahora). El procesador leerá el código, lo ejecutará y escupirá los resultados, el código de la máquina es solo alimento para el procesador.

Su confusión se deriva del uso de la palabra hardware. Aunque la división no es tan clara como solía ser, es mejor si piensa en términos de periféricos en lugar de simplemente llamar hardware a todo. Entonces, si hay un sistema operativo o similar en su máquina, su programa tiene que usar sus servicios para acceder a los periféricos, pero el procesador en sí no es un periférico, es la unidad de procesamiento principal en la que se ejecuta su programa directamente.

Los kernels, sistemas operativos y capas intermedias similares se usan normalmente solo en sistemas más grandes donde existe la expectativa de que se ejecutarán varios programas y existe la necesidad de que el sistema administre la forma en que estos programas pueden usar los periféricos de la computadora (con bastante frecuencia en el sistema). Mismo tiempo). En estos casos, los programas en ejecución solo pueden acceder a estos periféricos utilizando el sistema que decidirá cómo compartirlos y se asegurará de que no haya conflictos. Los sistemas pequeños donde no hay necesidad de administración entre los programas competidores porque no hay ninguno, a menudo no tienen ningún sistema subyacente y el programa único que normalmente se ejecuta en estos sistemas es más o menos libre de hacer lo que quiera con los periféricos.

Gábor
fuente
2

El BIOS que se ejecuta en su computadora en el encendido es un código ejecutable almacenado en la ROM. Se compone de instrucciones de la máquina más datos. Hay un compilador (o ensamblador) que ensambla este BIOS a partir del código fuente. Este es un caso especial.

Otros casos especiales incluyen el programa bootstrap que carga el kernel y el kernel mismo. Estos casos especiales generalmente están codificados en un lenguaje distinto de C ++.

En el caso general, es mucho más práctico que el compilador produzca algunas instrucciones que invocan los servicios del sistema proporcionados por un núcleo o por las rutinas de la biblioteca. Hace que el compilador sea mucho más ligero. También hace que el código compilado sea más ligero.

En el otro extremo del espectro está Java. En Java, el compilador no traduce el código fuente en instrucciones de la máquina, como suele entenderse este término. En su lugar, el código fuente se traduce en "instrucciones de máquina" para una máquina imaginaria, llamada Máquina Virtual de Java. Antes de que un programa Java pueda ejecutarse, debe combinarse con el tiempo de ejecución de Java, que incluye un intérprete para la Máquina Virtual de Java.

Walter Mitty
fuente
2

En los viejos tiempos, su programa era responsable de hacer todo lo que debía hacerse durante la ejecución de su programa, ya sea que lo hiciera usted mismo o agregando un código de biblioteca que otros escribieron a su programa. Lo único que se ejecutaba junto a eso en la computadora era el código para leer en tu programa compilado, si tenías suerte. Algunas computadoras tenían que haber ingresado un código a través de los interruptores antes de poder hacer más (el proceso original de "arranque"), o incluso todo el programa ingresado de esta manera.

Rápidamente se encontró que era bueno tener un código ejecutable capaz de cargar y ejecutar programas. Más tarde, se descubrió que las computadoras eran lo suficientemente poderosas como para permitir la ejecución de varios programas al mismo tiempo al hacer que la CPU cambiara entre ellas, especialmente si el hardware podía ayudar, pero con la complejidad agregada de los programas, no con los pasos en cada uno de los otros dedos (por ejemplo, , ¿cómo manejar múltiples programas tratando de enviar datos a la impresora a la vez?).

Todo esto dio lugar a una gran cantidad de código de ayuda que se trasladó de los programas individuales al "sistema operativo", con una forma estandarizada de invocar el código de ayuda de los programas del usuario.

Y ahí es donde estamos hoy. Sus programas se ejecutan a toda velocidad, pero cada vez que necesitan algo administrado por el sistema operativo, se llaman rutinas de ayuda proporcionadas por el sistema operativo, y ese código no es necesario y no está presente en los programas del usuario. Esto incluía escribir en la pantalla, guardar archivos, acceder a la red, etc.

Se han escrito microkernels que proporcionan justo lo que se necesita para que un programa determinado se ejecute sin un sistema operativo completo. Esto tiene algunas ventajas para los usuarios experimentados al tiempo que regala la mayoría de los demás. Si lo desea, puede leer la página de Wikipedia al respecto - https://en.wikipedia.org/wiki/Microkernel - Si quieres saber más.

Experimenté con un Microkernel capaz de ejecutar una Máquina Virtual Java, pero luego descubrí que el punto óptimo para eso es Docker.

Thorbjørn Ravn Andersen
fuente
1

En los sistemas operativos de escritorio típicos, el kernel sí mismo Es un ejecutable. (Windows tiene ntoskrnl.exe; Linux tiene vmlinux, etc.) Si necesita un kernel para que se ejecute un ejecutable, entonces esos sistemas operativos no podrían existir.

Para lo que necesitas un kernel es para hacer las cosas que hace un kernel. Permita que se ejecuten varios ejecutables a la vez, arbitren entre ellos, abstraigan el hardware, etc. La mayoría de los programas no son capaces de hacer esas cosas de manera competente, y usted no querría que lo hicieran, incluso si pudieran. En la época de DOS, que apenas podía llamarse un sistema operativo en sí mismo, los juegos a menudo utilizaban el sistema operativo como poco más que un cargador, y accedían directamente al hardware de manera muy parecida a como lo haría un núcleo. Pero a menudo tenías que saber qué marcas y modelos de hardware había en tu máquina antes de comprar un juego. Muchos juegos solo admitían ciertas familias de tarjetas de video y de sonido, y funcionaban muy mal con las marcas de la competencia, si es que funcionaban. Ese es el tipo de cosa que se obtiene cuando el programa controla el hardware directamente en lugar de hacerlo a través de la abstracción que generalmente se proporciona a través del kernel.

cHao
fuente