El sistema operativo gestionado de código abierto C# ( Cosmos ) es un conjunto de herramientas para crear sistemas operativos con interfaz gráfica de usuario (GUI ) y de línea de comandos , escrito principalmente en el lenguaje de programación C# y con pequeñas cantidades de un lenguaje ensamblador de alto nivel llamado X#. Cosmos es un acrónimo inverso , [ 1 ] ya que el acrónimo se eligió antes que su significado. Es un software de código abierto publicado bajo una licencia BSD .
A partir de 2022Cosmos incluye un compilador de compilación anticipada (AOT) llamado IL2CPU para traducir el Lenguaje Intermedio Común (CIL) a instrucciones nativas. Cosmos compila programas creados por el usuario y bibliotecas asociadas usando IL2CPU para crear un ejecutable nativo de arranque que puede ejecutarse de forma independiente. El resultado puede arrancarse desde una unidad flash USB , CD-ROM , a través de una red mediante el 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 del Bus Serie Universal ( 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 usar muchos lenguajes CLI , siempre que se compilen a CIL puro sin el uso de Servicios de Invocación de Plataforma (P/Invokes). Cosmos está diseñado principalmente para usarse con .NET .
Cosmos no pretende ser un sistema operativo completo, sino un conjunto de herramientas que permita a otros desarrolladores crear sus propios sistemas operativos de forma sencilla utilizando .NET. Además, funciona como una capa de abstracción , ocultando gran parte del funcionamiento interno del hardware al desarrollador.
Las versiones anteriores de Cosmos se publicaban en hitos , siendo el último el hito 5 (publicado en agosto de 2010). Más recientemente, el proyecto optó por nombrar las nuevas versiones simplemente según el número de confirmación más reciente.
Las versiones de Cosmos se dividen en dos tipos: Userkit y Devkit . Userkit es una versión preempaquetada que se actualiza de forma irregular, a medida que se añaden nuevas y mejores características. Los Userkits se consideran generalmente estables, pero no incluyen los cambios recientes y pueden carecer de algunas características. Los Devkits, que hacen referencia al código fuente de Cosmos, suelen ser estables, pero pueden contener algunos errores. Se pueden obtener en GitHub y deben compilarse manualmente. [ 1 ] Git se utiliza para la gestión del control de versiones.
La mayor parte del trabajo en Cosmos actualmente se centra en mejorar la funcionalidad del depurador y la integración con Microsoft Visual Studio . El trabajo en el núcleo se enfoca en la implementación de sistemas de archivos , la administración de memoria y el desarrollo de una interfaz de red confiable. Limine funciona como el gestor de arranque del proyecto ; en versiones anteriores del kit de herramientas, se utilizaba GRUB . [ 2 ]
Origen
La idea de Cosmos fue creada por Chad Hower y, en un principio, Hower y Matthijs ter Woord la desarrollaron conjuntamente . Con el tiempo, Cosmos ha recibido mantenimiento y mejoras por parte de muchas otras personas.
Desarrollando con Cosmos
Cosmos cuenta con numerosas herramientas para mejorar la experiencia de desarrollo de sistemas operativos y está diseñado para que el proceso sea lo más rápido y sencillo posible. No se requieren conocimientos de lenguaje ensamblador para usar Cosmos.
Integración con Visual Studio
Una característica clave de Cosmos, que lo distingue de otros sistemas operativos similares, 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 tan solo unas pocas pulsaciones de teclas. Cosmos ya no es compatible con Visual Studio 2015 , Visual Studio 2017 ni Visual Studio 2019 , sino únicamente con Visual Studio 2022 .
Depuración
Cosmos se puede depurar fácilmente a través de Visual Studio al ejecutarse mediante PXE o en una máquina virtual . Dispone de numerosas 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. Al ejecutarse en VMWare , Cosmos admite la ejecución paso a paso y los puntos de interrupción, incluso con un sistema operativo en funcionamiento.
Correr
Cosmos utiliza la virtualización para acelerar el desarrollo, permitiendo a los desarrolladores probar sus sistemas operativos sin tener que reiniciar sus equipos con tanta frecuencia. Por defecto, se utiliza VMware Player debido a su facilidad de uso e integración con el proyecto. También se admiten otros entornos de virtualización, como Bochs e Hyper-V . Además, se puede generar una imagen de disco ISO que se puede grabar en una unidad flash USB , un CD-ROM o un soporte 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.
Soporte IDE
Cosmos no requiere estrictamente Visual Studio. Los proyectos se pueden crear ejecutando el siguiente comando, siempre que tenga instalada la plantilla:
dotnet new cosmosCSKernel -n MyCOSMOSProject El código se puede escribir en otros editores e IDE , como JetBrains Rider , Visual Studio Code , Neovim y GNU Nano . Una desventaja es que la depuración puede resultar difícil sin el depurador de Visual Studio. COSMOS tampoco iniciará automáticamente el software de virtualización durante la compilación. Si desea utilizar QEMU , por ejemplo, puede ejecutar este comando después de la compilación:
qemu-system-x86_64 -cdrom ./bin/Debug/net6.0/MyCOSMOSProject.iso Proceso de compilación
IL2CPU
Para compilar .NET CIL a lenguaje ensamblador, los desarrolladores de Cosmos crearon un compilador anticipado llamado IL2CPU, diseñado para analizar CIL y generar códigos de operación x86 . IL2CPU (IL To CPU) es un compilador AOT escrito en un lenguaje compatible con Common Intermediate Language ( C# ). Traduce Common Intermediate Language a código máquina .
INCÓGNITA#
X# es un lenguaje de programación de bajo nivel diseñado para la arquitectura de procesador x86 como parte del sistema operativo Cosmos. Su objetivo es simplificar el desarrollo de sistemas operativos mediante la incorporación de una sintaxis similar a la de C al lenguaje ensamblador . Inicialmente, X# se utilizaba para depurar servicios en Cosmos. El compilador de X# es un programa de interfaz de línea de comandos (consola) de código abierto que analiza las líneas de código en tokens, los compara con patrones y traduce los patrones coincidentes a la sintaxis de ensamblador x86 de Intel , generalmente para el ensamblador YASM. Las primeras versiones de X# funcionaban casi directamente con el código ensamblador, pero esto ya no es así.
Sintaxis
La sintaxis de X# es sencilla pero más estricta en comparación con C.
Comentarios
X# solo admite comentarios de una sola línea al estilo C++, comenzando con - //.
Constantes
X# permite la definición de constantes con nombre declaradas fuera de las funciones. Las constantes numéricas se definen de forma similar a C++ ; por ejemplo:
constante i = 0. Para hacer referencia a ellos en otros lugares se requiere un #antes del nombre; por ejemplo: - "#i".
- Las constantes de cadena usan comillas simples (
''). Para incluir una comilla simple en una constante de cadena, use una barra invertida (por ejemplo,'I\'m so happy'). Las cadenas X# terminan en nulo . - Las constantes hexadecimales se preceden con un signo de dólar (
$), seguido de la constante. ($B8000). - Las constantes decimales no llevan prefijo, pero no pueden empezar con
0. - Las constantes binarias y octales aún no son compatibles.
Etiquetas
Las etiquetas en X# funcionan de manera similar a las etiquetas en otros lenguajes ensamblador. gotoSe utiliza el mnemónico para saltar a una etiqueta en lugar del jumpmnemónico convencional jmp.
Etiqueta de código1 : ir a Etiqueta de código2 :Espacios de nombres
Los archivos de programa X# deben comenzar con una directiva de espacio de nombres. X# carece de una jerarquía de espacios de nombres, por lo que el espacio de nombres actual cambia con cada directiva hasta que finaliza el archivo. 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 operaciones de bajo nivel.
espacio de nombres FIRST // Todos los nombres de variables o constantes tendrán como prefijo FIRST y un guion bajo. Por lo tanto, el nombre completo real de la siguiente variable // es FIRST_aVar. var aVarespacio de nombres SEGUNDO // No hay problema en nombrar otra variable como aVar. Su nombre verdadero es SEGUNDO_aVar. var aVarespacio de nombres FIRST // Este código ahora vuelve al espacio de nombres FIRST hasta que finaliza el archivo.Funciones
Todo el código ejecutivo de X# debe ubicarse dentro de funciones definidas con la palabra clave 'function'. A diferencia de C, X# no admite la declaración formal de parámetros en el encabezado de las funciones, por lo que se omiten los paréntesis convencionales después del nombre de la función. Dado que los patrones fijos de línea se especifican en la sintaxis implementada en el analizador de código, la llave de apertura no puede colocarse en la siguiente línea, a diferencia de muchos otros lenguajes de estilo C.
función xSharpFunction { // código de la función }Dado que X# es un lenguaje de bajo nivel, no se insertan marcos de pila , por lo que, por defecto, la dirección EIP de retorno se encuentra en la parte superior de la pila. Las llamadas a funciones de 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. Cabe destacar que la pila en plataformas x86 no puede insertar ni extraer registros de un byte.
función xSharpFunction { EAX = $10 otraFunción ( EAX ); return }función otraFunción { //código de la función }La returnpalabra 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 para X#. Un registro se puede copiar a otro escribiendo DST = SRCen lugar de movinstrucciones de carga/almacenamiento. Los registros se pueden incrementar o decrementar con la misma facilidad. Las operaciones aritméticas (suma, resta, multiplicación, división) se escriben como dest op srcdonde srces una constante, variable o registro, y destes tanto un operando como la ubicación donde se almacena el resultado.
A continuación se muestran ejemplos de operaciones de asignación y aritméticas.
ESI = 12345 // asigna 12345 a ESI EDX = #constantForEDX // asigna #ConstantForEDX a EDX EAX = EBX // mueve EBX a EAX => mov eax, ebx EAX -- // decrementa EAX => dec eax EAX ++ // incrementa EAX => inc eax EAX + 2 // suma 2 a eax => add 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 // divide CX entre BX => div bx CX mod BX // resto de CX/BX a BX => div bxEl cambio y la rotación de registros son similares a los de C.
DX << 10 // desplazamiento a la izquierda 10 bits CX >> 8 // desplazamiento a la derecha 8 bits EAX <~ 6 // rotación a la izquierda 6 bits EAX ~> 4 // rotación a la derecha 4 bitsOtras operaciones bit a bit son similares a las operaciones aritméticas.
DL & $ 08 // Realiza una operación AND bit a bit en DL con 0x08 y almacena el resultado en DL. CX | 1 // Establece el bit menos significativo de CX a 1 (hazlo impar). EAX = ~ ECX // Realiza una operación NOT bit a bit en ECX y almacena el resultado en EAX. EAX ^ EAX // Borra EAX mediante una operación XOR consigo mismo.Pila
La manipulación de la pila en X# se realiza mediante los prefijos +y -, donde +inserta un registro, un valor, una constante o todos los registros en la pila y -extrae un valor de 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 // insertar esi - EDI // insertar en edi + All // guardar todos los registros => pushad - All // cargar todos los registros => popad + $ 1 badboo2 // insertar 0x1badboo2 en la pila + $ cafe como palabra // \/ + $ babe como palabra // insertar 0xcafebabe + # VideoMemory // insertar el valor de la constante VideoMemoryVariables
Las variables se definen dentro de los espacios de nombres usando la varpalabra clave. Los arreglos se definen especificando el tipo y el tamaño. Las variables y los arreglos se inicializan a cero por defecto. Para hacer referencia al valor de una variable, use un punto ('.'), y para hacer referencia a su dirección, use @.
espacio de nombres XSharpVariables var zeroVar // a la variable se le asignará cero var myVar1 = $ f000beef // a la variable se le asignará 0xf000beef var someString = ' Hello XSharp ! ' // a la variable se le asignará 'Hello XSharp!\0', var buffer byte [ 1024 ] // a la variable de tamaño 1024 bytes se le asignarán 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 EAXX# 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 en ESI CL = 'B' // establece CL en 'B' (reescribe 'H' al principio) CH = ESI [ 1 ] // mueve el segundo carácter ('E') de la cadena a CH ESI [ 4 ] = $ 00 // fin de la cadena // El valor de someString será 'Bell' (o 'Bell\0 XSharp!\0')Comparación
En X# existen dos formas de comparar valores: comparación pura y comparación condicional (if-comparing).
- La comparación pura deja el resultado en FLAGS, que se puede usar en el lenguaje ensamblador nativo o con la
ifpalabra clave sin especificar miembros de comparación. - Si la comparación compara directamente dos miembros después de una
ifpalabra clave.
Aquí hay dos maneras de escribir una strlenfunción (lenta) para medir la longitud de una cadena X#:
// Método 1: usando la función de comparación pura strlen { ESI = ESP [ 4 ] // obtener puntero a la cadena pasada como primer argumento ECX ^ ECX // borrar ECX Loop : AL = ESI [ ECX ] // obtener el siguiente carácter AL ?= 0 // ¿es 0? guardar en FLAGS if = return // si ZF está activado, devolver ECX ++ // de lo contrario incrementar ECX goto Loop // bucle...// Método 2: usando la función if strlen { ESI = ESP [ 4 ] // obtener puntero a la cadena pasada como primer argumento ECX ^ ECX // borrar ECX Loop : AL = ESI [ ECX ] if AL = 0 return // ¿AL = 0? return ECX ++ goto Loop // bucle.... }Hay seis operadores de comparación disponibles: . Estos operadores se pueden usar 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á establecido.Escribiendo código Cosmos
Un sistema operativo creado con Cosmos se desarrolla de forma similar a cualquier programa de consola .NET C# . Al inicio del programa se incluyen referencias adicionales que permiten acceder a las bibliotecas de Cosmos.
Kit de usuario y Visual Studio
El kit de usuario de Cosmos forma parte de Cosmos y está diseñado para facilitar su uso a los desarrolladores que utilizan Microsoft Visual Studio . Al instalarse, el kit de usuario añade un nuevo tipo de proyecto a Visual Studio , denominado Proyecto Cosmos. Se trata de una versión modificada de una aplicación de consola, con el compilador de Cosmos y el código de arranque ya integrados.
Compilación de un proyecto
Una vez que el código esté completo, se puede compilar utilizando Roslyn, el compilador de .NET , ya sea a través de Microsoft Visual Studio o de las herramientas de línea de comandos de .NET (dotnet).
Esto convierte la aplicación desde el código fuente original ( C# o cualquier otro) al Lenguaje Intermedio Común (CIL), el lenguaje intermedio nativo de .NET.
El proceso de compilación invoca entonces al compilador IL2CPU , que analiza sistemáticamente todo el código CIL de la aplicación (excluyendo el código del compilador Cosmos) y lo convierte a lenguaje ensamblador para la arquitectura de procesador seleccionada. A partir de 2022Solo se admite la arquitectura x86 . A continuación, Cosmos invoca al ensamblador seleccionado para convertir este código en lenguaje ensamblador en código de operación nativo de la unidad central de procesamiento (CPU) . Finalmente, se activa la opción de salida deseada, ya sea iniciar una máquina virtual, iniciar un motor PXE o generar un archivo de imagen de disco ISO .
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 arrancar el sistema operativo en un entorno emulado mediante una máquina virtual . Esto permite a los desarrolladores probar el sistema en su propio ordenador sin necesidad de reiniciarlo, lo que ofrece la ventaja de no requerir hardware adicional ni salir de su entorno de desarrollo integrado (IDE). VMware es el método de virtualización principal, aunque también admite otros como QEMU e Hyper-V.
imágenes de disco
Esta opción graba el sistema operativo en un archivo de imagen de disco ( imagen ISO ), que se puede cargar en algunos emuladores (como Bochs , QEMU o, más comúnmente, VMware ) o grabar en una unidad flash USB e iniciar en hardware físico.
Arranque de red PXE
Esta opción permite que el sistema operativo arranque en hardware físico. Los datos se envían a través de una red de área local (LAN) a la máquina cliente . Esto requiere dos ordenadores: uno como máquina cliente (en el que se inicia el sistema operativo) y otro como servidor (normalmente la máquina de desarrollo). También requiere una red que conecte ambos ordenadores, una máquina cliente con tarjeta de red y un sistema básico de entrada/salida ( BIOS ) compatible con el arranque PXE. (Datos de 2022)La depuración a través de la red ya no es compatible.
Véase también
Referencias
Enlaces externos
- Sitio web oficial
- CosmosOS en GitHub
- Artículo de introducción a Cosmos en CodeProject.
- Grupo de Yahoo Cosmos Dev archivado el 8 de enero de 2011 en Wayback Machine.
- Página de fans de Cosmos en Facebook
Cobertura informativa
- Mary Jo Foley en ZDNet - Cosmos: Nace un sistema operativo de microkernel de código abierto basado en .Net
- Scott Hanselman: Edición de sistema operativo gestionado en miniatura
- Sistemas operativos integrados
- núcleos de sistemas operativos
- Sistemas operativos de software libre
- Software beta
- Sistemas operativos X86
- .NETO
- Software que utiliza la licencia BSD.