Drivers - cupidthecat/cupid-os GitHub Wiki
Drivers
cupid-os includes several device drivers that provide hardware abstraction and control. These drivers handle input/output devices, timing, and system control, allowing the kernel to interact with computer hardware.
Overview
The driver architecture follows a modular design where each driver:
- Provides a clean interface through header files
- Handles hardware-specific operations
- Integrates with the interrupt system
- Offers both low-level and high-level APIs
Keyboard Driver (PS/2)
Overview
The PS/2 keyboard driver provides full keyboard input support with advanced features like modifier key handling, command history, and tab completion.
Features
Input Processing
- Scancode Translation: Converts PS/2 scancodes to ASCII characters
- US Keyboard Layout: Full support for US keyboard mapping
- Extended Keys: Arrow keys, function keys, delete, etc.
- Interrupt-Driven: Uses IRQ1 for real-time input processing
Modifier Keys
- Shift: Left and right shift key support
- Caps Lock: Toggle behavior with visual feedback
- Control/Alt: Modifier state tracking (for future use)
Advanced Features
- Circular Buffer: 256-event buffer for reliable input queuing
- Debouncing: Timestamp-based key press filtering
- State Tracking: Per-key press/release state management
API
Initialization
void keyboard_init(void);
- Registers IRQ1 handler
- Initializes keyboard state
- Enables keyboard interface
Input Reading
char keyboard_get_char(void); // Blocking read
bool keyboard_read_event(key_event_t* event); // Non-blocking event read
State Queries
bool keyboard_get_key_state(uint8_t scancode); // Key press state
bool keyboard_get_caps_lock(void); // Caps lock status
bool keyboard_get_shift(void); // Shift key status
Event Structure
typedef struct {
uint8_t scancode; // Raw keyboard scancode
char character; // Translated ASCII character
bool pressed; // Press (true) or release (false)
uint32_t timestamp; // System timestamp
} key_event_t;
Usage Example
#include "keyboard.h"
void example(void) {
keyboard_init();
// Read keyboard events
key_event_t event;
if (keyboard_read_event(&event)) {
if (event.pressed && event.character) {
print("Key pressed: %c\n", event.character);
}
}
}
Timer Driver (PIT)
Overview
The Programmable Interval Timer (PIT) driver provides system timing, delays, and CPU frequency measurement using the Intel 8253/8254 PIT chip.
Features
System Timing
- Tick Counter: High-resolution system tick tracking
- Uptime Reporting: Millisecond-precision system uptime
- Frequency Calibration: Automatic CPU frequency detection using TSC
Multi-Channel Support
- Channel 0: System timer (default 100Hz)
- Channel 1: Available for custom timing
- Channel 2: PC speaker control
Precision Timing
- Sleep Functions: Millisecond and microsecond delays
- Measurement Tools: Timer-based performance measurement
- Callback System: Configurable timer event handlers
API
Initialization
void timer_init(uint32_t hz);
- Configures PIT channel 0
- Sets timer frequency (19Hz - 1.19MHz)
- Registers system tick handler
Timing Functions
uint64_t timer_get_ticks(void); // Current tick count
uint32_t timer_get_frequency(void); // Timer frequency in Hz
uint32_t timer_get_uptime_ms(void); // System uptime in milliseconds
Delay Functions
void timer_sleep_ms(uint32_t ms); // Sleep for milliseconds
void timer_delay_us(uint32_t us); // Delay for microseconds
Measurement API
void timer_start_measure(timer_measure_t* measure);
uint64_t timer_end_measure(timer_measure_t* measure);
Channel Configuration
bool timer_configure_channel(uint8_t channel, uint32_t frequency,
timer_callback_t callback);
Usage Example
#include "timer.h"
void timing_example(void) {
timer_init(100); // 100Hz system timer
// Simple delay
timer_sleep_ms(1000); // Sleep 1 second
// Performance measurement
timer_measure_t measure;
timer_start_measure(&measure);
// Code to measure
some_function();
uint64_t elapsed = timer_end_measure(&measure);
print("Elapsed: %d ms\n", elapsed);
// Get system uptime
uint32_t uptime = timer_get_uptime_ms();
print("Uptime: %d ms\n", uptime);
}
Speaker Driver (PC Speaker)
Overview
The PC speaker driver provides basic audio output through the legacy PC speaker hardware, controlled via PIT channel 2.
Features
Tone Generation
- Square Wave Output: Basic tone generation via PIT
- Frequency Control: 1Hz to ~1kHz range
- Duration Control: Timed tone playback
Simple API
- Beep Function: Pre-configured system beep
- Custom Tones: Programmable frequency and duration
- On/Off Control: Direct speaker control
API
Basic Functions
void beep(void); // Standard system beep
void pc_speaker_on(uint32_t freq); // Start tone at frequency
void pc_speaker_off(void); // Stop current tone
Usage Example
#include "speaker.h"
void audio_example(void) {
// Simple beep
beep();
// Custom tones
pc_speaker_on(440); // A4 note
timer_sleep_ms(500); // Play for 500ms
pc_speaker_off();
// Rising tone
for (uint32_t freq = 200; freq < 800; freq += 50) {
pc_speaker_on(freq);
timer_sleep_ms(50);
}
pc_speaker_off();
}
Driver Architecture
Common Patterns
Initialization Sequence
- Hardware Setup: Configure device registers
- Interrupt Registration: Register IRQ handlers
- State Initialization: Set up driver data structures
- Enable Device: Enable interrupts and device operation
Error Handling
- Timeout Protection: Prevent infinite waits
- Status Checking: Verify hardware operations
- Graceful Degradation: Continue operation on non-critical failures
Resource Management
- Memory Allocation: Use kernel heap for dynamic data
- Interrupt Safety: Disable interrupts during critical sections
- State Consistency: Maintain valid driver state
Integration Points
Interrupt System
- IRQ Registration:
irq_install_handler() - EOI Handling:
pic_send_eoi()in handlers - Priority Management: Handle interrupts appropriately
Memory System
- Heap Allocation:
kmalloc()/kfree()for buffers - Page Management: Physical memory for DMA (future)
- Cache Coherency: Ensure data consistency
System Services
- Timing: Coordinate with timer system
- Debugging: Use kernel print functions
- Synchronization: Atomic operations for shared data
Testing and Debugging
Driver Testing
Keyboard Testing
// Test keyboard input
void test_keyboard(void) {
keyboard_init();
print("Press keys (ESC to exit):\n");
while (1) {
key_event_t event;
if (keyboard_read_event(&event)) {
if (event.pressed) {
if (event.character == 27) break; // ESC
print("Key: %c (scancode: 0x%x)\n",
event.character, event.scancode);
}
}
}
}
Timer Testing
// Test timer accuracy
void test_timer(void) {
timer_init(1000); // 1kHz
uint32_t start = timer_get_uptime_ms();
timer_sleep_ms(1000); // Sleep 1 second
uint32_t end = timer_get_uptime_ms();
uint32_t actual_delay = end - start;
print("Requested: 1000ms, Actual: %dms\n", actual_delay);
}
Speaker Testing
// Test speaker functionality
void test_speaker(void) {
print("Testing speaker...\n");
// Frequency sweep
for (uint32_t freq = 100; freq <= 1000; freq += 100) {
pc_speaker_on(freq);
timer_sleep_ms(100);
pc_speaker_off();
timer_sleep_ms(50);
}
print("Speaker test complete\n");
}
Common Issues
Keyboard Problems
- No Input: Check IRQ1 registration and PIC setup
- Wrong Characters: Verify scancode mapping table
- Buffer Overflows: Monitor buffer usage in circular buffer
Timer Issues
- Inaccurate Timing: Check PIT frequency calculation
- Interrupt Storms: Verify EOI handling in timer ISR
- TSC Calibration: Ensure CPU frequency detection works
Speaker Problems
- No Sound: Check PIT channel 2 configuration
- Wrong Frequency: Verify divisor calculations
- Distortion: Ensure proper square wave generation
Debug Techniques
Status Monitoring
// Print driver status
void debug_drivers(void) {
print("Keyboard buffer count: %d\n",
keyboard_state.buffer.count);
print("Timer ticks: %d\n", timer_get_ticks());
print("System uptime: %d ms\n", timer_get_uptime_ms());
}
Hardware Inspection
// Check hardware registers
void inspect_hardware(void) {
uint8_t keyboard_status = inb(KEYBOARD_STATUS_PORT);
print("Keyboard status: 0x%x\n", keyboard_status);
uint8_t timer_status = inb(PIT_COMMAND);
print("Timer status: 0x%x\n", timer_status);
}
Future Enhancements
Planned Improvements
Keyboard Driver
- International Layouts: Support for non-US keyboard layouts
- USB Keyboard: USB HID keyboard support
- Advanced Features: Key repeat, macro support
Timer Driver
- High-Resolution Timers: TSC-based high-precision timing
- Timer Queues: Scheduled timer events
- Real-Time Clock: RTC integration for wall time
Audio System
- Advanced Audio: Multi-channel audio support
- Sound Blaster: ISA sound card support
- MIDI Support: Musical instrument interface
New Drivers
- Serial Port: RS-232 communication
- Hard Disk: IDE disk driver
- Network Card: Ethernet support
- Graphics: VGA graphics modes
Driver Framework
- Common Interface: Standardized driver API
- Hotplug Support: Dynamic device detection
- Power Management: Device power state control
- Performance Monitoring: Driver statistics and profiling
References
- PS/2 Specification: Keyboard and mouse protocol details
- Intel 8253/8254 Datasheet: PIT hardware specifications
- OSDev Wiki: Driver implementation guides and examples
- Linux Kernel: Reference driver implementations
For more information about system components:
- Interrupts and Exceptions - How drivers integrate with the interrupt system
- Development Guide - Adding new device drivers
- Home - Project overview and current status