C # Open Source Managed Operating System ( Cosmos ) es un conjunto de herramientas para construir sistemas operativos , escrito principalmente en el lenguaje de programación C # y pequeñas cantidades de un lenguaje ensamblador de alto nivel llamado X #. Cosmos es un backronym , [1] en el sentido de que se eligió el acrónimo antes del significado. Es un software de código abierto publicado bajo una licencia BSD .
Desarrollador | Proyecto Cosmos |
---|---|
Escrito en | C # , X # |
Estado de trabajo | Activo |
Modelo fuente | Fuente abierta |
Último lanzamiento | Versión 20200708/8 de julio de 2020 |
Repositorio | github |
Disponible en | inglés |
Plataformas | x86 |
Tipo de grano | Monolítico |
Licencia | BSD |
Página web oficial | www |
Cosmos incluye un compilador AOT llamado IL2CPU para traducir Common Intermediate Language (CIL) en instrucciones nativas. Cosmos compila programas creados por el usuario y bibliotecas asociadas utilizando IL2CPU para crear un ejecutable nativo de arranque que se puede ejecutar sin soporte. La salida resultante se puede iniciar desde una unidad flash USB , CD-ROM , a través de una red a través del entorno de ejecución de prearranque (PXE) o dentro de una máquina virtual . Las versiones recientes también permiten la implementación en ciertos dispositivos integrados x86 a través de Universal Serial Bus ( USB ). Si bien C # es el lenguaje principal utilizado por los desarrolladores (tanto en el backend como por los usuarios finales de Cosmos), se pueden utilizar muchos lenguajes CLI , siempre que se compilen en CIL puro sin el uso de Platform Invocation Services (P / Invokes). Cosmos está diseñado principalmente para su uso con .NET Core .
A partir de 2021 [actualizar], Cosmos no pretende convertirse en un sistema operativo completo, sino más bien en un conjunto de herramientas que permita a otros desarrolladores construir de manera simple y sencilla sus propios sistemas operativos utilizando .NET Core. También funciona como una capa de abstracción, ocultando gran parte del funcionamiento interno del hardware al eventual desarrollador.
Las versiones anteriores de Cosmos se lanzaron en Milestones , siendo la última Milestone 5 (publicada en agosto de 2010). Más recientemente, el proyecto cambió a simplemente nombrar las nuevas versiones después del último número de confirmación. Las versiones de Cosmos se dividen en dos tipos: Userkit y Devkit . El Userkit es una versión preempaquetada que se actualiza de forma irregular a medida que se agregan funciones nuevas y mejoradas. Los Userkits generalmente se consideran estables, pero no incluyen cambios recientes y pueden carecer de funciones. El Devkit se refiere al código fuente de Cosmos y debe construirse manualmente. Los Devkits suelen ser algo estables, pero pueden tener algunos errores. El Devkit se puede adquirir en GitHub [1] y usa Git como la gestión de control de código fuente. La mayor parte del trabajo en Cosmos está dirigido actualmente a mejorar la funcionalidad del depurador y la integración de Visual Studio . El trabajo del kernel se centra en implementar sistemas de archivos , administración de memoria y desarrollar una interfaz de red confiable. Syslinux sirve como gestor de arranque del proyecto .
Desarrollando con Cosmos
Cosmos tiene muchas facilidades para mejorar la experiencia de desarrollar sistemas operativos con él, diseñadas para hacer el proceso lo más rápido y sencillo posible, no se requiere conocimiento del lenguaje ensamblador para usar Cosmos.
Integración de Visual Studio
Una característica clave de Cosmos, que lo distingue de otros sistemas operativos de su tipo, es su estrecha integración con Microsoft Visual Studio . El código se puede escribir, compilar , depurar y ejecutar completamente a través de Visual Studio , con solo presionar algunas teclas. Cosmos ya no es compatible con Visual Studio 2015 o Visual Studio 2017 , ahora solo es compatible con Visual Studio 2019 .
Depuración
Cosmos se puede depurar sin problemas a través de Visual Studio cuando se ejecuta sobre PXE o en una máquina virtual. Están presentes muchas funciones de depuración estándar, como puntos de interrupción, seguimiento y registro. Además, la depuración se puede realizar mediante cables serie, si se ejecuta en hardware físico. Cuando se ejecuta en VMWare, Cosmos admite pasos y puntos de interrupción, incluso mientras se está ejecutando un sistema operativo.
Corriendo
Cosmos utiliza la virtualización para ayudar a acelerar el desarrollo al permitir que los desarrolladores prueben sus sistemas operativos sin tener que reiniciar sus computadoras con tanta frecuencia. Por defecto, se utiliza VMWare Player, debido a su facilidad de uso en cuanto a integración con el proyecto. También se admiten otros entornos de virtualización, como Bochs y VirtualPC. También se puede generar una imagen de disco ISO que se puede grabar en una unidad flash USB, CD-ROM o un medio similar.
También se admite el arranque PXE, lo que permite que las máquinas remotas ejecuten Cosmos a través de una conexión de red.
Proceso de compilación
IL2CPU
Para compilar .NET CIL en lenguaje ensamblador, los desarrolladores crearon un Cosmos por delante de los tiempos compilador llamado IL2CPU, diseñado para CIL y la salida de análisis sintáctico x 86 códigos de operación . (IL To CPU) es un compilador AOT que se escribe utilizando un lenguaje compatible con Common Intermediate Language ( C # ). Traduce el lenguaje intermedio común al código de máquina .
X#
X # es un lenguaje de programación de bajo nivel desarrollado para la arquitectura del procesador x86 como parte del sistema operativo Cosmos para facilitar el desarrollo del sistema operativo. X # ha sido diseñado para traer un poco de C-como el lenguaje de sintaxis de lenguaje ensamblador . Al principio, X # fue una ayuda para depurar los servicios de Cosmos. El compilador X # es un programa de interfaz de consola de código abierto con una arquitectura atípica. Analiza líneas de código en tokens y las compara con patrones. Finalmente, los patrones de código X # coincidentes se traducen al ensamblaje x86 de sintaxis Intel , generalmente para el compilador NASM . En las primeras versiones, la operación X # era principalmente 1: 1 con código ensamblador, pero no ha sido la razón por la que se escribió el compilador X #.
Sintaxis
La sintaxis de X # es simple. A pesar de ser similar a C , la sintaxis de X # difiere y es más estricta.
Comentarios
X # admite solo un tipo de comentario, el comentario de una sola línea de estilo C ++, que comienza con una barra inclinada doble //
.
Constantes
X # admite la definición de constantes con nombre que se declaran fuera de funciones. Definir una constante numérica es similar a C ++ , por ejemplo,
constante i = 0
. Hacer referencia a la constante en otro lugar requiere un #
antes del nombre "#i"
, por ejemplo.
- Para definir una constante de cadena ,
''
se utilizan comillas simples ( ). Para usar una comilla simple en una constante de cadena, debe escaparse colocando una barra invertida antes, como'I\'m so happy'
. Las cadenas X # tienen terminación nula . - Las constantes hexadecimales tienen como prefijo un signo de dólar (
$
), seguido de la constante. ($B8000
). - Las constantes decimales no están decoradas pero no pueden comenzar con
0
. - Aún no se admiten las constantes binarias y octales.
Etiquetas
Las etiquetas en X # son en su mayoría equivalentes a las etiquetas en otros lenguajes ensambladores. La instrucción para saltar a una etiqueta usa el goto
mnemónico, en contraposición al convencional jump
o jmp
mnemónico.
CodeLabel1 : ir a CodeLabel2 :
Espacios de nombres
Los archivos de programa X # deben comenzar con una directiva de espacio de nombres. X # carece de una jerarquía de espacio de nombres, por lo que cualquier directiva cambiará el espacio de nombres actual hasta que se vuelva a cambiar o el archivo finalice. Las variables o constantes en diferentes espacios de nombres pueden tener el mismo nombre ya que el espacio de nombres se antepone al nombre del miembro en la salida del ensamblado. Los espacios de nombres no pueden hacer referencia entre sí excepto mediante "trampas" que utilizan operaciones de nivel de ensamblado nativo.
namespace FIRST // Todo el nombre de la variable o constante tendrá el prefijo FIRST y un guión bajo. Por lo tanto, el verdadero nombre completo de la siguiente variable // es FIRST_aVar. var aVarespacio de nombres SEGUNDO // No es un problema nombrar otra variable aVar. Su verdadero nombre es SECOND_aVar. var aVarnamespace FIRST // Este código vuelve ahora al FIRST espacio de nombres hasta que finaliza el archivo.
Funciones
Todo el código ejecutivo de X # debe colocarse en funciones definidas por la palabra clave 'función'. A diferencia de C, X # no admite ninguna declaración de parámetro formal en el encabezado de las funciones, por lo que se omiten los paréntesis convencionales después del nombre de la función. Debido a que los patrones de línea fija se especifican en la sintaxis implementada en el analizador de código, el corchete de apertura no se puede colocar en la siguiente línea, a diferencia de muchos otros lenguajes de estilo C.
function xSharpFunction { // código de función }
Debido a que X # es un lenguaje de bajo nivel, no se insertan marcos de pila, por lo que, de forma predeterminada, debería haber la dirección EIP de retorno en la parte superior de la pila. Las llamadas a funciones X # contienen argumentos entre paréntesis, a diferencia de los encabezados de función. Los argumentos que se pasan a las funciones pueden ser registros, direcciones o constantes. Estos argumentos se insertan en la pila en orden inverso. Tenga en cuenta que la pila en plataformas x86 no puede empujar ni abrir registros de un byte.
función xSharpFunction { EAX = $ 10 otra función ( EAX ); volver }function anotherFunction { // código de función }
La return
palabra clave devuelve la ejecución a la dirección EIP de retorno guardada en la pila.
Operaciones aritméticas y bit a bit
X # puede trabajar con tres estructuras de datos de bajo nivel: los registros , la pila y la memoria , en diferentes puertos. Los registros son la base de todas las operaciones normales de X #. Un registro se puede copiar a otro escribiendo DST = SRC
en lugar de mov
cargar / almacenar instrucciones. Los registros se pueden incrementar o disminuir con la misma facilidad. Las operaciones aritméticas (sumar, restar, multiplicar, dividir) se escriben como dest op src
donde src
es una constante, variable o registro, y dest
es tanto un operando como la ubicación donde se almacena el resultado.
A continuación se muestran ejemplos de operaciones aritméticas y de asignación.
ESI = 12345 // asignar 12345 a ESI EDX = # constantForEDX // asignar #ConstantForEDX a EDX EAX = EBX // mover EBX a EAX => mov eax, ebx EAX - // disminuir EAX => dec eax EAX ++ / / incremento EAX => inc eax EAX + 2 // suma 2 a eax => suma eax, 2 EAX - $ 80 // resta 0x80 de eax => sub eax, 0x80 BX * CX // multiplica BX por CX => mul cx - la división, la multiplicación y el módulo deben conservar los registros CX / BX // dividir CX por BX => div bx CX mod BX // resto de CX / BX a BX => div bx
El cambio y el balanceo de registros es similar a C.
DX << 10 // desplazar 10 bits a la izquierda CX >> 8 // desplazar 8 bits a la derecha EAX <~ 6 // girar 6 bits a la izquierda EAX ~> 4 // girar 4 bits a la derecha
Otras operaciones bit a bit son similares a las operaciones aritméticas.
DL & $ 08 // realiza AND bit a bit en DL con 0x08 y almacena el resultado en DL CX | 1 // establece el bit más bajo de CX en 1 ( hazlo extraño) EAX = ~ ECX // realiza bit a bit NOT en ECX y almacena el resultado en EAX EAX ^ EAX // borra EAX haciendo XORing consigo mismo
Apilar
La manipulación de la pila en X # se realiza usando +
y -
prefijos, donde +
empuja un registro, valor, constante o todos los registros a la pila y -
coloca un valor en algún registro. Todas las constantes se insertan en la pila como palabras dobles, a menos que se indique lo contrario (no se admite la inserción de bytes individuales).
+ ESI // empujar esi - EDI // entrar en edi + All // guardar todos los registros => pushad - All // cargar todos los registros => popad + $ 1 badboo2 // empujar 0x1badboo2 en la pila + $ cafe como palabra / / \ / + $ babe as word // push 0xcafebabe + # VideoMemory // valor de push de VideoMemory constante
Variables
Las variables se definen dentro de los espacios de nombres (ya que no hay marcos de pila, las variables locales no son compatibles) usando la var
palabra clave. Las matrices se pueden definir agregando el tipo y tamaño de la matriz al final de la declaración. Las variables y matrices se ponen a cero de forma predeterminada. Para hacer referencia al valor de una variable, debe ir precedida de un punto. Anteponer eso con un @
hará referencia a la dirección de la variable.
namespace XSharpVariables var zeroVar // se asignará la variable zero var myVar1 = $ f000beef // se asignará la variable 0xf000beef var someString = ' ¡Hola XSharp ! ' // Se asignará la variable' Hola XSharp! \ 0 ', var buffer byte [ 1024 ] // A la variable de tamaño 1024 bytes se le asignará 1024 bytes cero ... EAX = . myVar1 // mueve el valor de myVar1 (0xf000beef) a EAX ESI = @ . someString // mueve la dirección de someString a ESI CL = . someString // mueve el primer carácter de someString ('H') a CL . zeroVar = EAX // asigna zeroVar al valor de EAX
X # puede acceder a una dirección con un desplazamiento especificado usando corchetes:
var someString = ' ¡Hola XSharp ! ' // La variable se asignará a' Hello XSharp! \ 0 ' ... ESI = @ . someString // carga la dirección de someString a ESI CL = 'B' // establece CL en 'B' (reescribe 'H' al inicio) CH = ESI [ 1 ] // mueve el segundo carácter ('E') de la cadena a CH ESI [ 4 ] = $ 00 // cadena final // El valor de someString será 'Bell' (o 'Bell \ 0 XSharp! \ 0')
Comparación
Hay dos formas de comparar valores: comparación pura y comparación si.
- La comparación pura deja el resultado en BANDERAS para que pueda usarse en ensamblado nativo o usando la
if
palabra clave sin especificar miembros de comparación. - Si la comparación compara dos miembros directamente después de una
if
palabra clave.
Aquí hay dos formas de escribir una función (lenta) X # string length ( strlen
):
// Método 1: usar la función de comparación pura strlen { ESI = ESP [ 4 ] // obtener el puntero a la cadena pasada como primer argumento ECX ^ ECX // borrar el bucle ECX : AL = ESI [ ECX ] // obtener el siguiente carácter AL ? = 0 // ¿es 0? guardar en FLAGS if = return // si se establece ZF, return ECX ++ // si no, incrementa ECX goto Loop // loop ...// Modo 2: usar la función if strlen { ESI = ESP [ 4 ] // obtener el puntero a la cadena pasada como primer argumento ECX ^ ECX // borrar el bucle ECX : AL = ESI [ ECX ] if AL = 0 return // AL = 0? return ECX ++ goto Loop // loop .... }
Hay seis operadores de comparación disponibles: < > = <= >= !=
. Estos operadores se pueden utilizar tanto en comparaciones como en bucles. Tenga en cuenta que también hay un operador AND bit a bit que prueba bits:
AL ? & $ 80 // prueba AL MSB if = return // si ZF es 0, la instrucción de prueba resultó en 0 y MSB no está configurado.
Escribir código Cosmos
Un sistema operativo creado con Cosmos se desarrolla de manera similar a cualquier programa de consola .NET C #. Se hacen referencias adicionales al inicio del programa que dan acceso a las bibliotecas de Cosmos. Estas bibliotecas anulan las bibliotecas del sistema que se utilizan normalmente en los programas de consola de C #, ya que el binario resultante no se ejecutará en una instalación de Microsoft Windows .
Kit de usuario y Visual Studio
El kit de usuario de Cosmos es una parte de Cosmos diseñado para hacer que Cosmos sea más fácil de usar para los desarrolladores que usan Microsoft Visual Studio . Cuando se instala, el kit de usuario agrega un nuevo tipo de proyecto a Visual Studio, llamado Proyecto Cosmos. Esta es una versión modificada de una aplicación de consola, con el compilador Cosmos y el código auxiliar de arranque ya agregado.
Compilar un proyecto
Una vez que el código está completo, se puede compilar utilizando el compilador .NET. Esto convierte la aplicación del código fuente original ( C # o de otro modo) en Common Intermediate Language (CIL), el idioma nativo de .NET Framework. A continuación, se ejecuta la aplicación, que muestra la ventana Cosmos Builder, que presenta al desarrollador opciones que determinan exactamente cómo se compila el proyecto. Estas opciones incluyen cómo iniciar el proyecto, a través de emuladores como Quick Emulator ( QEMU ), Virtual PC y VMWare , escribiendo en un archivo de imagen de disco (ISO) que luego se puede escribir en un CD-ROM o mediante el entorno de ejecución de prearranque. (PXE), así como opciones de depuración mediante el depurador integrado de Cosmos y otras opciones.
Cuando el usuario ha elegido las opciones deseadas, presiona el botón Construir. Esto invoca el compilador IL2CPU que escanea sistemáticamente el código CIL de todas las aplicaciones (excluyendo el código del compilador Cosmos), convirtiéndolo en lenguaje ensamblador para la arquitectura de procesador seleccionada. A partir de 2016[actualizar], solo se admite x86 . A continuación, Cosmos invoca al ensamblador seleccionado para convertir este código en lenguaje ensamblador en código de operación de la unidad central de procesamiento (CPU) nativo . Finalmente, se activa la opción de salida deseada, ya sea iniciando un emulador, iniciando un motor PXE o produciendo un archivo de imagen de disco ISO a partir del código de operación de código binario .
Opciones de depuración
Cosmos ofrece varias opciones sobre cómo implementar el sistema operativo resultante y cómo depurar la salida.
Virtualización
Cosmos permite a los usuarios iniciar el sistema operativo en un entorno emulado utilizando una máquina virtual . Esto permite a los desarrolladores probar el sistema en su propia computadora sin tener que reiniciar, lo que brinda la ventaja de no requerir hardware adicional o que los desarrolladores salgan de su entorno de desarrollo . Actualmente, solo se admite VMWare. El apoyo de Bochs está en marcha. QEMU y VirtualBox no son compatibles oficialmente.
Imágenes de disco
Esta opción escribe el sistema operativo en un archivo de imagen de disco ( ISO ), que se puede cargar en algunos emuladores (como Bochs , QEMU o más comúnmente VMware ) o escribir en un CD-ROM y arrancar en hardware real. Esta opción también permite la implementación en un dispositivo de almacenamiento masivo USB, como una unidad flash USB , para iniciar en dispositivos que pueden no tener una unidad de disco óptico. Debido a que la red aún no está en su lugar, la depuración no es compatible con esta opción de implementación.
Arranque de red PXE
Esta opción permite que el sistema operativo se inicie en hardware real. Los datos se envían a través de una red de área local (LAN) a la máquina cliente . Esto requiere dos computadoras: una como máquina cliente (en la que se inicia el sistema operativo) y otra como servidor (generalmente la máquina de desarrollo). También requiere una red que conecte las dos computadoras, una máquina cliente con una tarjeta de red y un sistema básico de entrada / salida ( BIOS ) que pueda arrancar con PXE. A partir de 2016[actualizar], la depuración a través de una red no es compatible.
Ensamblador cosmos
El equipo del Proyecto Cosmos también ha creado un ensamblador que está diseñado para convertirse eventualmente en el ensamblador principal del sistema Cosmos. Sin embargo, el ensamblador sigue siendo ineficaz y lento, por lo que se utiliza Netwide Assembler (NASM) en su lugar.
Ver también
- IL2CPU
- .NET Framework
- Mono (software)
- SharpOS
- Singularidad
- Sistema operativo fantasma
Referencias
- ^ a b Sitio web de Cosmos: repositorio del proyecto en GitHub
enlaces externos
- Página web oficial
- Repositorio de proyectos en GitHub
- Artículo de descripción general de Cosmos en CodeProject
- Cosmos Dev Yahoo Group
- Página de fans de Cosmos en Facebook
Cobertura de noticias
- Mary Jo Foley en ZDNet - Cosmos: nace un sistema operativo de microkernel basado en .Net de código abierto
- Scott Hanselman - Tiny Managed Operating System Edition