Conductor Microkernel Architecture
A microkernel is an operating system design where the kernel provides only the most essential services, while all other functionality runs as separate processes (services) in userspace. This is opposite to monolithic kernels where everything runs in kernel space with full privileges.
Core Philosophy: Keep the kernel minimal, secure, and stable. Push complexity to userspace where it can't crash the system.
The absolute minimal kernel that cannot be removed or run in userspace.
class MicrokernelCore {
// The heart of the system - coordinates everything
function boot() {
initialize_memory_manager()
initialize_scheduler()
initialize_ipc_system()
initialize_interrupt_handler()
start_initial_services()
}
function shutdown() {
notify_all_services()
cleanup_resources()
halt_system()
}
}
Why it can't be userspace: Someone needs to have ultimate authority over hardware and process creation.
Manages virtual memory, physical memory allocation, and memory protection.
class MemoryManager {
function allocate_virtual_memory(process_id, size, permissions) {
// Allocate virtual address space for a process
virtual_address = find_free_virtual_range(size)
physical_pages = allocate_physical_pages(size)
map_virtual_to_physical(virtual_address, physical_pages, permissions)
return virtual_address
}
function free_memory(process_id, virtual_address) {
// Free both virtual and physical memory
physical_pages = get_physical_mapping(virtual_address)
unmap_virtual_address(virtual_address)
free_physical_pages(physical_pages)
}
function protect_memory(virtual_address, new_permissions) {
// Change memory protection (read/write/execute)
update_page_table_permissions(virtual_address, new_permissions)
flush_tlb() // Translation Lookaside Buffer
}
function share_memory(process1_id, process2_id, size) {
// Allow two processes to share memory region
physical_pages = allocate_physical_pages(size)
map_to_process(process1_id, physical_pages)
map_to_process(process2_id, physical_pages)
}
}
Critical for microkernel: Services need isolated memory spaces, but also controlled sharing for IPC.
Decides which process runs when and manages CPU time allocation.
class Scheduler {
queue ready_queue
queue blocked_queue
process current_process
function schedule_next() {
// Choose next process to run
if (ready_queue.is_empty()) {
run_idle_process()
} else {
next_process = ready_queue.dequeue()
context_switch(current_process, next_process)
current_process = next_process
}
}
function create_process(executable_path, priority, memory_limit) {
process = new Process()
process.load_executable(executable_path)
process.allocate_memory(memory_limit)
process.set_priority(priority)
ready_queue.enqueue(process)
return process.process_id
}
function block_process(process_id, reason) {
// Move process from ready to blocked state
process = find_process(process_id)
ready_queue.remove(process)
blocked_queue.add(process, reason)
}
function unblock_process(process_id) {
// Move process from blocked back to ready
process = blocked_queue.remove(process_id)
ready_queue.enqueue(process)
}
function terminate_process(process_id) {
process = find_process(process_id)
cleanup_process_resources(process)
remove_from_all_queues(process)
}
}
Why essential: Without scheduling, multiple services can't coexist and share CPU time fairly.