Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

2 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

Repository files navigation

my-own-operating-system

Sistema operativo de 64 bits para arquitectura x86, construido desde cero. Implementa la cadena de arranque completa: desde GRUB/Multiboot2 hasta la transición de modo 32→64 bits y un kernel con salida de texto por VGA.


Visión General de la Arquitectura

┌─────────────────────────────────────────────┐
│           Bootloader GRUB                    │  (protocolo Multiboot2)
│         targets/x86_64/iso/boot/            │
└────────────────────┬────────────────────────┘
                     │ carga kernel.bin, pone en eax el magic de Multiboot2
                     ▼
┌─────────────────────────────────────────────┐
│          Cabecera Multiboot2                 │  src/impl/x86_64/boot/header.asm
│   Magic: 0xe85250d6  |  Arch: i386           │
└────────────────────┬────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────┐
│         Arranque en 32 bits                  │  src/impl/x86_64/boot/main.asm
│  - Valida Multiboot2, CPUID, long mode       │
│  - Construye tablas de páginas de 4 niveles  │
│  - Habilita PAE + paginación                 │
│  - Activa long mode via MSR                  │
│  - Carga GDT 64 bits, salto lejano           │
└────────────────────┬────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────┐
│         Punto de entrada 64 bits             │  src/impl/x86_64/boot/main64.asm
│  - Limpia registros de segmento              │
│  - Llama a kernel_main()                     │
└────────────────────┬────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────┐
│              Kernel (C)                      │  src/impl/kernel/main.c
│  - Limpieza de pantalla y colores            │
│  - Utilidades de conversión entero/cadena    │
│  - Punto de entrada kernel_main()            │
└────────────────────┬────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────┐
│           Driver de texto VGA                │  src/impl/x86_64/vga.c
│  - E/S mapeada en memoria (0xb8000)          │
│  - Modo texto 80×25, 16 colores              │
│  - Scroll, saltos de línea, cursor           │
└─────────────────────────────────────────────┘

Capas del Sistema

Bootloader — src/impl/x86_64/boot/

Archivo Descripción
header.asm Cabecera Multiboot2 (número mágico + checksum). Permite que GRUB identifique y cargue el kernel.
main.asm Arranque en modo protegido de 32 bits. Valida capacidades del hardware, construye tablas de páginas de 4 niveles con páginas de 2 MB (mapeo de identidad del primer 1 GB), habilita PAE y long mode via MSR, carga una GDT de 64 bits y realiza un salto lejano al código de 64 bits.
main64.asm Primer código en 64 bits. Pone a cero todos los registros de segmento de datos y llama a kernel_main().

Kernel — src/impl/kernel/

Archivo Descripción
main.c Punto de entrada del kernel (kernel_main). Limpia la pantalla, establece colores, imprime mensajes de arranque y ejercita las utilidades de conversión entero/cadena (itoa, ItoA).

Drivers — src/impl/x86_64/

Archivo Descripción
vga.c Driver del buffer de texto VGA. Escribe struct Char (carácter + byte de color) directamente en la dirección física 0xb8000. Gestiona el movimiento del cursor, saltos de línea, desbordamiento de pantalla y scroll.

Interfaces — src/intf/

Archivo Descripción
vga.h API pública del driver VGA: print_clear(), print_char(), print_str(), print_newline(), print_set_color(). Define también las 16 constantes de color de la paleta VGA.

Linker y Configuración de Arranque — targets/x86_64/

Archivo Descripción
linker.ld Ubica primero .multiboot_header, luego .text, a partir de 1 MB (0x100000). El punto de entrada es el símbolo start de main.asm.
iso/boot/grub/grub.cfg Menú de GRUB: timeout cero, carga kernel.bin via multiboot2.

Estructura del Proyecto

my-own-operating-system/
├── buildenv/
│   └── Dockerfile          # Entorno de compilación cruzada (x86_64-elf-gcc + nasm + grub)
├── src/
│   ├── intf/
│   │   └── vga.h           # Interfaz pública del driver VGA
│   └── impl/
│       ├── kernel/
│       │   └── main.c      # Punto de entrada del kernel (kernel_main)
│       └── x86_64/
│           ├── boot/
│           │   ├── header.asm   # Cabecera Multiboot2
│           │   ├── main.asm     # Arranque 32 bits + configuración de long mode
│           │   └── main64.asm   # Entrada 64 bits, llama a kernel_main
│           └── vga.c            # Driver de texto VGA
├── targets/
│   └── x86_64/
│       ├── linker.ld            # Script del linker (disposición de memoria)
│       └── iso/boot/grub/
│           └── grub.cfg         # Configuración del bootloader GRUB
├── Makefile                     # Reglas de compilación, enlazado y creación de ISO
├── build.sh                     # Script de build con Docker
└── test.sh                      # Runner de pruebas con QEMU

Desarrollo

Prerrequisitos

Herramienta Uso
Docker Proporciona el entorno de compilación cruzada en contenedor
QEMU Emula una máquina x86_64 para ejecutar la ISO del kernel

En macOS (Homebrew):

brew install docker qemu

En Debian/Ubuntu:

sudo apt install docker.io qemu-system-x86

Entorno de Build

El build se ejecuta dentro de un contenedor Docker basado en randomdude/gcc-cross-x86_64-elf. Incluye:

  • x86_64-elf-gcc — compilador C cruzado (sin stdlib, target bare-metal)
  • nasm — ensamblador para archivos .asm
  • xorriso + grub-pc-bin — creación de ISO con GRUB

Construir la imagen Docker (solo la primera vez o tras modificar buildenv/Dockerfile):

docker build -t mario21ic/my-own-os:builder buildenv/

Compilar

./build.sh

Internamente ejecuta make build-x86_64 dentro del contenedor. El Makefile:

  1. Compila todos los .c bajo src/impl/kernel/ y src/impl/x86_64/ con:
    x86_64-elf-gcc -c -I src/intf -ffreestanding
    
  2. Ensambla todos los .asm bajo src/impl/x86_64/ con:
    nasm -f elf64
    
  3. Enlaza todos los objetos via targets/x86_64/linker.ld generando dist/x86_64/kernel.bin:
    x86_64-elf-ld -n -T targets/x86_64/linker.ld
    
  4. Empaqueta una ISO arrancable con grub-mkrescue:
    dist/x86_64/kernel.iso
    

Ejecutar / Probar

./test.sh

Lanza:

qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso

QEMU arranca la ISO, GRUB carga kernel.bin y la salida del kernel aparece en la ventana de QEMU.

Ciclo completo

./build.sh && ./test.sh

Cómo Se Conectan las Piezas

src/intf/vga.h
    └── incluido por src/impl/kernel/main.c
                  y src/impl/x86_64/vga.c

src/impl/x86_64/boot/header.asm  ─────────┐
src/impl/x86_64/boot/main.asm    ──────────┤ enlazados por linker.ld
src/impl/x86_64/boot/main64.asm  ──────────┤ entrada: start (main.asm)
src/impl/x86_64/vga.c            ──────────┤
src/impl/kernel/main.c           ──────────┘
        │
        └──→ dist/x86_64/kernel.bin
                    │
                    └──→ targets/x86_64/iso/boot/kernel.bin (symlink)
                                │
                                └──→ dist/x86_64/kernel.iso  (grub-mkrescue)

Flujo de ejecución en tiempo de arranque:

GRUB → start (main.asm, 32 bits)
         → valida el magic de Multiboot2 (eax)
         → verifica soporte de CPUID / long mode
         → mapea 1 GB con páginas de 2 MB
         → habilita PAE + long mode + paginación
         → carga GDT 64 bits, salto lejano
              → long_mode_start (main64.asm, 64 bits)
                   → kernel_main() (main.c)
                        → print_clear() / print_set_color() / print_str()
                             → buffer VGA 0xb8000 (vga.c)

Agregar un Nuevo Archivo Fuente

  • Archivo C en cualquier lugar bajo src/impl/kernel/ o src/impl/x86_64/: el wildcard del Makefile lo toma automáticamente.
  • Archivo ASM en cualquier lugar bajo src/impl/x86_64/: igual — NASM lo ensambla y el linker lo incluye.
  • Nuevo header de interfaz: colocarlo en src/intf/ e incluirlo con #include "tuarchivo.h".

Capacidades Actuales

  • Arranca en hardware real y QEMU via GRUB/Multiboot2
  • Transición de modo 32 bits → 64 bits (long mode) con paginación y GDT correctas
  • Salida de texto VGA: 80×25 caracteres, 16 colores de primer plano/fondo, scroll
  • Utilidades básicas del kernel: itoa (entero a cadena), familia print_*

Referencias


Licencia

MIT © 2021 Mario IC

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages