Skip to content

Sri-Ln/VertexOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 

Repository files navigation

VertexOS - A Simple 16-bit Operating System

Logo

A bootable 16-bit operating system built entirely in x86 assembly for CSYE6230 Operating Systems at Northeastern University.

Project Overview

VertexOS is a real-mode operating system that boots from scratch using BIOS interrupts. It features a two-stage bootloader, an interactive shell with file management commands, persistent storage across reboots, and command history with tab completion. Built using the MikeOS approach (pure 16-bit assembly, BIOS interrupts, floppy disk image).

Features

Boot.mp4

Core File Management

Command Description
LIST Display all files with names, sizes, created and modified timestamps
CREATE <n> Create a new file with duplicate checking and filename validation
DELETE <n> Remove a file with error handling for non-existent entries
DELETE_ALL Bulk delete all files with Y/N confirmation prompt
RENAME <old> <new> Rename a file with validation and modified timestamp update
HELP Display all available commands with color-coded output

System Functions

Command Description
CLEAR Clear screen and reset cursor position
STATUS Display system info: OS version, CPU mode, file count, memory, UTC time

Additional Features

  • Data persistence - File table and command history survive reboots via a separate data disk
  • Command history - Last 10 commands stored, navigate with up/down arrows, persisted across sessions
  • Tab completion - Type a prefix and press Tab to auto-complete commands, cycles through matches
  • Colored output - VGA text mode colors: cyan headers, green success, red errors, yellow commands
  • Animated boot sequence - Progress bars with percentage during system initialization
  • File validation - Rejects invalid characters and requires file extensions
  • Case-insensitive input - Automatic uppercase conversion
  • UTC timestamps - Creation and modification dates via BIOS real-time clock

Tools and Environment

Tool Purpose
WSL2 (Ubuntu) Linux environment inside Windows
NASM 2.16 Assembler - converts .asm files to raw binary machine code
QEMU 8.2 Virtual machine emulator - boots and runs the OS in a window
Make 4.3 Build automation - one command to assemble and run
VS Code Code editor connected to WSL2 via Remote-WSL extension

Project Structure

myos/
├── boot.asm        - All OS source code (boot sector + OS kernel)
├── Makefile        - Build automation (assemble, run, clean, reset)
├── data.img        - Persistent data disk (generated at first build, not tracked)
├── boot.bin        - Compiled binary (generated, not tracked)
├── .gitignore      - Excludes .bin and .img files from version control
└── README.md       - This file

Build and Run

Prerequisites

  • Windows 10/11 with WSL2 and Ubuntu installed
  • NASM, QEMU, and Make installed in WSL2

Setup

  1. Open Ubuntu from the Windows Start menu
  2. Install tools:
    sudo apt update && sudo apt upgrade -y
    sudo apt install nasm qemu-system-x86 make -y
  3. Clone and navigate to the project:
    cd ~/myos
  4. Open in VS Code:
    code .

Build Commands

Command What it does
make run Assembles boot.asm, creates data.img if needed, and boots in QEMU
make build Assembles boot.asm without booting
make clean Deletes boot.bin (preserves data.img and saved data)
make reset Deletes both boot.bin and data.img (full fresh start)

Architecture

System Overview

                                       ┌─────────────────────────────────────────────────────┐
                                       │                         QEMU                        │
                                       │                                                     │
                                       │    ┌────────────────┐         ┌───────────────┐     │
                                       │    │  boot.bin      │         │  data.img     │     │
                                       │    │  (OS Disk)     │         │  (Data Disk)  │     │
                                       │    │                │         │               │     │
                                       │    │  Sector 1:     │         │  Sector 1:    │     │
                                       │    │  Boot sector   │         │  File table   │     │
                                       │    │                │         │               │     │
                                       │    │  Sectors 2-20: │         │  Sectors 2-3: │     │
                                       │    │  OS code       │         │  Cmd history  │     │
                                       │    └────────────────┘         └───────────────┘     │
                                       │            ▲                         ▲              │
                                       │            │ Boot                    │ Read/Writ    │
                                       │            │                         │              │
                                       │    ┌──────────────────────────────────────────┐     │
                                       │    │              RAM (0x7C00+)               │     │
                                       │    │                                          │     │
                                       │    │   Boot sector → loads OS → jumps to OS   │     │
                                       │    │     OS: shell, commands, file table,     │     │
                                       │    │       history buffer, save buffer        │     │
                                       │    └──────────────────────────────────────────┘     │
                                       └─────────────────────────────────────────────────────┘

Two-Stage Boot Process

  1. Boot sector (Sector 1, 512 bytes): The BIOS loads this automatically at address 0x7C00. It sets up CPU segment registers, then uses BIOS interrupt int 0x13 to load 19 additional sectors from disk into memory at address 0x7E00. It then jumps to that address.

  2. OS code (Sectors 2-20, loaded at 0x7E00): Contains the ASCII art banner, shell loop, keyboard input handler, command parser, all command implementations, utility functions, and data structures.

Why Two Stages?

A boot sector is exactly 512 bytes. The last 2 bytes must be the boot signature (0xAA55), and the loader code takes some space, leaving very little room for actual OS functionality. By loading extra sectors, we get approximately 9.5 KB of space for OS code and data.

Dual-Disk Architecture

VertexOS uses two separate disk images:

  • boot.bin (OS disk) - Contains the bootloader and all OS code. Rebuilt from source on every make run.
  • data.img (Data disk) - Stores the file table and command history. Created once and never overwritten by builds, ensuring data survives code changes.

This separation solves a key problem: rebuilding the OS from source code would normally destroy any saved user data. By using a dedicated data disk, the build process only touches the OS disk while user data remains intact.

Memory Layout

Address     Contents
─────────────────────────────
0x0000      Interrupt Vector Table
0x7C00      Boot sector (loaded by BIOS)
0x7E00      OS code start (loaded by boot sector)
  ├── Shell loop and command parser
  ├── Command handlers
  ├── Utility functions (print_string, compare_strings, etc.)
  ├── String data (prompts, messages, ASCII art logo)
  ├── File table (8 entries x 28 bytes)
  ├── Input buffer (64 bytes)
  ├── History buffer (10 entries x 64 bytes)
  ├── Save buffers (512 + 1024 bytes for disk I/O)
  └── Variables (color state, date/time, tab completion state)
0xB800      VGA text mode video memory

File Table Structure

Each file entry is 28 bytes:

Offset  Size  Field
──────────────────────────
0       1     Active flag (1 = exists, 0 = deleted)
1       15    File name (null-terminated, max 14 chars)
16      6     Created timestamp (YY, MM, DD, HH, MM, SS in BCD)
22      6     Modified timestamp (YY, MM, DD, HH, MM, SS in BCD)

The table holds 8 entries (224 bytes total). Deletion marks entries as inactive rather than erasing data, similar to early FAT file systems.

Persistence Mechanism

Data is saved to the second floppy drive using BIOS disk write interrupts:

  • Sector 1: Magic number (0xBEEF) + file table
  • Sectors 2-3: Magic number (0xFACE) + history count + history buffer

On boot, the OS reads these sectors and checks the magic numbers. If valid data is found, it loads the saved state. If not (first boot or after make reset), it uses the hardcoded default files.

Key BIOS Interrupts Used

Interrupt Function Purpose
int 0x10 ah=0x0E Print character to screen (teletype mode)
int 0x10 ah=0x09 Write character with color attribute
int 0x10 ah=0x02 Set cursor position
int 0x10 ah=0x03 Get cursor position
int 0x10 ah=0x06 Scroll/clear screen
int 0x12 - Get conventional memory size
int 0x13 ah=0x02 Read sectors from disk
int 0x13 ah=0x03 Write sectors to disk
int 0x16 ah=0x00 Wait for and read keypress
int 0x1A ah=0x02 Read time from RTC
int 0x1A ah=0x04 Read date from RTC

Command Parsing Flow

User types command → Enter pressed
        │
        ▼
Save to history → Save history to disk
        │
        ▼
Is input empty? ──yes──→ Show prompt again
        │ no
        ▼
Compare against exact commands (HELP, CLEAR, LIST, STATUS)
        │ no match
        ▼
Compare against prefix commands (CREATE, RENAME, DELETE_ALL, DELETE)
        │ no match
        ▼
Print "Unknown command"

Prefix matching is used for commands that take arguments. DELETE_ALL is checked before DELETE to prevent DELETE_ALL from being caught by the DELETE prefix.

Design Decisions

Why Pure Assembly (No C)?

  1. Simplicity - No cross-compiler, linker scripts, GDT setup, or protected mode switching required
  2. Predictability - Every instruction does exactly one thing, no compiler optimizations or hidden behavior
  3. Direct hardware access - Every BIOS interrupt call is explicit and visible in the source code
  4. Educational value - Understanding what happens at the instruction level is the core goal of an OS course

The tradeoff is verbosity: operations that take one line in C require 3-5 lines in assembly.

Why 16-bit Real Mode?

Real mode is what the CPU starts in after power-on. Staying in real mode means direct access to BIOS interrupts for hardware I/O, no need for the Global Descriptor Table (GDT) or memory protection setup, a simpler memory model, and maximum compatibility with BIOS services. The limitation is 1 MB of addressable memory, which is more than sufficient for this project.

Why a Separate Data Disk?

Initially, persistence was implemented by writing to a reserved sector on the boot disk. This broke every time the OS was rebuilt from source because NASM generates a fresh binary that overwrites the entire disk image. The dual-disk approach ensures the build process never touches user data.

Why In-Memory File Table (Not a Real File System)?

A real file system (FAT12, ext2) would require implementing sector allocation, directory structures, cluster chains, and free space tracking. The in-memory table approach demonstrates the same concepts (creation, deletion, naming, metadata) while keeping the implementation achievable within the project timeline.

Implementation Challenges

Register Conflicts

The most persistent class of bugs involved CPU registers being inadvertently overwritten:

  • BX/BL conflict: compare_strings originally used BL for comparisons, which corrupted BX (since BL is the lower half of BX). This caused file table pointer corruption during LIST and CREATE. Fixed by using AH instead.
  • DX corruption: validate_filename used DX internally, destroying the argument pointer stored in DX by do_create. Fixed by saving and restoring DX around the function call.
  • BIOS clobbering: Some BIOS interrupts modify registers unexpectedly. Resolved by pushing and popping registers around BIOS calls.

Code Size vs. Boot Sector Limit

The 512-byte boot sector limit was hit early when the welcome banner alone exceeded available space. This forced the two-stage bootloader design. Later, as features were added, the sector count had to be increased from 4 to 19.

Fall-Through Bugs

Assembly has no function boundaries. Code execution flows from one label to the next unless explicitly redirected with jmp or ret. The DELETE_ALL handler had a bug where the confirmed path fell through into the error handler because the error label was placed between the confirmation logic and the wipe loop.

Color Rendering

VGA text mode teletype output (ah=0x0E) ignores the color attribute on SeaBIOS. The solution was a two-step approach: write the character with color using ah=0x09 (which does not advance the cursor), then advance the cursor using ah=0x0E.

Cursor Color Persistence

The blinking cursor inherits its color from the character attribute at its position. After printing colored text, the cursor would display the wrong color. Fixed by writing an invisible space character with the desired color attribute at the cursor position after every print operation.

Limitations and Future Enhancements

Current Limitations

  • No real file content storage (files exist as table entries only)
  • No left/right cursor editing (input only supports typing at end and backspace)
  • Fixed file table size (maximum 8 files, 14-character names)
  • No scrollback (text that scrolls off screen is lost)
  • UTC-only timestamps (no timezone conversion)

Potential Enhancements

  • Write file content to disk sectors for actual file storage
  • Implement FAT12 file system for real disk-based file management
  • Add cursor movement with mid-line insertion and deletion
  • Switch to 32-bit protected mode and load a C kernel for advanced features
  • Implement a VGA graphics mode GUI
  • Add scrollback buffer using Page Up/Page Down

Total Lines of Code

File Lines Description
boot.asm 2,603 All OS source code
Makefile 13 Build automation
Total 2,616 Pure x86 assembly, no external libraries

References

About

A bootable 16-bit operating system built entirely in x86 assembly

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors