Learning Objectives
- Understand what VOS is and why it exists
- Learn about computer architecture basics
- Set up your development environment
- Run your first VOS program
VOS (Virtual Operating System) is a complete computer system simulator that runs entirely in software. It includes:
- A virtual CPU that executes instructions
- Virtual memory (RAM) for storing data
- I/O devices like keyboards and displays
- An operating system kernel that manages everything
- A shell for interacting with the system
- A programming language for writing programs
Think of VOS as a computer inside your computer - it's fully functional but designed specifically for learning.
Learning operating systems and computer architecture from textbooks alone can be abstract and difficult. VOS makes these concepts concrete by providing:
- Working code - See exactly how things work
- Safe experimentation - Break things without consequences
- Complete control - Modify anything you want
- Educational design - Built for understanding, not performance
You can't easily break a real operating system to see how it works. With VOS, you can!
Let's start with a simple mental model of a computer:
┌─────────────────────────────────────────┐
│ CPU (Processor) │
│ ┌────────────────────────────────┐ │
│ │ Registers (Fast Storage) │ │
│ │ - R0, R1, R2, ... (16 total) │ │
│ │ - PC (Program Counter) │ │
│ └────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ ALU (Arithmetic Logic Unit) │ │
│ │ - Performs calculations │ │
│ │ - Comparisons │ │
│ └────────────────────────────────┘ │
└──────────────┬──────────────────────────┘
│ Bus
├─────────────────┐
│ │
┌────────▼────────┐ ┌─────▼──────┐
│ Memory (RAM) │ │ I/O │
│ │ │ Devices │
│ - Programs │ │ │
│ - Data │ │ - Display │
│ │ │ - Keyboard│
└─────────────────┘ └────────────┘
The CPU (Central Processing Unit) is the brain of the computer. It:
- Fetches instructions from memory
- Decodes them to understand what to do
- Executes the instruction
- Repeats forever
This is called the fetch-decode-execute cycle.
The CPU contains:
- Registers: Super-fast storage inside the CPU (like variables)
- ALU: Does math and logic (add, subtract, compare, etc.)
- Control Unit: Orchestrates everything
Memory stores both programs (instructions) and data. Think of it as a huge array:
Address Data
0x0000 [42]
0x0001 [17]
0x0002 [99]
...
0xFFFF [13]
Each address points to one byte of data. The CPU can:
- Read from an address (get the value)
- Write to an address (change the value)
I/O (Input/Output) devices let the computer interact with the world:
- Input: Keyboard, mouse, disk
- Output: Display, printer, speakers
In VOS, devices are memory-mapped, meaning you interact with them by reading and writing to special memory addresses.
An operating system (OS) is a program that:
- Manages hardware resources (CPU, memory, devices)
- Provides a nice interface for other programs
- Keeps programs from interfering with each other
- Makes programming easier
Examples: Linux, Windows, macOS, or... VOS!
VOS implements a simple but complete computer architecture:
- 32-bit RISC architecture (simple instructions)
- 16 general-purpose registers (R0-R15)
- ~30 instructions (just enough to be useful)
- Word size: 32 bits (4 bytes)
VOS divides its 4GB address space into regions:
0x00000000 - 0x00000FFF Interrupt Vector Table (4KB)
0x00001000 - 0x000FFFFF Kernel Code (1MB)
0x00100000 - 0x001FFFFF Kernel Stack (1MB)
0x00200000 - 0x3FFFFFFF User Programs (~1GB)
0x40000000 - 0x7FFFFFFF Heap (1GB)
0x80000000 - 0xBFFFFFFF Memory-Mapped I/O (1GB)
0xC0000000 - 0xFFFFFFFF Reserved (1GB)
This organization keeps different parts of the system separate and organized.
You need Rust installed. If you don't have it:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/envVerify installation:
rustc --version # Should show 1.70 or later
cargo --versionClone the repository:
git clone https://github.com/[username]/vos.git
cd vosBuild the project:
cargo build --releaseThis compiles all the VOS components. It may take a few minutes the first time.
vos/
├── crates/ # All the VOS components
│ ├── vos-core/ # Core types and traits
│ ├── vos-cpu/ # CPU emulator
│ ├── vos-memory/ # Memory system
│ ├── vos-kernel/ # OS kernel
│ └── ...
├── tutorials/ # This is where you are now!
├── examples/ # Example programs
└── tests/ # Integration tests
Let's run a simple program to make sure everything works.
Create a file examples/asm/hello.asm:
; Hello World in VOS assembly
; This program prints "Hello, VOS!" to the display
.text
.global _start
_start:
; Load address of message into R1
lui R1, hi(message)
ori R1, R1, lo(message)
; Load syscall number (1 = write)
addi R2, R0, 1
; File descriptor (1 = stdout)
addi R3, R0, 1
; Buffer address
mov R4, R1
; Length of message
addi R5, R0, 12
; Make syscall
syscall
; Exit
addi R2, R0, 0 ; syscall 0 = exit
addi R3, R0, 0 ; exit code 0
syscall
halt
.data
message:
.string "Hello, VOS!\n"Don't worry if you don't understand this yet! We'll learn assembly in Chapter 2.
# Assemble the program
cargo run --bin vos-cli -- asm examples/asm/hello.asm -o hello.bin
# Run it
cargo run --bin vos-cli -- run hello.binYou should see:
Hello, VOS!
Congratulations! You just ran your first program on VOS.
Let's break down what occurred:
- Assembler converted assembly code to machine code (binary instructions)
- VOS CLI loaded the program into virtual memory
- Virtual CPU executed the instructions one by one
- System call (syscall) asked the OS to print text
- Virtual display showed the output
All of this happened in software, but it's exactly how a real computer works!
Let's look at vos-core, the foundation of VOS. Open crates/vos-core/src/types.rs:
/// A 32-bit word - the native data type of the VOS CPU.
pub type Word = u32;
/// A memory address in the VOS system.
pub type Address = u32;
/// A single byte of data.
pub type Byte = u8;These are type aliases - we give meaningful names to basic types:
Wordis a 32-bit unsigned integer (0 to 4,294,967,295)Addressis also 32 bits, giving us 4GB of address spaceByteis 8 bits (0 to 255)
Now look at AddressRange:
pub struct AddressRange {
pub start: Address,
pub end: Address,
}
impl AddressRange {
pub fn contains(&self, address: Address) -> bool {
address >= self.start && address < self.end
}
}This represents a range of memory addresses and can check if an address falls within it. Simple but useful!
Let's verify VOS is working correctly.
cargo test -p vos-coreYou should see all tests pass. These tests verify that the core types work correctly.
- Open
crates/vos-core/src/types.rs - Find the
memory_regionsmodule - Answer these questions:
- What address does the kernel code start at?
- How large is the user space region?
- What addresses are used for memory-mapped I/O?
Click to reveal answers
- Kernel code starts at
0x00001000 - User space is
0x3FFFFFFF - 0x00200000 = 0x3FDFFFFFbytes (~1GB) - MMIO uses
0x80000000to0xBFFFFFFF
Add a test to crates/vos-core/src/types.rs:
#[test]
fn test_my_first_test() {
use crate::types::memory_regions;
// Kernel code region
assert!(memory_regions::KERNEL_CODE.contains(0x00001000));
// User space
assert!(memory_regions::USER_SPACE.contains(0x00200000));
// This should NOT be in kernel code
assert!(!memory_regions::KERNEL_CODE.contains(0x80000000));
}Run it:
cargo test -p vos-core test_my_first_testCongratulations! You just wrote your first VOS test.
Ready for more? Try these:
Add a new memory region called VIDEO_MEMORY from 0x80000000 to 0x80100000 (1MB for the display buffer).
- Add it to the
memory_regionsmodule - Write a test for it
- Make sure all tests still pass
Implement an iterator that yields all 4KB-aligned addresses in a range:
impl AddressRange {
pub fn aligned_addresses(&self, alignment: usize) -> impl Iterator<Item = Address> {
// Your code here
}
}Test it:
#[test]
fn test_aligned_addresses() {
let range = AddressRange::new(0x1000, 0x3000);
let addresses: Vec<_> = range.aligned_addresses(0x1000).collect();
assert_eq!(addresses, vec![0x1000, 0x2000]);
}Read about the Von Neumann architecture and answer:
- What is the key idea of Von Neumann architecture?
- How does VOS follow this architecture?
- What is the alternative (Harvard architecture)?
In this chapter, you learned:
- ✅ What VOS is and why it's useful for learning
- ✅ Basic computer architecture (CPU, memory, I/O)
- ✅ How to set up the VOS development environment
- ✅ How to run and test VOS programs
- ✅ The structure of the VOS codebase
In Chapter 2: CPU Basics, we'll dive into how the CPU works:
- Registers and the ALU
- The fetch-decode-execute cycle
- Instruction formats
- Writing assembly programs
- Computer Systems: A Programmer's Perspective
- The Rust Programming Language Book
- Operating Systems: Three Easy Pieces
- MIPS Assembly Language (VOS is MIPS-inspired)