This document details the refactoring of OpenOS from a flat directory structure to a modular monolithic architecture. This refactoring was performed to improve code organization, maintainability, and scalability.
Before:
Kernel2.0/
├── boot.S
├── kernel.c
├── idt.c/h
├── pic.c/h
├── isr.S/h
├── exceptions.c/h/S
├── pmm.c/h
├── vmm.c/h
├── keyboard.c/h
├── timer.c/h
└── linker.ld
After:
├── arch/x86/ # Architecture-specific code
├── kernel/ # Core kernel
├── memory/ # Memory management
├── drivers/ # Device drivers
├── fs/ # File systems (future)
├── process/ # Process management (future)
├── include/ # Common headers
└── Kernel2.0/ # Output directory (compatibility)
| Original Location | New Location | Changes |
|---|---|---|
Kernel2.0/boot.S |
arch/x86/boot.S |
None |
Kernel2.0/idt.c/h |
arch/x86/idt.c/h |
Updated header guards |
Kernel2.0/isr.S/h |
arch/x86/isr.S/h |
Updated header guards |
Kernel2.0/pic.c/h |
arch/x86/pic.c/h |
Removed inline I/O functions |
Kernel2.0/exceptions.* |
arch/x86/exceptions.* |
Updated to use console_* |
Kernel2.0/pmm.c/h |
memory/pmm.c/h |
Use include/multiboot.h |
Kernel2.0/vmm.c/h |
memory/vmm.c/h |
Updated header guards |
Kernel2.0/keyboard.c/h |
drivers/keyboard.c/h |
Updated includes |
Kernel2.0/timer.c/h |
drivers/timer.c/h |
Updated includes |
Kernel2.0/kernel.c |
kernel/kernel.c |
Extracted console code |
| N/A | drivers/console.c/h |
New (extracted from kernel.c) |
| N/A | kernel/panic.c/h |
New |
| N/A | include/types.h |
New |
| N/A | include/multiboot.h |
New |
| N/A | arch/x86/ports.h |
New |
All header guards updated to reflect new paths:
// Before
#ifndef IDT_H
#define IDT_H
// After
#ifndef OPENOS_ARCH_X86_IDT_H
#define OPENOS_ARCH_X86_IDT_H
All include statements updated for new structure:
// Before (in keyboard.c)
#include "keyboard.h"
#include "pic.h"
// After
#include "keyboard.h"
#include "../arch/x86/pic.h"
#include "../arch/x86/ports.h"
Console functions standardized:
// Before
terminal_write(const char* s);
terminal_put_char(char c);
terminal_clear(void);
// After
console_write(const char* s);
console_put_char(char c);
console_clear(void);
// Compatibility aliases provided
void terminal_write(char c) { console_write(c); }
void terminal_put_char(char c) { console_put_char(c); }
Complete rewrite of Makefile with:
Key changes:
# Include paths
CFLAGS += -I./include
CFLAGS += -I./arch/x86
CFLAGS += -I./kernel
CFLAGS += -I./memory
CFLAGS += -I./drivers
# Objects organized by directory
ARCH_OBJS = arch/x86/boot.o arch/x86/idt.o ...
KERNEL_OBJS = kernel/kernel.o kernel/panic.o
MEMORY_OBJS = memory/pmm.o memory/vmm.o
DRIVERS_OBJS = drivers/console.o drivers/keyboard.o drivers/timer.o
# Output to legacy location for compatibility
OUTPUT_BIN = Kernel2.0/openos.bin
Kernel2.0/openos.bin_start -> kmainmake - Still builds the kernelmake run - Still runs in QEMUmake iso - Still creates bootable ISOmake run-vbox - Still works with VirtualBoxtools/* scripts - No changes neededIf you’re working on OpenOS, here’s what you need to know:
| What you’re looking for | Where it is now |
|---|---|
| Boot code | arch/x86/boot.S |
| Interrupts (IDT/ISR) | arch/x86/idt.c, arch/x86/isr.S |
| PIC initialization | arch/x86/pic.c |
| Exception handlers | arch/x86/exceptions.c |
| Memory management | memory/pmm.c, memory/vmm.c |
| Keyboard driver | drivers/keyboard.c |
| Timer driver | drivers/timer.c |
| Console/VGA | drivers/console.c |
| Main kernel | kernel/kernel.c |
Architecture code (x86-specific):
# Create file in arch/x86/
touch arch/x86/newfeature.c arch/x86/newfeature.h
# Add to Makefile ARCH_OBJS
ARCH_OBJS = ... arch/x86/newfeature.o
Drivers:
# Create file in drivers/
touch drivers/newdriver.c drivers/newdriver.h
# Add to Makefile DRIVERS_OBJS
DRIVERS_OBJS = ... drivers/newdriver.o
Memory management:
# Create file in memory/
touch memory/newmem.c memory/newmem.h
# Add to Makefile MEMORY_OBJS
MEMORY_OBJS = ... memory/newmem.o
// Include the console header
#include "console.h" // or "../drivers/console.h" depending on location
// Use console functions
console_write("Hello, World!\n");
console_put_char('X');
console_clear();
// Include ports header
#include "ports.h" // or "../arch/x86/ports.h"
// Use port functions
outb(0x3F8, 'A'); // Write byte to port
uint8_t data = inb(0x3F8); // Read byte from port
io_wait(); // Short delay
When submitting PRs:
make clean && make works// File: drivers/newdriver.c
#include "newdriver.h"
#include "../arch/x86/ports.h"
// Static (internal) state
static int internal_state = 0;
// Static (internal) functions
static void internal_helper(void) {
// ...
}
// Public functions
void newdriver_init(void) {
// Initialize driver
}
void newdriver_read(void *buffer, size_t size) {
// Read from device
}
# Clean build
make clean
# Build kernel
make
# Check binary exists
ls -lh Kernel2.0/openos.bin
# Check symbols
nm Kernel2.0/openos.bin | grep kmain
Expected output:
00100950 T kmain
The refactored kernel should:
| Metric | Before | After | Change |
|---|---|---|---|
| Binary size | ~17 KB | ~17 KB | No change |
| Source lines | ~1,881 | ~2,400 | +519 (docs, headers) |
| C files | 10 | 14 | +4 (console, panic, types, multiboot) |
| Headers | 11 | 17 | +6 (split modules) |
The following are noted for future improvement:
This refactoring successfully reorganized OpenOS into a modular monolithic architecture while preserving all functionality and compatibility. The new structure provides a solid foundation for future development.
For questions about the refactoring: