2 puntos por GN⁺ 2024-12-06 | 1 comentarios | Compartir por WhatsApp
  • Banan-OS es un sistema operativo de hobby escrito en C++ y actualmente soporta las arquitecturas x86_64 e i686
  • Su alcance funcional incluye espacio de usuario Ring3, SMP, stack de red, carga de ELF y enlace dinámico, memoria copy-on-write y un entorno gráfico básico
  • En cuanto a drivers y funciones del sistema, soporta discos NVMe y ATA, NIC E1000/E1000E y de la familia RTL, entrada PS2 y USB, sistemas de archivos Ext2 y FAT, GRUB y su propio bootloader BIOS
  • TCP está marcado como implementado parcialmente y con bugs, mientras que SSL, dispositivos virtio, algunos controladores USB, los sistemas de archivos Sys y 9P, y su propio bootloader UEFI aún no están implementados
  • La compilación se centra en el script ./bos; después de generar el toolchain, permite ejecutar QEMU y Bochs, compilar el kernel y la imagen, y elegir opciones de arquitectura, bootloader, UEFI e initrd

Descripción general de Banan-OS

  • Banan-OS es un sistema operativo de hobby escrito en C++
  • Las arquitecturas soportadas actualmente son x86_64 e i686
  • Hay una demo en vivo disponible en bananymous.com/banan-os
  • Para ejecutar DOOM, hay que entrar al entorno GUI con el comando start-gui y luego ejecutar doom desde la terminal GUI

Funciones principales implementadas

  • Funciones generales
    • Espacio de usuario Ring3

      • SMP, es decir, multiprocesamiento
      • Framebuffer lineal basado en VESA y GOP
      • Stack de red
      • Carga de ejecutables ELF
      • Intérprete AML parcial
      • Entorno gráfico básico
      • Emulador de terminal
      • Barra de estado
      • Lanzador de programas
      • “Apps decentes” aún no implementadas
      • Enlace dinámico de ELF
      • Memoria copy-on-write
      • El mapeo de archivos está implementado
      • El mapeo anónimo no está implementado

Soporte de drivers, red y sistemas de archivos

  • Drivers
    • Soporta discos NVMe y discos ATA IDE/SATA
    • Soporta NIC E1000, E1000E y RTL8111/8168/8211/8411
    • El teclado PS2 soporta todos los conjuntos de scancodes, y también se soporta mouse PS2
    • USB soporta xHCI, teclado, mouse, almacenamiento masivo y hubs
    • EHCI, OHCI, UHCI y dispositivos virtio de red y almacenamiento no están implementados
  • Red
    • Soporta ARP, ICMP, IPv4 y UDP
    • TCP está implementado parcialmente y tiene bugs

      • Soporta Unix domain sockets
      • SSL no está implementado
      • Sistemas de archivos
      • Soporta sistema de archivos virtual, Ext2, FAT12/16/32, Dev, Ram y Proc
      • Sys y 9P no están implementados
      • Bootloader
      • Soporta GRUB y su propio bootloader BIOS
      • Su propio bootloader UEFI aún no está implementado

Estructura del código

  • Cada componente y biblioteca principal tiene un subdirectorio separado, como kernel, userspace o libc
  • Cada directorio tiene un directorio include que contiene todos los archivos de encabezado del componente
  • Todos los encabezados se incluyen mediante rutas absolutas

Compilación y ejecución

  • En Ubuntu 22.04, se requieren los paquetes apt build-essential, git, ninja-build, texinfo, bison, flex, libgmp-dev, libmpfr-dev, libmpc-dev, parted, qemu-system-x86 y cpu-checker
  • En un entorno pacman, se requieren base-devel, git, wget, cmake, ninja, parted y qemu-system-x86
  • El toolchain para el sistema operativo se compila una sola vez con ./bos toolchain
    • Puede tardar bastante porque compila binutils y gcc
  • La compilación y ejecución del propio OS se realizan con el comando ./bos
    • ./bos qemu
    • ./bos qemu-nographic
    • ./bos qemu-debug
    • ./bos bochs
  • También se puede compilar solo el kernel o la imagen de disco
    • ./bos kernel
    • ./bos image
  • Se necesitan privilegios root para crear o modificar la imagen de disco

Opciones de compilación y gestión de imágenes

  • Para compilar para otra arquitectura, se configura la variable de entorno BANAN_ARCH
    • Ejemplo: BANAN_ARCH=i686
  • Para cambiar el bootloader, se configura la variable de entorno BANAN_BOOTLOADER
    • Los valores soportados son BANAN y GRUB
  • Para ejecutar con UEFI, hay que configurar BANAN_UEFI_BOOT=1
    • También hay que configurar OVMF_PATH con la ruta correcta de OVMF; el valor predeterminado es /usr/share/ovmf/x64/OVMF.fd
  • Para crear una imagen initrd sin un sistema de archivos root físico, se configura BANAN_INITRD=1
    • Puede usarse al probar en hardware con controladores USB no soportados
  • Si la imagen de disco está dañada o se quiere crear una nueva, hay que borrar build/banan-os.img o ejecutar ./bos image-full
  • También se ofrece un script de shell completion para zsh
    • Copia el archivo _script/shell-completion/zsh/_bos a /usr/share/zsh/site-functions/, o agrega _script/shell-completion/zsh al fpath de .zshrc

Cómo contribuir

  • El upstream no está alojado en GitHub, sino en https://git.bananymous.com/Bananymous/banan-os
  • También se pueden enviar PRs en GitHub, pero el maintainer tendrá que descargar el diff y aplicarlo manualmente
  • También se puede obtener una cuenta en el servidor git separado; en ese caso hay que contactarlo por email o Discord
  • Para agregar nuevas funciones, se prefiere contactar primero al maintainer
    • Como es un proyecto con fines de aprendizaje, si se envía sin consulta previa un PR con una función que el maintainer planeaba implementar por su cuenta, puede ser cerrado
    • Las correcciones de bugs siempre son bienvenidas
  • La primera línea de los mensajes de commit debe escribirse en el formato Subject: Description
    • Subject indica el área modificada, como Kernel, Shell o BuildSystem
    • La primera línea debe tener 72 caracteres o menos
    • El cuerpo debe explicar con más detalle qué cambió y por qué
  • Todos los commits deben pasar los hooks de pre-commit definidos en .pre-commit-config.yaml

1 comentarios

 
GN⁺ 2024-12-06
Comentarios de Hacker News
  • Está realmente genial y me encanta el nombre. Me da curiosidad saber cuál fue la parte más difícil de implementar hasta ahora y si hubo algún obstáculo serio en el camino

    • No hubo ninguna parte excesivamente difícil, pero si tuviera que elegir, diría que el intérprete de AML o el stack de USB
      El intérprete de AML fue difícil porque la especificación de ACPI está muy mal escrita, y USB fue pesado porque la especificación es extensa y tiene muchísimas referencias cruzadas
      No hubo grandes obstáculos, pero sí hubo funciones que dejé de lado y retomé uno o dos meses después
    • Al principio lo leía como “banyan tree”, y solo al ver el arte ASCII me di cuenta de que era una referencia a banana
  • Está buenísimo. Sobre todo impresiona que hayas implementado el driver de USB desde cero. Como referencia, probé romperlo con cat doom1.wad

    • Gracias. Casi no hay serialización en los datos que se escriben al TTY, así que si le metes datos binarios arbitrarios, puede romperse :D
  • Hay una frase que tradicionalmente debería aparecer en todo anuncio de un nuevo kernel de sistema operativo, y en este anuncio falta

    • Seguro te refieres a la frase “esto es un proyecto hobby y no va a ser grande ni profesional como GNU”, ¿no?
  • Está genial. Me da curiosidad cuántas horas por semana le dedicas a este proyecto. Parece que le has metido muchísimo trabajo
    En tu perfil dice que eres estudiante; me pregunto si eso significa universitario y, de ser así, si también trabajaste directamente con este OS como parte de tus estudios

    • Sí, soy universitario. Le mostré el proyecto a un profesor y gracias a eso pude “saltarme” algunas materias como sistemas operativos o concurrencia
      Fuera de eso, este proyecto no forma parte directa de mis estudios. Pero sí me ayudó a conseguir un trabajo de medio tiempo en el área de embebidos de la universidad
      El tiempo que le dedico varía muchísimo según lo que esté pasando en mi vida. Algunos meses solo le metí 5 horas en total, y en algunas semanas casi llegué a 40 horas
  • Gran proyecto. Como nombre para un fork, PlatanOS también sonaría bien

    • Me gusta PlátanOS, con el acento en la primera sílaba
  • Se ve muy bien y parece muchísimo trabajo. Me pregunto cuál fue el desafío más memorable en particular

    • Creo que el mayor desafío fue leer especificaciones grandes. Antes nunca había hecho algo así en serio, así que me tomó tiempo acostumbrarme
  • Increíble. Me da curiosidad cómo desarrollas esto. Si lo corres en VM, en hardware real, y cómo es el proceso cuando te sientas a trabajar
    Seguro aprendiste muchísimo haciéndolo; también me pregunto cómo llevas notas o seguimiento del desarrollo. O si el propio OS es una especie de diario de desarrollo vivo

    • Aproximadamente el 95% de las pruebas las hago en VM. Es mucho más rápido y mucho más cómodo. Aun así, también pruebo regularmente en hardware real
      Verlo correr en bare metal siempre es genial, y el bare metal no perdona tanto como una VM
      Normalmente decido qué funcionalidad quiero agregar, luego reviso por encima las especificaciones relacionadas y a veces también miro cómo lo manejan otros sistemas operativos. Después de hacerme un modelo mental de lo que necesita el sistema, escribo el código según se me va ocurriendo en ese momento
      Tengo la muy mala costumbre de no escribir documentación ni notas. Básicamente guardo todo en la cabeza y luego olvido la información cuando la necesito. Para cosas más complejas sí hago diagramas y tomo notas, pero casi siempre las guardo solo en local
  • Me da curiosidad por dónde empiezas exactamente para escribir drivers como NVMe, ATA o Realtek NIC. Sé que el mouse y el teclado usan HID, que es estándar, pero me pregunto si los demás dispositivos también tienen protocolos estándar parecidos
    También me pregunto si esa es la razón por la que Linux puede evitar en la mayoría de los casos la “instalación de drivers”, y si existen APIs estándar para dispositivos, por qué Windows pasa por un proceso de instalación de drivers cada vez que conectas algo

    • Básicamente, casi todos los dispositivos de uso común tienen protocolos estandarizados. Aun así, hay dispositivos para los que el fabricante sí tiene que proveer un driver
      Todos los dispositivos para los que escribí drivers tenían sus especificaciones disponibles gratis. Por ejemplo, NVMe está en https://nvmexpress.org/specifications
      No sé muy bien cómo manejan Linux o Windows los drivers. Cuando compilas el kernel de Linux, eliges qué drivers incluir en el kernel y cuáles dejar como módulos. Normalmente los drivers comunes se compilan junto con el kernel, así que casi nunca hace falta instalarlos después; solo hay que cargar el módulo del driver
      También hay dispositivos que funcionan con drivers genéricos, pero que pueden usar más funciones si tienen un driver dedicado. Por ejemplo, configurar los LED de un mouse gamer. Supongo que Windows instala este tipo de drivers opcionales
  • Muy buen side project. Me da curiosidad si tienes consejos sobre por dónde empezar, qué materiales de referencia sirven, ese tipo de cosas, para alguien que quiera intentar algo parecido

    • Casi lo mismo que dijeron otros. Conviene leer https://wiki.osdev.org/Getting_Started y, si vas a desarrollar un sistema operativo, tener presente que toma muchísimo tiempo
    • Para conocimiento práctico, OSDev Wiki; para teoría, libros de diseño de sistemas operativos y arquitectura de computadoras
    • En Rust está https://os.phil-opp.com/ y para desarrollo general de sistemas operativos está https://github.com/tuhdo/os01. Además, Operating Systems: Three Easy Pieces es lectura obligatoria
  • Excelente. No esperaba una combinación de funciones así. Me da curiosidad si piensas portar más software en el futuro

    • Sí, planeo portar más cosas. No quiero meter código de terceros en el OS base, pero los ports son una muy buena forma de poder ejecutar cosas que todavía no he escrito yo mismo
      En local todavía tengo algunos ports que no funcionan. git, binutils, gcc y make compilan todos, pero están dando errores raros. Lo más probable es que haya algún bug en mi libc o del lado de las llamadas al sistema