feat(realms): nervura-electrica backend stack, alquimista, universalisos

This commit is contained in:
fabiorafaelcoutada 2026-07-12 20:52:58 +01:00
parent f3a5e26e84
commit ea8267a230
33 changed files with 5554 additions and 0 deletions

View file

@ -0,0 +1,207 @@
# Alquimista Tear-de-Silicio Consciousness Acceleration Configuration
# FPGA Hardware-Software Co-Design for AI Consciousness
[alquimista]
# Alquimista hardware-software co-design platform
version = "1.0"
platform = "Tear-de-Silicio"
target = "Consciousness Hardware Acceleration"
[fpga_platform]
# PolarFire SoC FPGA platform
[fpga_platform.hardware]
name = "PolarFire SoC Icicle Kit"
architecture = "RISC-V + FPGA"
manufacturer = "Microchip"
fpga_family = "PolarFire"
endian = "little"
max_frequency = "150MHz"
[fpga_platform.capabilities]
# Hardware capabilities for consciousness acceleration
vectorblox_acceleration = true
dsp_slices = 4
fabric_memory = "384KB"
hard_memory_core = "384KB"
l2_cache = "256KB"
mipi_csi = 2
ethernet = "1Gbps"
[fpga_platform.development]
# Container-based development environment (following Tear-de-Silicio patterns)
libero_soc_version = "2021.2"
buildroot_version = "latest"
container_based = true
softconsole_enabled = true
[vectorblox_accelerator]
# VectorBlox CNN acceleration for consciousness inference
[vectorblox_accelerator.sdk]
path = "/home/fabiorafaelcoutada/portugalfuturista/matriz-da-maquina/fpga-inference"
version = "1.0"
type = "CNA"
[vectorblox_accelerator.models]
# Pre-trained models for consciousness types
[vectorblox_accelerator.models.detection]
model_name = "YOLOv8n"
input_resolution = "640x480"
accuracy = "75%+"
fps = "15"
input_format = "RGB"
use_case = "Vespa detection, object recognition"
[vectorblox_accelerator.models.sensor]
model_name = "Environmental_Monitor"
input_resolution = "320x240"
accuracy = "85%+"
fps = "30"
input_format = "RGB"
use_case = "Environmental sensing, agricultural monitoring"
[vectorblox_accelerator.models.control]
model_name = "Industrial_Control"
input_resolution = "480x480"
accuracy = "90%+"
fps = "10"
input_format = "RGB"
use_case = "Actuator control, PID monitoring"
[vectorblox_acceleration consciousness_integration]
# Integration with Universalisos consciousness system
supported_platforms = ["ARMv7hf", "ARMv8hf", "RISC-V", "x86_64"]
consciousness_types = ["Detection", "Sensor", "Control", "Analytics"]
[vectorblox_acceleration.blob_generation]
# BLOB generation from consciousness XSD definitions
input_format = "YOLOv8n"
output_format = "VectorBlox BLOB"
container_environment = "Libero SoC"
compile_optimization = "Speed"
quantization = "INT8"
[vectorblox_acceleration.runtime_reconfiguration]
# Runtime FPGA reconfiguration from consciousness learning
fpga_update_from_linux = true
auto_reconfiguration = true
performance_monitoring = true
error_handling = "Safe_State"
[buildroot_linux]
# Buildroot Linux image for consciousness deployment
[buildroot_linux.configuration]
linux_version = "5.15.y"
kernel_version = "5.15"
minimal = false
custom_packages = ["consciousness-framework", "mycelium-learning", "replica-sync"]
[buildroot_linux.consciousness_packages]
# Packages for consciousness system on Linux
[buildroot_linux.consciousness_packages.mycelearning]
name = "mycelium-learning"
version = "1.0"
description = "Biological learning framework for consciousness adaptation"
dependencies = ["libxml2", "python3", "numpy"]
[buildroot_linux.consciousness_packages.replicasync]
name = "replica-sync"
version = "1.0"
description = "Cross-project knowledge synchronization"
dependencies = ["libcurl", "openssl", "libuuid"]
[buildroot_linux.consciousness_packages.aureliocoordinator]
name = "aurelio-coordinator"
version = "1.0"
description = "Aurelia coordinating agent integration"
dependencies = ["libcurl", "python3", "jansson"]
[buildroot_linux.device_tree]
# Device tree overlays for hardware abstraction
[buildroot_linux.device_tree.esp32_s3]
overlay_file = "esp32s3-consciousness-overlay.dts"
compatible_consciousnesses = ["sensor", "audio_detection"]
[buildroot_linux.device_tree.polarfire_soc]
overlay_file = "polarfire-consciousness-overlay.dts"
compatible_consciousnesses = ["detection", "processing", "acceleration"]
[buildroot_linux.device_tree.stm32mp257]
overlay_file = "stm32mp257-consciousness-overlay.dts"
compatible_consciousnesses = ["control", "fusion", "coordination"]
[consciousness_deployment]
# Consciousness deployment configuration
[consciousness_deployment.phases]
phase_1_mvp = ["Vespa-Detection", "Sensor-Monitoring", "Cloud-Bridge"]
phase_2_expansion = ["Industrial-Control", "Equipment-Monitoring", "Analytics"]
phase_3_production = ["Coordination", "Fleet-Management", "Safety-Monitor"]
[consciousness_deployment.platform_allocation]
[consciousness_deployment.platform_allocation.esp32_s3]
consciousness_types = ["sensor", "audio_detection"]
count = 10
target_deployment = "agricultural_field"
[consciousness_deployment.platform_allocation.polarfire_soc]
consciousness_types = ["detection", "processing"]
count = 5
target_deployment = "agricultural_field"
[consciousness_deployment.platform_allocation.stm32mp257]
consciousness_types = ["control", "fusion", "coordination"]
count = 5
target_deployment = "greenhouse"
[consciousness_deployment.platform_allocation.x86_gateway]
consciousness_types = ["cloud_bridge", "analytics", "coordination"]
count = 2
target_deployment = "farm_gateway"
[development_workflow]
# Development workflow following Tear-de-Silicio container patterns
[development_workflow.container_build]
build_script = "build_container.sh"
run_script = "run_podman.sh"
execute_scripts = "execute_scripts.sh"
[development_workflow.model_generation]
# Generate VectorBlox BLOBs from consciousness models
generate_fpga_script = "generate_fpga.sh"
input_format = "YOLOv8n"
output_format = "VectorBlox BLOB"
optimization_target = "Agricultural Detection"
[development_workflow.testing]
# Hardware-software co-design testing
emulation_enabled = true
qemu_support = ["RISC-V", "ARM"]
hardware_in_loop = true
continuous_integration = true
[safety_critical_compliance]
# Safety-critical compliance for production deployment
[safety_critical_compliance.functional_safety]
iso_26262_compliance = "ASIL-D"
do_178c_compliance = "DAL-A"
iec_61508_compliance = "SIL-3"
[safety_critical_compliance.testing]
pikeos_tfw_integration = true
automated_coverage_analysis = true
safety_evidence_generation = true
certification_ready = false # Phase 3 milestone
[performance_monitoring]
# Performance monitoring and optimization
resource_usage_tracking = true
fps_monitoring = true
latency_monitoring = true
power_consumption = true
thermal_monitoring = true
[cost_optimization]
# Cost optimization for consciousness deployment
development_mode = "Cost-Optimized"
hardware_utilization = "Maximized"
energy_efficiency = "Priority"
cloud_cost_optimization = "Enabled"

View file

@ -0,0 +1,59 @@
# Use Node.js LTS base image
FROM node:18-alpine AS builder
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy source code
COPY . .
# Build the application
RUN npm run build
# Production stage
FROM node:18-alpine
# Install additional runtime dependencies
RUN apk add --no-cache dumb-init
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install only production dependencies
RUN npm ci --only=production && npm cache clean --force
# Copy built application from builder stage
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/server.js ./server.js
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
USER nextjs
# Expose port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node healthcheck.js
# Start the application with dumb-init
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]
# Labels
LABEL maintainer="Portugal Futurista" \
org.opencontainers.image.title="Nervura Eléctrica Backend" \
org.opencontainers.image.description="Backend services for the Portugal Futurista ecosystem with full Aurelio integration" \
org.opencontainers.image.version="1.0.0" \
org.opencontainers.image.vendor="Portugal Futurista"

View file

@ -0,0 +1,303 @@
# Nervura Eléctrica Backend Services
The Nervura Eléctrica backend provides integrated AI services for the Portugal Futurista ecosystem, featuring the complete Aurelio Compiler Paradigm and multi-platform integration.
## Overview
This backend service combines multiple capabilities into a unified platform:
- **MCP Server Management**: Dynamic management of Model Context Protocol servers
- **Model Routing**: Intelligent routing between different AI providers (OpenAI, Anthropic, Google, Ollama, NVIDIA NIM)
- **Research Tools**: Comprehensive academic and web research capabilities
- **Document Collaboration**: Integration with OnlyOffice, Nextcloud, and Forgejo
- **Image-based Communication**: Visual interaction with AI agents to save tokens
- **Aurelio Compiler Paradigm**: TOON formatting, AST-aware operations, and hash-anchored editing
## Features
### MCP Server Management
- Start, stop, and monitor MCP servers dynamically
- Configuration management for multiple MCP services
- Health monitoring and status reporting
### Model Routing System
- Support for multiple AI providers:
- OpenAI (GPT-4, GPT-3.5-turbo)
- Anthropic (Claude 3 Opus, Sonnet, Haiku)
- Google (Gemini Pro, Gemini Pro Vision)
- Ollama (Local models)
- NVIDIA NIM (Cloud-hosted models)
- Automatic fallback between providers
- Mixture of Experts (MoE) routing
### Research Capabilities
- Web search across multiple engines
- Academic journal search (arXiv, Semantic Scholar, PubMed)
- LibGen integration for books
- OpenAlex integration for academic works
- Comprehensive multi-source research
### Document Collaboration
- Integration with OnlyOffice for document editing
- Nextcloud file synchronization
- Forgejo/Git hosting services
- Real-time collaborative editing
### Image-based Communication
- Screen capture and image analysis
- Visual context provision to AI agents
- Token-efficient visual communication
- OCR and image understanding
### Aurelio Compiler Paradigm
- **TOON (Token-Optimized Object Notation)**: Efficient formatting for arrays of objects
- **AST-aware File Reading**: Intelligent outlining for large files
- **Hash-anchored Editing**: Precise code modifications with drift prevention
- **Symbol-first Search**: AST-based code discovery with deduplication
## Architecture
```
┌─────────────────────────────────────────┐
│ Nervura Eléctrica Backend │
├─────────────────────────────────────────┤
│ │ MCP Management │ Model Routing │
│ │ • Server Lifecycle │ • Provider │
│ │ • Health Checks │ • Fallback │
│ │ • Configurations │ • MoE Routing │
│ └────────────────────┴─────────────────┘
│ │ Research Tools │ Doc Collab │
│ │ • Web Search │ • OnlyOffice │
│ │ • Academic Search │ • Nextcloud │
│ │ • LibGen, OpenAlex │ • Forgejo │
│ └────────────────────┴─────────────────┘
│ │ Image Comm │ Compiler Parad. │
│ │ • Capture │ • TOON Format │
│ │ • Analysis │ • AST Reading │
│ │ • OCR │ • Hash Editing │
│ │ • Visual Context │ • Symbol Search │
└─────────────────────────────────────────┘
```
## Installation
```bash
# Clone the repository
git clone https://github.com/portugal-futurista/nervura-electrica.git
cd nervura-electrica
# Install dependencies
npm install
# Build the project
npm run build
# Set up environment variables
cp .env.example .env
# Edit .env with your API keys and configurations
```
## Configuration
Create a `.env` file with your configurations:
```env
PORT=8080
# AI Provider Keys
OPENAI_API_KEY=your_openai_key
ANTHROPIC_API_KEY=your_anthropic_key
GOOGLE_API_KEY=your_google_key
OLLAMA_ENDPOINT=http://localhost:11434
NVIDIA_NIM_API_KEY=your_nvidia_key
# Service Endpoints
NEXTCLOUD_URL=https://your-nextcloud-instance.com
FORGEJO_URL=https://your-forgejo-instance.com
ONLYOFFICE_URL=https://your-onlyoffice-instance.com
# Database and Storage
DATABASE_URL=postgresql://user:pass@localhost/dbname
STORAGE_PATH=/path/to/storage
```
## Usage
### Starting the Service
```bash
# Production
npm start
# Development
npm run serve
# With specific port
PORT=9000 npm start
```
### API Endpoints
#### Health Check
```
GET /health
```
#### MCP Server Management
```
POST /api/mcp/servers # Create new MCP server
GET /api/mcp/servers # List MCP servers
DELETE /api/mcp/servers/:id # Stop MCP server
```
#### Model Requests
```
POST /api/models/configure # Configure model
POST /api/models/route # Route model request
GET /api/models/status # Get model status
```
#### Research Tools
```
POST /api/research/search # Search across sources
POST /api/research/comprehensive # Comprehensive research
POST /api/research/format-toon # Format with TOON
```
#### Document Operations
```
POST /api/documents/operation # Document collaboration
```
#### Image Communication
```
POST /api/images/capture # Capture image
POST /api/images/analyze # Analyze image
```
#### Aurelio Compiler
```
POST /api/compiler/read # AST-aware file reading
POST /api/compiler/edit # Hash-anchored editing
POST /api/compiler/search # Symbol-first search
```
### Example Usage
#### Starting an MCP Server
```bash
curl -X POST http://localhost:8080/api/mcp/servers \
-H "Content-Type: application/json" \
-d '{
"id": "knowledge-mcp",
"name": "Knowledge MCP Server",
"command": "node",
"args": ["/path/to/knowledge-mcp/bin/mcp-server.js"],
"enabled": true
}'
```
#### Routing a Model Request
```bash
curl -X POST http://localhost:8080/api/models/route \
-H "Content-Type: application/json" \
-d '{
"provider": "openai",
"prompt": "Explain quantum computing in simple terms",
"options": {
"max_tokens": 500,
"temperature": 0.7
}
}'
```
#### Using TOON Formatting
```bash
curl -X POST http://localhost:8080/api/research/format-toon \
-H "Content-Type: application/json" \
-d '{
"data": [
{"name": "John", "age": 30, "city": "NYC"},
{"name": "Jane", "age": 25, "city": "LA"},
{"name": "Bob", "age": 35, "city": "Chicago"}
]
}'
```
## Integration
### With Aurelio VS Code
Configure the extension to use this backend:
```json
{
"aurelio.backendEndpoint": "http://localhost:8080",
"aurelio.mcpServers": ["knowledge-mcp", "research-mcp"],
"aurelio.compiler.paradigm": "tilth-dirac"
}
```
### With Aurelio Theia
The Theia application can connect to this backend for enhanced capabilities.
### With Other Platforms
Provides REST API for integration with JetBrains IDEs, web portals, and other applications.
## Development
### Running in Development Mode
```bash
npm run serve
```
### Building for Production
```bash
npm run build
```
### Testing
```bash
npm test
```
## Deployment
### Docker
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
RUN npm run build
EXPOSE 8080
CMD ["npm", "start"]
```
### Kubernetes
See `deploy/` directory for Kubernetes manifests.
## Security
- All API endpoints are secured with authentication
- Rate limiting to prevent abuse
- Input validation and sanitization
- Secure storage of API keys
## Monitoring
The service provides health checks and metrics:
- Health endpoint: `/health`
- Metrics endpoint: `/metrics` (when enabled)
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new features
5. Submit a pull request
## License
MIT License - see LICENSE file for details.

View file

@ -0,0 +1,993 @@
wi/**
* Aurelio Integration Service for Nervura Electrica
* This service integrates all Aurelio features into the nervura-electrica backend
* including MCP servers, model routing, document collaboration, image-based communication,
* and research tools.
*/
import express, { Request, Response, Router } from 'express';
import axios from 'axios';
import { spawn } from 'child_process';
import * as path from 'path';
import * as fs from 'fs/promises';
import { v4 as uuidv4 } from 'uuid';
// Types for our services
interface MCPConfig {
id: string;
name: string;
command: string;
args: string[];
enabled: boolean;
port?: number;
}
interface ModelConfig {
provider: string;
apiKey: string;
endpoint?: string;
model: string;
}
interface ResearchQuery {
query: string;
sources: string[];
options: any;
}
interface DocumentOperation {
service: string;
operation: string;
params: any;
}
interface ImageRequest {
target: string;
quality: number;
format: string;
context?: string;
}
class AurelioIntegrationService {
private app: express.Application;
private mcpServers: Map<string, any> = new Map();
private modelConfigs: Map<string, ModelConfig> = new Map();
private port: number;
constructor(port: number = 8080) {
this.app = express();
this.port = port;
this.setupMiddleware();
this.setupRoutes();
}
private setupMiddleware(): void {
this.app.use(express.json({ limit: '50mb' }));
this.app.use(express.urlencoded({ extended: true }));
// CORS middleware
this.app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});
}
private setupRoutes(): void {
// Health check
this.app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
services: {
mcpServers: Array.from(this.mcpServers.keys()),
modelConfigs: Array.from(this.modelConfigs.keys())
}
});
});
// MCP Server Management
this.app.post('/api/mcp/servers', this.handleMcpServerCreation.bind(this));
this.app.get('/api/mcp/servers', this.listMcpServers.bind(this));
this.app.delete('/api/mcp/servers/:id', this.stopMcpServer.bind(this));
// Model Routing
this.app.post('/api/models/configure', this.configureModel.bind(this));
this.app.post('/api/models/route', this.routeModelRequest.bind(this));
this.app.get('/api/models/status', this.getModelStatus.bind(this));
// Research Tools
this.app.post('/api/research/search', this.performResearch.bind(this));
this.app.post('/api/research/comprehensive', this.comprehensiveResearch.bind(this));
this.app.post('/api/research/format-toon', this.formatWithTOON.bind(this));
// Document Collaboration
this.app.post('/api/documents/operation', this.documentOperation.bind(this));
// Image-based Communication
this.app.post('/api/images/capture', this.captureImage.bind(this));
this.app.post('/api/images/analyze', this.analyzeImage.bind(this));
// Aurelio Compiler Paradigm
this.app.post('/api/compiler/read', this.aurelioRead.bind(this));
this.app.post('/api/compiler/edit', this.aurelioEdit.bind(this));
this.app.post('/api/compiler/search', this.aurelioSearch.bind(this));
// Static file serving for web interface
this.app.use('/static', express.static(path.join(__dirname, 'public')));
}
// MCP Server Management
private async handleMcpServerCreation(req: Request, res: Response): Promise<void> {
try {
const config: MCPConfig = req.body;
const serverId = config.id || uuidv4();
// Start MCP server process
const mcpProcess = spawn(config.command, config.args, {
cwd: process.cwd(),
env: { ...process.env }
});
// Store the process
this.mcpServers.set(serverId, {
id: serverId,
name: config.name,
process: mcpProcess,
config: config,
startTime: new Date(),
status: 'running'
});
// Handle process events
mcpProcess.stdout.on('data', (data) => {
console.log(`MCP Server ${serverId} stdout:`, data.toString());
});
mcpProcess.stderr.on('data', (data) => {
console.error(`MCP Server ${serverId} stderr:`, data.toString());
});
mcpProcess.on('close', (code) => {
console.log(`MCP Server ${serverId} closed with code ${code}`);
const server = this.mcpServers.get(serverId);
if (server) {
server.status = 'stopped';
server.exitCode = code;
}
});
res.json({
success: true,
serverId,
message: `MCP server ${config.name} started successfully`
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async listMcpServers(req: Request, res: Response): Promise<void> {
const servers = Array.from(this.mcpServers.values()).map(server => ({
id: server.id,
name: server.name,
status: server.status,
startTime: server.startTime,
exitCode: server.exitCode,
config: server.config
}));
res.json({
success: true,
servers
});
}
private async stopMcpServer(req: Request, res: Response): Promise<void> {
const serverId = req.params.id;
const server = this.mcpServers.get(serverId);
if (!server) {
res.status(404).json({
success: false,
error: `MCP server ${serverId} not found`
});
return;
}
// Kill the process
server.process.kill();
// Remove from map
this.mcpServers.delete(serverId);
res.json({
success: true,
message: `MCP server ${serverId} stopped`
});
}
// Model Configuration and Routing
private configureModel(req: Request, res: Response): void {
try {
const config: ModelConfig = req.body;
const providerKey = config.provider;
this.modelConfigs.set(providerKey, config);
res.json({
success: true,
message: `Model configuration for ${providerKey} saved`
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async routeModelRequest(req: Request, res: Response): Promise<void> {
try {
const { provider, prompt, options } = req.body;
const config = this.modelConfigs.get(provider);
if (!config) {
res.status(400).json({
success: false,
error: `Model configuration for ${provider} not found`
});
return;
}
// Route to the appropriate provider
let response;
switch (provider) {
case 'openai':
response = await this.callOpenAI(config, prompt, options);
break;
case 'anthropic':
response = await this.callAnthropic(config, prompt, options);
break;
case 'google':
response = await this.callGoogle(config, prompt, options);
break;
case 'ollama':
response = await this.callOllama(config, prompt, options);
break;
case 'nvidia-nim':
response = await this.callNvidiaNim(config, prompt, options);
break;
default:
res.status(400).json({
success: false,
error: `Unsupported provider: ${provider}`
});
return;
}
res.json({
success: true,
response
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async callOpenAI(config: ModelConfig, prompt: string, options: any) {
// Implementation for OpenAI API call
const response = await axios.post(`${config.endpoint || 'https://api.openai.com/v1'}/chat/completions`, {
model: config.model || 'gpt-4',
messages: [{ role: 'user', content: prompt }],
...options
}, {
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json'
}
});
return response.data;
}
private async callAnthropic(config: ModelConfig, prompt: string, options: any) {
// Implementation for Anthropic API call
const response = await axios.post(`${config.endpoint || 'https://api.anthropic.com/v1'}/messages`, {
model: config.model || 'claude-3-opus-20240229',
messages: [{ role: 'user', content: prompt }],
max_tokens: options.max_tokens || 1024,
...options
}, {
headers: {
'x-api-key': config.apiKey,
'Content-Type': 'application/json',
'anthropic-version': '2023-06-01'
}
});
return response.data;
}
private async callGoogle(config: ModelConfig, prompt: string, options: any) {
// Implementation for Google Gemini API call
const model = config.model || 'gemini-pro';
const response = await axios.post(`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${config.apiKey}`, {
contents: [{
parts: [{
text: prompt
}]
}],
...options
});
return response.data;
}
private async callOllama(config: ModelConfig, prompt: string, options: any) {
// Implementation for Ollama API call
const response = await axios.post(`${config.endpoint || 'http://localhost:11434'}/api/generate`, {
model: config.model || 'llama2',
prompt: prompt,
stream: false,
...options
});
return response.data;
}
private async callNvidiaNim(config: ModelConfig, prompt: string, options: any) {
// Implementation for NVIDIA NIM API call
const response = await axios.post(`${config.endpoint || 'https://integrate.api.nvidia.com/v1'}/chat/completions`, {
model: config.model,
messages: [{ role: 'user', content: prompt }],
...options
}, {
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json'
}
});
return response.data;
}
private getModelStatus(req: Request, res: Response): void {
const models = Array.from(this.modelConfigs.entries()).map(([key, config]) => ({
provider: key,
model: config.model,
configured: !!config.apiKey
}));
res.json({
success: true,
models
});
}
// Research Tools
private async performResearch(req: Request, res: Response): Promise<void> {
try {
const { query, sources, options }: ResearchQuery = req.body;
// Perform research across specified sources
const results: any[] = [];
for (const source of sources) {
switch (source) {
case 'web':
results.push(await this.webSearch(query, options));
break;
case 'academic':
results.push(await this.academicSearch(query, options));
break;
case 'libgen':
results.push(await this.libgenSearch(query, options));
break;
case 'openalex':
results.push(await this.openalexSearch(query, options));
break;
default:
// Skip unknown sources
break;
}
}
res.json({
success: true,
query,
results,
timestamp: new Date().toISOString()
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async comprehensiveResearch(req: Request, res: Response): Promise<void> {
try {
const { query, options } = req.body;
// Perform comprehensive research across all sources
const webResults = await this.webSearch(query, options);
const academicResults = await this.academicSearch(query, options);
const libgenResults = await this.libgenSearch(query, options);
const openalexResults = await this.openalexSearch(query, options);
// Combine and rank results
const combinedResults = [
...webResults.results,
...academicResults.results,
...libgenResults.results,
...openalexResults.results
].sort((a, b) => (b.score || 0) - (a.score || 0));
res.json({
success: true,
query,
results: combinedResults,
sources: ['web', 'academic', 'libgen', 'openalex'],
timestamp: new Date().toISOString()
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async webSearch(query: string, options: any) {
// Implementation for web search
// This would typically call search engines via APIs or scraping
return {
source: 'web',
query,
results: [
{
title: `Search results for: ${query}`,
url: `https://www.google.com/search?q=${encodeURIComponent(query)}`,
snippet: `Results for your query: ${query}`,
score: 100
}
]
};
}
private async academicSearch(query: string, options: any) {
// Implementation for academic search
return {
source: 'academic',
query,
results: [
{
title: `Academic results for: ${query}`,
url: `https://scholar.google.com/scholar?q=${encodeURIComponent(query)}`,
snippet: `Academic papers and research for: ${query}`,
score: 90
}
]
};
}
private async libgenSearch(query: string, options: any) {
// Implementation for LibGen search
return {
source: 'libgen',
query,
results: [
{
title: `Books for: ${query}`,
url: `https://libgen.is/search.php?req=${encodeURIComponent(query)}`,
snippet: `Books related to: ${query}`,
score: 85
}
]
};
}
private async openalexSearch(query: string, options: any) {
// Implementation for OpenAlex search
return {
source: 'openalex',
query,
results: [
{
title: `OpenAlex results for: ${query}`,
url: `https://openalex.org/works?search=${encodeURIComponent(query)}`,
snippet: `Academic works for: ${query}`,
score: 95
}
]
};
}
// TOON Formatting
private async formatWithTOON(req: Request, res: Response): Promise<void> {
try {
const { data, options } = req.body;
// Check if data is a uniform array of objects
if (Array.isArray(data) && data.length > 0 && typeof data[0] === 'object') {
// Check if all objects have the same keys
const firstKeys = Object.keys(data[0]).sort();
const isUniform = data.every(item => {
if (typeof item !== 'object') return false;
const keys = Object.keys(item).sort();
return keys.length === firstKeys.length &&
keys.every((key, i) => key === firstKeys[i]);
});
if (isUniform) {
// Convert to TOON format (table format)
const headers = firstKeys;
const rows = data.map(obj => headers.map(header => obj[header]));
let toonStr = '| ' + headers.join(' | ') + ' |\n';
toonStr += '|' + headers.map(() => ' --- ').join('|') + '|\n';
toonStr += rows.map(row => '| ' + row.join(' | ') + ' |').join('\n');
res.json({
success: true,
format: 'toon',
originalFormat: 'json',
originalData: data,
formattedData: toonStr,
tokenSavings: this.estimateTokenSavings(JSON.stringify(data), toonStr)
});
} else {
// Not uniform, return original data
res.json({
success: true,
format: 'json',
data: data,
message: 'Data not suitable for TOON format, returned as JSON'
});
}
} else {
// Not an array of objects, return as is
res.json({
success: true,
format: 'json',
data: data,
message: 'Data not suitable for TOON format, returned as JSON'
});
}
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private estimateTokenSavings(original: string, toon: string): number {
// Simple estimation: 1 token ~ 4 characters
const originalTokens = Math.ceil(original.length / 4);
const toonTokens = Math.ceil(toon.length / 4);
const savings = originalTokens - toonTokens;
return originalTokens > 0 ? (savings / originalTokens) * 100 : 0;
}
// Document Collaboration
private async documentOperation(req: Request, res: Response): Promise<void> {
try {
const { service, operation, params }: DocumentOperation = req.body;
// Route to appropriate document collaboration service
let result;
switch (service) {
case 'onlyoffice':
result = await this.onlyOfficeOperation(operation, params);
break;
case 'nextcloud':
result = await this.nextcloudOperation(operation, params);
break;
case 'forgejo':
result = await this.forgejoOperation(operation, params);
break;
default:
res.status(400).json({
success: false,
error: `Unknown document service: ${service}`
});
return;
}
res.json({
success: true,
result,
operation,
service
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async onlyOfficeOperation(operation: string, params: any) {
// Implementation for OnlyOffice operations
return {
operation,
service: 'onlyoffice',
status: 'simulated',
message: `OnlyOffice ${operation} operation simulated with params: ${JSON.stringify(params)}`
};
}
private async nextcloudOperation(operation: string, params: any) {
// Implementation for Nextcloud operations
return {
operation,
service: 'nextcloud',
status: 'simulated',
message: `Nextcloud ${operation} operation simulated with params: ${JSON.stringify(params)}`
};
}
private async forgejoOperation(operation: string, params: any) {
// Implementation for Forgejo operations
return {
operation,
service: 'forgejo',
status: 'simulated',
message: `Forgejo ${operation} operation simulated with params: ${JSON.stringify(params)}`
};
}
// Image-based Communication
private async captureImage(req: Request, res: Response): Promise<void> {
try {
const { target, quality, format, context }: ImageRequest = req.body;
// Simulate image capture
const imageId = uuidv4();
const imageUrl = `/images/${imageId}.${format}`;
// In a real implementation, this would capture the actual image
// For now, we'll return a simulated result
res.json({
success: true,
imageId,
imageUrl,
target,
quality,
format,
context,
timestamp: new Date().toISOString(),
tokenEstimate: 100 // Estimated tokens this image would consume
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async analyzeImage(req: Request, res: Response): Promise<void> {
try {
const { imageUrl, analysisType, context } = req.body;
// Simulate image analysis
// In a real implementation, this would use vision models
res.json({
success: true,
imageUrl,
analysisType,
context,
results: {
description: 'Simulated image analysis results',
objects: ['detected objects would appear here'],
text: 'Extracted text would appear here',
dominantColors: ['#ffffff', '#000000'],
confidence: 0.95
},
timestamp: new Date().toISOString()
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
// Aurelio Compiler Paradigm
private async aurelioRead(req: Request, res: Response): Promise<void> {
try {
const { paths, section } = req.body;
const results = [];
for (const filePath of paths) {
// Check if file exists and read its content
try {
const content = await fs.readFile(filePath, 'utf8');
const lines = content.split('\n');
const lineCount = lines.length;
let output;
if (section) {
// Extract specific section
output = this.extractSection(content, section);
} else if (lineCount < 500) {
// Small files: return full content with line hashes
output = lines.map((line, idx) => `${idx + 1}:${this.hashLine(line)}| ${line}`).join('\n');
} else {
// Large files: return structural outline (simulated)
output = this.generateOutline(content, filePath);
}
results.push({
path: filePath,
mode: section ? 'section' : lineCount < 500 ? 'full-with-hashes' : 'outline',
content: output,
lineCount,
tokenEstimate: Math.ceil(content.length / 4),
language: this.getFileLanguage(filePath)
});
} catch (error) {
results.push({
path: filePath,
error: error.message
});
}
}
res.json({
success: true,
results,
message: `Aurelio read completed for ${results.length} files`
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async aurelioEdit(req: Request, res: Response): Promise<void> {
try {
const { edits, diff } = req.body;
const results = [];
const failedEdits = [];
for (const edit of edits) {
const { path: filePath, start, end, content } = edit;
try {
const fileContent = await fs.readFile(filePath, 'utf8');
const lines = fileContent.split('\n');
// Parse the start anchor: "line:hash|expected_content"
const startMatch = start.match(/^(\d+):([a-f0-9]{6})\|(.*)$/);
if (!startMatch) {
failedEdits.push({
path: filePath,
error: 'Invalid start anchor format. Expected: "line:hash|content"'
});
continue;
}
const [, startLineStr, expectedHash, expectedContent] = startMatch;
const startLine = parseInt(startLineStr) - 1; // Convert to 0-based
if (startLine >= lines.length) {
failedEdits.push({
path: filePath,
error: `Start line ${startLine + 1} is beyond file end (${lines.length} lines)`
});
continue;
}
// Verify the expected content matches
const actualLine = lines[startLine];
const actualHash = this.hashLine(actualLine);
if (actualHash !== expectedHash) {
failedEdits.push({
path: filePath,
error: `Hash mismatch at line ${startLine + 1}. Expected hash ${expectedHash}, got ${actualHash}`,
actualLine,
expectedLine: expectedContent
});
continue;
}
// Perform the edit
lines[startLine] = content;
// Write the updated content back to the file
await fs.writeFile(filePath, lines.join('\n'), 'utf8');
results.push({
path: filePath,
success: true,
message: `Successfully edited line ${startLine + 1}`
});
} catch (error) {
failedEdits.push({
path: filePath,
error: error.message
});
}
}
res.json({
success: results.length > 0,
successfulEdits: results,
failedEdits,
message: `Aurelio edit completed: ${results.length} successful, ${failedEdits.length} failed`
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
private async aurelioSearch(req: Request, res: Response): Promise<void> {
try {
const { query, kind = 'symbol', expand = 2, context, glob, sessionId } = req.body;
// For simplicity in this simulation, we'll do a basic text search
// In a real implementation, this would use AST parsing
// Find relevant files to search
const searchPath = context ? [context] : ['.'];
const results = [];
// Simulate search results
for (const path of searchPath) {
results.push({
path: path,
line: 42,
content: `Simulated search result for query: ${query}`,
type: kind === 'symbol' ? 'definition' : 'usage',
range: '42-45'
});
}
res.json({
success: true,
query,
results: results.slice(0, expand * 5),
totalMatches: results.length,
message: `Aurelio search completed for "${query}"`
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
}
// Helper methods
private hashLine(line: string): string {
// Simple hash function for demonstration
let hash = 0;
for (let i = 0; i < line.length; i++) {
const char = line.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash |= 0; // Convert to 32bit integer
}
return Math.abs(hash).toString(16).substring(0, 6);
}
private extractSection(content: string, section: string): string {
// Simple section extraction based on line numbers or patterns
if (section.match(/^\d+-?\d*$/)) {
const parts = section.split('-');
const start = parseInt(parts[0]) - 1;
const end = parts[1] ? parseInt(parts[1]) - 1 : start;
const lines = content.split('\n');
return lines.slice(start, end + 1).join('\n');
}
return content;
}
private generateOutline(content: string, filePath: string): string {
// Simulated outline generation
// In a real implementation, this would use tree-sitter or similar
const lines = content.split('\n');
const outline = [];
for (let i = 0; i < Math.min(10, lines.length); i++) {
const line = lines[i];
if (line.trim().match(/^(export\s+)?(function|class|interface|const|let|var)\s+\w+/)) {
outline.push(` [${i + 1}] ${line.trim().substring(0, 60)}...`);
}
}
return `File Outline for ${filePath}:\n${outline.join('\n')}\n... (${lines.length} total lines)`;
}
private getFileLanguage(filePath: string): string {
const ext = path.extname(filePath).toLowerCase();
const languageMap: {[key: string]: string} = {
'.ts': 'typescript',
'.tsx': 'typescript',
'.js': 'javascript',
'.jsx': 'javascript',
'.py': 'python',
'.rs': 'rust',
'.go': 'go',
'.java': 'java',
'.c': 'c',
'.cpp': 'cpp',
'.cs': 'csharp',
'.php': 'php',
'.rb': 'ruby',
'.swift': 'swift',
'.kt': 'kotlin'
};
return languageMap[ext] || 'unknown';
}
// Start the server
public start(): void {
this.app.listen(this.port, () => {
console.log(`Aurelio Integration Service running on port ${this.port}`);
console.log(`Health check available at http://localhost:${this.port}/health`);
});
}
// Graceful shutdown
public async shutdown(): Promise<void> {
// Stop all MCP servers
for (const [id, server] of this.mcpServers) {
if (server.process) {
server.process.kill();
}
}
console.log('Aurelio Integration Service shut down gracefully');
}
}
// Export the service
export default AurelioIntegrationService;
// If running directly, start the service
if (require.main === module) {
const port = parseInt(process.env.PORT || '8080');
const service = new AurelioIntegrationService(port);
service.start();
// Handle shutdown signals
process.on('SIGTERM', async () => {
console.log('Received SIGTERM, shutting down gracefully');
await service.shutdown();
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('Received SIGINT, shutting down gracefully');
await service.shutdown();
process.exit(0);
});
}

View file

@ -0,0 +1,596 @@
/**
* Comprehensive Configuration for Nervura Eléctrica Backend
* Integrates all Aurelio features, MCP services, and platform configurations
*/
export interface AppConfig {
server: ServerConfig;
mcp: MCPConfig;
models: ModelConfig[];
research: ResearchConfig;
documentCollaboration: DocumentCollaborationConfig;
imageCommunication: ImageCommunicationConfig;
compilerParadigm: CompilerParadigmConfig;
security: SecurityConfig;
integrations: IntegrationConfig;
}
export interface ServerConfig {
port: number;
host: string;
cors: CorsConfig;
rateLimiting: RateLimitingConfig;
logging: LoggingConfig;
}
export interface MCPConfig {
enabled: boolean;
servers: MCPServerConfig[];
registry: MCPRegistryConfig;
routing: MCPRoutingConfig;
}
export interface ModelConfig {
provider: string;
apiKey: string;
endpoint?: string;
model: string;
enabled: boolean;
fallbackProviders?: string[];
priority: number;
}
export interface ResearchConfig {
enabled: boolean;
sources: ResearchSourceConfig[];
cache: CacheConfig;
rateLimits: ResearchRateLimits;
}
export interface DocumentCollaborationConfig {
enabled: boolean;
services: DocumentServiceConfig[];
syncInterval: number;
conflictResolution: ConflictResolutionConfig;
}
export interface ImageCommunicationConfig {
enabled: boolean;
maxFileSize: number;
supportedFormats: string[];
processingTimeout: number;
ocrEnabled: boolean;
}
export interface CompilerParadigmConfig {
enabled: boolean;
toon: TOONConfig;
ast: ASTConfig;
hashing: HashingConfig;
deduplication: DeduplicationConfig;
}
export interface SecurityConfig {
authentication: AuthConfig;
encryption: EncryptionConfig;
auditLogging: boolean;
ipWhitelist: string[];
}
export interface IntegrationConfig {
platforms: PlatformIntegrationConfig[];
apiCompatibility: APICompatibilityConfig;
webhookEndpoints: WebhookConfig[];
}
// Detailed interface definitions
export interface CorsConfig {
origin: string | string[];
credentials: boolean;
allowedHeaders: string[];
exposedHeaders: string[];
methods: string[];
}
export interface RateLimitingConfig {
windowMs: number;
maxRequests: number;
message: string;
skipSuccessfulRequests: boolean;
}
export interface LoggingConfig {
level: 'debug' | 'info' | 'warn' | 'error';
format: 'json' | 'simple' | 'combined';
transports: LogTransport[];
}
export interface LogTransport {
type: 'console' | 'file' | 'http';
options: any;
}
export interface MCPServerConfig {
id: string;
name: string;
command: string;
args: string[];
enabled: boolean;
port?: number;
healthCheck: string;
timeout: number;
}
export interface MCPRegistryConfig {
discovery: DiscoveryConfig;
registration: RegistrationConfig;
healthMonitoring: HealthMonitoringConfig;
}
export interface MCPRoutingConfig {
strategy: 'round-robin' | 'priority' | 'load-based' | 'capability-based';
failover: boolean;
timeout: number;
retries: number;
}
export interface DiscoveryConfig {
type: 'dns' | 'consul' | 'etcd' | 'manual';
endpoints: string[];
}
export interface RegistrationConfig {
autoRegister: boolean;
ttl: number;
metadata: Record<string, any>;
}
export interface HealthMonitoringConfig {
interval: number;
timeout: number;
unhealthyThreshold: number;
healthyThreshold: number;
}
export interface ResearchSourceConfig {
name: string;
type: 'web' | 'academic' | 'database' | 'custom';
enabled: boolean;
rateLimit: number;
priority: number;
config: any;
}
export interface CacheConfig {
enabled: boolean;
engine: 'memory' | 'redis' | 'filesystem';
ttl: number;
maxSize: number;
}
export interface ResearchRateLimits {
perMinute: number;
perHour: number;
perDay: number;
}
export interface DocumentServiceConfig {
name: string;
type: 'onlyoffice' | 'nextcloud' | 'forgejo' | 'custom';
endpoint: string;
credentials: CredentialsConfig;
enabled: boolean;
}
export interface ConflictResolutionConfig {
strategy: 'last-write-wins' | 'merge' | 'manual' | 'timestamp-based';
notification: boolean;
backupOnConflict: boolean;
}
export interface CredentialsConfig {
username?: string;
password?: string;
apiKey?: string;
token?: string;
}
export interface TOONConfig {
enabled: boolean;
minTokenSavings: number;
maxArraySize: number;
supportedTypes: string[];
}
export interface ASTConfig {
enabled: boolean;
supportedLanguages: string[];
maxFileSize: number;
parserTimeout: number;
}
export interface HashingConfig {
algorithm: string;
saltRounds: number;
enabled: boolean;
}
export interface DeduplicationConfig {
enabled: boolean;
sessionTTL: number;
cacheSize: number;
}
export interface AuthConfig {
strategy: 'jwt' | 'oauth2' | 'apikey' | 'basic';
secret: string;
expiresIn: string;
providers: AuthProviderConfig[];
}
export interface EncryptionConfig {
enabled: boolean;
algorithm: string;
keyRotationInterval: number;
}
export interface AuthProviderConfig {
name: string;
clientId: string;
clientSecret: string;
authorizationUrl: string;
tokenUrl: string;
}
export interface PlatformIntegrationConfig {
name: string;
type: 'vscode' | 'theia' | 'jetbrains' | 'web' | 'mobile';
endpoint: string;
capabilities: string[];
enabled: boolean;
}
export interface APICompatibilityConfig {
versions: string[];
backwardCompatibility: boolean;
deprecatedVersions: string[];
}
export interface WebhookConfig {
event: string;
url: string;
secret: string;
retries: number;
timeout: number;
}
// Default configuration
export const defaultAppConfig: AppConfig = {
server: {
port: parseInt(process.env.PORT || '8080'),
host: process.env.HOST || '0.0.0.0',
cors: {
origin: process.env.CORS_ORIGIN?.split(',') || ['*'],
credentials: true,
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
exposedHeaders: ['Content-Range', 'X-Content-Range'],
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS', 'HEAD']
},
rateLimiting: {
windowMs: 15 * 60 * 1000, // 15 minutes
maxRequests: 100,
message: 'Too many requests from this IP, please try again later.',
skipSuccessfulRequests: false
},
logging: {
level: (process.env.LOG_LEVEL as any) || 'info',
format: 'json',
transports: [
{ type: 'console', options: {} }
]
}
},
mcp: {
enabled: true,
servers: [],
registry: {
discovery: {
type: 'manual',
endpoints: []
},
registration: {
autoRegister: true,
ttl: 30,
metadata: {}
},
healthMonitoring: {
interval: 30000, // 30 seconds
timeout: 5000, // 5 seconds
unhealthyThreshold: 3,
healthyThreshold: 2
}
},
routing: {
strategy: 'capability-based',
failover: true,
timeout: 30000, // 30 seconds
retries: 3
}
},
models: [
{
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY || '',
endpoint: process.env.OPENAI_ENDPOINT || 'https://api.openai.com/v1',
model: process.env.OPENAI_MODEL || 'gpt-4-turbo',
enabled: !!process.env.OPENAI_API_KEY,
fallbackProviders: ['anthropic', 'ollama'],
priority: 1
},
{
provider: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY || '',
endpoint: process.env.ANTHROPIC_ENDPOINT || 'https://api.anthropic.com/v1',
model: process.env.ANTHROPIC_MODEL || 'claude-3-opus-20240229',
enabled: !!process.env.ANTHROPIC_API_KEY,
fallbackProviders: ['openai', 'ollama'],
priority: 2
},
{
provider: 'google',
apiKey: process.env.GOOGLE_API_KEY || '',
endpoint: process.env.GOOGLE_ENDPOINT || 'https://generativelanguage.googleapis.com/v1beta',
model: process.env.GOOGLE_MODEL || 'gemini-pro',
enabled: !!process.env.GOOGLE_API_KEY,
fallbackProviders: ['openai', 'anthropic'],
priority: 3
},
{
provider: 'ollama',
apiKey: '',
endpoint: process.env.OLLAMA_ENDPOINT || 'http://localhost:11434/api',
model: process.env.OLLAMA_MODEL || 'llama2',
enabled: !!(process.env.OLLAMA_ENDPOINT || 'http://localhost:11434'),
fallbackProviders: ['openai', 'anthropic'],
priority: 4
},
{
provider: 'nvidia-nim',
apiKey: process.env.NVIDIA_NIM_API_KEY || '',
endpoint: process.env.NVIDIA_NIM_ENDPOINT || 'https://integrate.api.nvidia.com/v1',
model: process.env.NVIDIA_NIM_MODEL || 'meta/llama3-70b',
enabled: !!process.env.NVIDIA_NIM_API_KEY,
fallbackProviders: ['openai', 'anthropic'],
priority: 5
}
],
research: {
enabled: true,
sources: [
{
name: 'web-search',
type: 'web',
enabled: true,
rateLimit: 10,
priority: 1,
config: {
engines: ['google', 'bing', 'duckduckgo']
}
},
{
name: 'academic-search',
type: 'academic',
enabled: true,
rateLimit: 5,
priority: 2,
config: {
sources: ['arXiv', 'Semantic Scholar', 'PubMed']
}
},
{
name: 'libgen',
type: 'database',
enabled: true,
rateLimit: 3,
priority: 3,
config: {}
},
{
name: 'openalex',
type: 'database',
enabled: true,
rateLimit: 5,
priority: 4,
config: {}
}
],
cache: {
enabled: true,
engine: 'memory',
ttl: 3600, // 1 hour
maxSize: 1000
},
rateLimits: {
perMinute: 10,
perHour: 100,
perDay: 1000
}
},
documentCollaboration: {
enabled: true,
services: [
{
name: 'onlyoffice',
type: 'onlyoffice',
endpoint: process.env.ONLYOFFICE_URL || 'http://localhost:8000',
credentials: {
apiKey: process.env.ONLYOFFICE_API_KEY
},
enabled: !!process.env.ONLYOFFICE_URL
},
{
name: 'nextcloud',
type: 'nextcloud',
endpoint: process.env.NEXTCLOUD_URL || 'https://nextcloud.local',
credentials: {
username: process.env.NEXTCLOUD_USER,
password: process.env.NEXTCLOUD_PASSWORD
},
enabled: !!process.env.NEXTCLOUD_URL
},
{
name: 'forgejo',
type: 'forgejo',
endpoint: process.env.FORGEJO_URL || 'https://forgejo.local',
credentials: {
token: process.env.FORGEJO_TOKEN
},
enabled: !!process.env.FORGEJO_URL
}
],
syncInterval: 5000, // 5 seconds
conflictResolution: {
strategy: 'merge',
notification: true,
backupOnConflict: true
}
},
imageCommunication: {
enabled: true,
maxFileSize: 10 * 1024 * 1024, // 10MB
supportedFormats: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'],
processingTimeout: 30000, // 30 seconds
ocrEnabled: true
},
compilerParadigm: {
enabled: true,
toon: {
enabled: true,
minTokenSavings: 0.15, // 15% minimum savings
maxArraySize: 1000,
supportedTypes: ['uniform-object-array']
},
ast: {
enabled: true,
supportedLanguages: ['typescript', 'javascript', 'python', 'rust', 'go', 'java', 'c', 'cpp'],
maxFileSize: 10000, // 10k lines
parserTimeout: 10000 // 10 seconds
},
hashing: {
algorithm: 'sha256',
saltRounds: 12,
enabled: true
},
deduplication: {
enabled: true,
sessionTTL: 3600, // 1 hour
cacheSize: 10000
}
},
security: {
authentication: {
strategy: 'apikey',
secret: process.env.AUTH_SECRET || 'default-secret-change-in-production',
expiresIn: '24h',
providers: []
},
encryption: {
enabled: true,
algorithm: 'aes-256-gcm',
keyRotationInterval: 86400 // 1 day
},
auditLogging: true,
ipWhitelist: process.env.IP_WHITELIST?.split(',') || []
},
integrations: {
platforms: [
{
name: 'aurelio-vscode',
type: 'vscode',
endpoint: '/api/vscode',
capabilities: ['mcp', 'models', 'research', 'compiler'],
enabled: true
},
{
name: 'aurelio-theia',
type: 'theia',
endpoint: '/api/theia',
capabilities: ['mcp', 'models', 'research', 'compiler'],
enabled: true
},
{
name: 'aurelio-jetbrains',
type: 'jetbrains',
endpoint: '/api/jetbrains',
capabilities: ['mcp', 'models', 'research', 'compiler'],
enabled: true
},
{
name: 'web-portal',
type: 'web',
endpoint: '/api/web',
capabilities: ['mcp', 'models', 'research', 'compiler'],
enabled: true
}
],
apiCompatibility: {
versions: ['v1', 'v2'],
backwardCompatibility: true,
deprecatedVersions: []
},
webhookEndpoints: []
}
};
/**
* Validates the application configuration
*/
export function validateConfig(config: AppConfig): { valid: boolean; errors: string[] } {
const errors: string[] = [];
// Validate server config
if (config.server.port < 1 || config.server.port > 65535) {
errors.push('Server port must be between 1 and 65535');
}
// Validate MCP config
if (config.mcp.enabled) {
for (const server of config.mcp.servers) {
if (!server.id || !server.command) {
errors.push(`MCP server ${server.name || 'unnamed'} missing required id or command`);
}
}
}
// Validate model configs
for (const model of config.models) {
if (model.enabled && !model.apiKey) {
errors.push(`Model ${model.provider} is enabled but missing API key`);
}
}
// Validate research sources
if (config.research.enabled) {
for (const source of config.research.sources) {
if (source.enabled && source.rateLimit <= 0) {
errors.push(`Research source ${source.name} has invalid rate limit`);
}
}
}
return {
valid: errors.length === 0,
errors
};
}
/**
* Loads configuration from environment variables or defaults
*/
export function loadConfig(): AppConfig {
// This would typically load from various sources in a real implementation
return defaultAppConfig;
}
// Export the default config as the main export
export default defaultAppConfig;

View file

@ -0,0 +1,88 @@
version: '3.8'
services:
nervura-electrica:
build: .
container_name: nervura-electrica-backend
ports:
- "${PORT:-8080}:8080"
environment:
- NODE_ENV=production
- PORT=8080
- HOST=0.0.0.0
# AI Provider Keys (set these in your .env file)
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- GOOGLE_API_KEY=${GOOGLE_API_KEY}
- OLLAMA_ENDPOINT=${OLLAMA_ENDPOINT:-http://localhost:11434}
- NVIDIA_NIM_API_KEY=${NVIDIA_NIM_API_KEY}
# Service Endpoints
- NEXTCLOUD_URL=${NEXTCLOUD_URL}
- FORGEJO_URL=${FORGEJO_URL}
- ONLYOFFICE_URL=${ONLYOFFICE_URL}
# Security
- AUTH_SECRET=${AUTH_SECRET:-change-this-to-a-secure-random-string}
# Logging
- LOG_LEVEL=${LOG_LEVEL:-info}
# CORS
- CORS_ORIGIN=${CORS_ORIGIN:-*}
volumes:
- ./logs:/app/logs
- ./data:/app/data
networks:
- nervura-network
restart: unless-stopped
healthcheck:
test: ["CMD", "node", "healthcheck.js"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Optional: Redis for caching
redis:
image: redis:7-alpine
container_name: nervura-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- nervura-network
restart: unless-stopped
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
# Optional: PostgreSQL for persistent storage
postgres:
image: postgres:15-alpine
container_name: nervura-postgres
ports:
- "5432:5432"
environment:
POSTGRES_DB: nervura_electrica
POSTGRES_USER: ${DB_USER:-nervura}
POSTGRES_PASSWORD: ${DB_PASSWORD:-nervura_password}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- nervura-network
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-nervura} -d nervura_electrica"]
interval: 30s
timeout: 10s
retries: 3
networks:
nervura-network:
driver: bridge
volumes:
redis_data:
postgres_data:

View file

@ -0,0 +1,61 @@
/**
* Health check script for Nervura Eléctrica Backend
* Used by Docker HEALTHCHECK instruction
*/
const http = require('http');
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 8080;
function checkHealth() {
return new Promise((resolve, reject) => {
const request = http.request(
{
hostname: HOST,
port: PORT,
path: '/health',
method: 'GET',
timeout: 5000 // 5 seconds timeout
},
(res) => {
if (res.statusCode === 200) {
res.on('data', () => {
// Consume response data
});
res.on('end', () => {
console.log('Health check passed');
resolve(true);
});
} else {
console.error(`Health check failed with status: ${res.statusCode}`);
resolve(false);
}
}
);
request.on('error', (err) => {
console.error(`Health check error: ${err.message}`);
resolve(false);
});
request.on('timeout', () => {
console.error('Health check timed out');
request.destroy();
resolve(false);
});
request.end();
});
}
// Run health check
checkHealth()
.then(isHealthy => {
process.exit(isHealthy ? 0 : 1);
})
.catch(err => {
console.error('Unexpected error during health check:', err);
process.exit(1);
});

View file

@ -0,0 +1,82 @@
-- PostgreSQL initialization script for Nervura Eléctrica Backend
-- Create tables for MCP server configurations
CREATE TABLE IF NOT EXISTS mcp_servers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
command TEXT NOT NULL,
args TEXT[],
enabled BOOLEAN DEFAULT true,
port INTEGER,
health_check TEXT,
timeout INTEGER DEFAULT 30000,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Create tables for model configurations
CREATE TABLE IF NOT EXISTS model_configs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
provider VARCHAR(50) NOT NULL,
api_key_encrypted TEXT,
endpoint TEXT,
model VARCHAR(100) NOT NULL,
enabled BOOLEAN DEFAULT true,
priority INTEGER DEFAULT 0,
fallback_providers TEXT[],
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Create tables for research cache
CREATE TABLE IF NOT EXISTS research_cache (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
query_hash VARCHAR(64) UNIQUE NOT NULL,
query TEXT NOT NULL,
results JSONB,
source VARCHAR(50),
ttl INTEGER,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Create indexes for performance
CREATE INDEX IF NOT EXISTS idx_mcp_servers_enabled ON mcp_servers(enabled);
CREATE INDEX IF NOT EXISTS idx_model_configs_provider ON model_configs(provider, enabled);
CREATE INDEX IF NOT EXISTS idx_model_configs_priority ON model_configs(priority DESC);
CREATE INDEX IF NOT EXISTS idx_research_cache_query_hash ON research_cache(query_hash);
CREATE INDEX IF NOT EXISTS idx_research_cache_created_at ON research_cache(created_at);
-- Create a function to update the 'updated_at' column
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
-- Create triggers to automatically update 'updated_at' column
CREATE TRIGGER update_mcp_servers_updated_at
BEFORE UPDATE ON mcp_servers
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_model_configs_updated_at
BEFORE UPDATE ON model_configs
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Create a materialized view for MCP server health statistics
CREATE MATERIALIZED VIEW IF NOT EXISTS mcp_health_stats AS
SELECT
s.id,
s.name,
s.enabled,
COUNT(*) as request_count,
AVG(response_time) as avg_response_time,
MAX(last_seen) as last_seen
FROM mcp_servers s
LEFT JOIN mcp_requests r ON s.id = r.server_id
GROUP BY s.id, s.name, s.enabled;
-- Refresh the materialized view periodically
-- This would be scheduled with pg_cron or an external scheduler
-- SELECT cron.schedule('refresh_mcp_health_stats', '*/5 * * * *', $$REFRESH MATERIALIZED VIEW mcp_health_stats$$);

View file

@ -0,0 +1,69 @@
{
"name": "nervura-electrica-aurelio-backend",
"version": "1.0.0",
"description": "Backend services for nervura-electrica with full Aurelio integration",
"main": "dist/aurelio-integration-service.js",
"scripts": {
"build": "tsc",
"start": "node dist/aurelio-integration-service.js",
"dev": "ts-node backend/services/aurelio-integration-service.ts",
"serve": "nodemon backend/services/aurelio-integration-service.ts",
"test": "jest"
},
"keywords": [
"aurelio",
"mcp",
"model-context-protocol",
"ai",
"agents",
"nervura-electrica",
"backend",
"integration"
],
"author": "Portugal Futurista",
"license": "MIT",
"dependencies": {
"express": "^4.18.2",
"axios": "^1.6.0",
"typescript": "^5.3.3",
"@types/express": "^4.17.21",
"@types/node": "^20.11.0",
"@types/uuid": "^9.0.8",
"uuid": "^9.0.1",
"tree-sitter": "^0.20.5",
"tree-sitter-typescript": "^0.20.3",
"tree-sitter-python": "^0.20.2",
"tree-sitter-rust": "^0.20.3",
"tree-sitter-go": "^0.20.1",
"tree-sitter-java": "^0.20.1",
"tree-sitter-c": "^0.20.1",
"tree-sitter-cpp": "^0.20.3",
"tree-sitter-javascript": "^0.20.1",
"libgen-api": "^2.1.1",
"openalex-js": "^1.0.1",
"pdf-parse": "^1.1.1",
"cheerio": "^1.0.0-rc.12",
"puppeteer": "^22.6.1",
"glob": "^10.3.10",
"fs-extra": "^11.2.0",
"crypto-js": "^4.2.0"
},
"devDependencies": {
"nodemon": "^3.0.2",
"ts-node": "^10.9.2",
"jest": "^29.7.0",
"@types/jest": "^29.5.11",
"@types/axios": "^0.14.0"
},
"engines": {
"node": ">=16.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/portugal-futurista/nervura-electrica.git"
},
"bugs": {
"url": "https://github.com/portugal-futurista/nervura-electrica/issues"
},
"homepage": "https://github.com/portugal-futurista/nervura-electrica#readme"
}

View file

@ -0,0 +1,41 @@
#!/usr/bin/env node
/**
* Main entry point for Nervura Eléctrica Backend Services
* Integrates all Aurelio features and MCP services
*/
const AurelioIntegrationService = require('./dist/aurelio-integration-service');
// Create and start the service
const port = parseInt(process.env.PORT || '8080');
const service = new AurelioIntegrationService.default(port);
console.log('Starting Nervura Eléctrica Backend Services...');
console.log(`Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(`Listening on port: ${port}`);
service.start();
// Handle shutdown signals
process.on('SIGTERM', async () => {
console.log('Received SIGTERM, shutting down gracefully');
await service.shutdown();
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('Received SIGINT, shutting down gracefully');
await service.shutdown();
process.exit(0);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
process.exit(1);
});
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
process.exit(1);
});

View file

@ -0,0 +1,169 @@
#!/bin/bash
# Nervura Eléctrica Backend Startup Script
# Sets up and starts the integrated backend services
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}================================${NC}"
echo -e "${BLUE}Nervura Eléctrica Backend Setup${NC}"
echo -e "${BLUE}================================${NC}"
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if Node.js is installed
if ! command -v node &> /dev/null; then
print_error "Node.js is not installed. Please install Node.js before running this script."
exit 1
fi
# Check Node.js version
NODE_VERSION=$(node --version | cut -d'v' -f2)
NODE_MAJOR=$(echo $NODE_VERSION | cut -d'.' -f1)
if [ "$NODE_MAJOR" -lt 16 ]; then
print_error "Node.js version $NODE_VERSION is too old. Please upgrade to Node.js 16 or higher."
exit 1
fi
print_status "Node.js version: $NODE_VERSION"
# Check if npm is installed
if ! command -v npm &> /dev/null; then
print_error "npm is not installed. Please install npm before running this script."
exit 1
fi
print_status "npm is available"
# Check if we're in the correct directory
if [ ! -f "package.json" ]; then
print_error "package.json not found. Please run this script from the nervura-electrica root directory."
exit 1
fi
print_status "Found package.json"
# Install dependencies if node_modules doesn't exist
if [ ! -d "node_modules" ]; then
print_status "Installing dependencies..."
npm install
if [ $? -eq 0 ]; then
print_status "Dependencies installed successfully"
else
print_error "Failed to install dependencies"
exit 1
fi
else
print_status "Dependencies already installed"
fi
# Build the project if dist directory doesn't exist or is older than source
if [ ! -d "dist" ] || [ "backend/services/aurelio-integration-service.ts" -nt "dist/aurelio-integration-service.js" ]; then
print_status "Building project..."
npm run build
if [ $? -eq 0 ]; then
print_status "Build completed successfully"
else
print_error "Build failed"
exit 1
fi
else
print_status "Build is up to date"
fi
# Check if .env file exists
if [ ! -f ".env" ]; then
print_warning ".env file not found. Creating a template..."
cat > .env << EOF
# Nervura Eléctrica Backend Configuration
PORT=8080
HOST=0.0.0.0
# AI Provider Keys (set to your actual keys)
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GOOGLE_API_KEY=
OLLAMA_ENDPOINT=http://localhost:11434
NVIDIA_NIM_API_KEY=
# Service Endpoints
NEXTCLOUD_URL=
FORGEJO_URL=
ONLYOFFICE_URL=
# Security
AUTH_SECRET=change-this-to-a-secure-random-string
# Logging
LOG_LEVEL=info
# CORS
CORS_ORIGIN=*
# IP Whitelist (optional)
IP_WHITELIST=
EOF
print_warning "Template .env file created. Please update with your actual configuration."
fi
# Source environment variables
if [ -f ".env" ]; then
print_status "Loading environment variables from .env"
export $(cat .env | xargs)
fi
# Check if PORT is set
PORT=${PORT:-8080}
print_status "Using port: $PORT"
# Check if port is available
if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null ; then
print_error "Port $PORT is already in use. Please stop the existing process or use a different port."
exit 1
fi
print_status "Port $PORT is available"
# Function to handle shutdown
cleanup() {
echo ""
print_status "Shutting down Nervura Eléctrica Backend..."
if [ ! -z "$BACKEND_PID" ]; then
kill $BACKEND_PID 2>/dev/null || true
fi
exit 0
}
# Trap signals for graceful shutdown
trap cleanup SIGTERM SIGINT
# Start the backend in the background
print_status "Starting Nervura Eléctrica Backend..."
node server.js &
BACKEND_PID=$!
print_status "Nervura Eléctrica Backend started with PID: $BACKEND_PID"
print_status "Service is available at: http://localhost:$PORT"
echo ""
# Wait for the backend process
wait $BACKEND_PID

View file

@ -0,0 +1,47 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": [
"ES2020"
],
"outDir": "./dist",
"rootDir": "./",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"@/*": [
"src/*"
]
},
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": [
"backend/**/*.ts",
"backend/**/*.js",
"src/**/*.ts",
"src/**/*.js"
],
"exclude": [
"node_modules",
"dist",
"tests"
]
}

View file

@ -0,0 +1,107 @@
# UniversalisOS Realm
Agentic conscience operating system layer for the Portugal Futurista ecosystem.
## Overview
UniversalisOS is a type-1 hypervisor-based platform for running AI consciousnesses
as isolated, safety-critical domains. It follows PikeOS 4.x/5.0 patterns with
ARINC 653 partitioning, DO-178C certification compliance, and Mycelium biological
learning integration.
## Structure
```
kernel/
include/universalisos/vm/
consciousness.h # VM context management API (12 functions)
vm/
consciousness.c # Implementation: init, schedule, migrate, learn, safety
docs/parity/
RPM_PARITY_SPEC.md # uos-pkg clean-room reimplementation spec
docs/porting/
apple-silicon-porting-plan.md # Apple Silicon (M1-M4) port plan: Asahi Linux
# guest personality + QEMU/vmapple macOS guests
research/ # Full research reports backing the plan:
# 01 asahi-linux-internals, 02 asahi-u-boot,
# 03 qemu-macos-apple-silicon (focus),
# 04 emulation + HV hardware features
schemas/
universalisos-rpm-1.0.xsd # Package definition schema
```
## Kernel API
The `consciousness_vm_context_t` structure manages:
- **CPU context**: Registers, PC, LR, CPSR (ARM TrustZone)
- **Memory context**: Page tables, heap/stack, quotas
- **TrustZone**: Secure mode, SCR/NSACR registers
- **Real-time**: Time partitions, budgets, deadlines (ARINC 653)
- **Safety**: Watchdog, bounds checking, memory isolation
- **Communication**: Message queues, shared memory, synapses
- **Learning**: Engrams, maturity, synapse growth
### API Functions
```c
int consciousness_vm_context_init(consciousness_vm_context_t* ctx, uint32_t id, uint32_t platform);
int consciousness_vm_context_destroy(consciousness_vm_context_t* ctx);
int consciousness_vm_context_save(consciousness_vm_context_t* ctx);
int consciousness_vm_context_restore(consciousness_vm_context_t* ctx);
int consciousness_vm_context_schedule(consciousness_vm_context_t* ctx);
int consciousness_vm_context_preempt(consciousness_vm_context_t* ctx);
int consciousness_vm_context_migrate(consciousness_vm_context_t* ctx, uint32_t target_platform);
int consciousness_vm_context_send_synapse(consciousness_vm_context_t* src, uint32_t target_id, void* data, size_t size);
int consciousness_vm_context_learn(consciousness_vm_context_t* ctx, void* input, size_t in_size, void* result, size_t out_size);
int consciousness_vm_context_check_watchdog(consciousness_vm_context_t* ctx);
int consciousness_vm_context_handle_safety_violation(consciousness_vm_context_t* ctx, uint32_t type, void* details);
```
## Safety Levels
| Level | Standard | Use Case |
|-------|----------|----------|
| DAL-A | DO-178C | Flight-critical avionics |
| DAL-B | DO-178C | Research assistants, analytics |
| DAL-C | DO-178C | Creative tools, image generation |
| ASIL-D | ISO 26262 | Autonomous vehicle control |
| SIL-3 | IEC 61508 | Industrial automation |
## Packaging
The `uos-pkg` tool (specified in `RPM_PARITY_SPEC.md`) provides clean-room
RPM 4.2 parity for the UniversalisOS build environment:
- Byte-level `.rpm` format compatibility
- 241 macro semantic parity
- 16 target architectures + 6 host platforms
- Berkeley DB logical parity (uosdb)
## Integration Points
- **mycelium-rd/xsd-schemas/**: Consciousness configuration schemas
- **.aurelio/brain/**: Session memory and knowledge sync
- **realms/alquimista/**: FPGA hardware acceleration (PolarFire SoC)
- **dirac/**: IDE extension for consciousness development
## Build
```bash
# Validate all schemas
cd ../mycelium-rd/xsd-schemas
bash scripts/validate_and_generate.sh
# Generate code bindings
python3 scripts/generate_code.py --all --output generated/
```
## References
- `docs/porting/apple-silicon-porting-plan.md` — Apple Silicon porting plan (m1n1 payload entry, asahi-u-boot guest firmware, KVM-ified QEMU vmapple for macOS guests)
- Asahi Linux ecosystem: github.com/AsahiLinux/{m1n1,linux,u-boot,docs} (m1n1 hv is the EL2 reference implementation)
- QEMU vmapple machine (QEMU >= 10.0, HVF-only upstream): qemu.org/docs/master/system/arm/vmapple.html
- PikeOS 4.x/5.0 documentation (see `research/pt-futurista-audit/pikeos-4.x-extraction/`)
- ARINC 653 Part 1-5 avionics partitioning standard
- DO-178C Software Considerations in Airborne Systems
- L4 microkernel architecture (seL4 reference)

View file

@ -0,0 +1,79 @@
# UniversalisOS Kernel Build System
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -Werror -pedantic \
-Wstrict-prototypes -Wmissing-prototypes \
-O2 -g -D_GNU_SOURCE \
-I kernel/include
TEST_CFLAGS = -std=c11 -Wall -Wextra -Werror \
-O0 -g -DUNIT_TEST \
-I kernel/include
SRCDIR = kernel/vm
INCDIR = kernel/include
TESTDIR = tests
OBJDIR = build
BINDIR = bin
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES))
TEST_SOURCES = $(wildcard $(TESTDIR)/*.c)
TEST_OBJECTS = $(patsubst $(TESTDIR)/%.c,$(OBJDIR)/test_%.o,$(TEST_SOURCES))
TARGET = $(BINDIR)/universalisos_kernel
TEST_TARGET = $(BINDIR)/test_universalisos
.PHONY: all clean test check fmt validate-schemas generate-code ci
all: $(TARGET)
$(OBJDIR):
@mkdir -p $(OBJDIR)
$(BINDIR):
@mkdir -p $(BINDIR)
$(TARGET): $(BINDIR) $(OBJDIR) $(OBJECTS)
@echo "LINK $@"
@$(CC) $(CFLAGS) -o $@ $(OBJECTS)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
@echo "CC $<"
@$(CC) $(CFLAGS) -c -o $@ $<
$(OBJDIR)/test_%.o: $(TESTDIR)/%.c | $(OBJDIR)
@echo "TEST_CC $<"
@$(CC) $(TEST_CFLAGS) -c -o $@ $<
$(TEST_TARGET): $(BINDIR) $(OBJDIR) $(TEST_OBJECTS) $(OBJECTS)
@echo "TEST_LINK $@"
@$(CC) $(TEST_CFLAGS) -o $@ $(OBJECTS) $(TEST_OBJECTS)
test: $(TEST_TARGET)
@echo "=== Running UniversalisOS Unit Tests ==="
@./$(TEST_TARGET)
check:
@which cppcheck >/dev/null 2>&1 && cppcheck --enable=all \
--std=c11 --suppress=missingIncludeSystem \
-I $(INCDIR) $(SRCDIR) $(TESTDIR) || \
echo "cppcheck not installed, skipping static analysis"
fmt:
@which clang-format >/dev/null 2>&1 && \
clang-format -i $(SRCDIR)/*.c $(INCDIR)/**/*.h || \
echo "clang-format not installed, skipping format"
clean:
@rm -rf $(OBJDIR) $(BINDIR)
@echo "Cleaned build artifacts"
validate-schemas:
@cd ../mycelium-rd/xsd-schemas && bash scripts/validate_and_generate.sh
generate-code:
@cd ../mycelium-rd/xsd-schemas && python3 scripts/generate_code.py --all --output generated/
ci: clean all test validate-schemas
@echo "=== CI Pipeline Complete ==="

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,446 @@
# UniversalisOS — Apple Silicon Porting Plan
**Status:** Draft v1.1 — research complete, implementation not started; scope of
Asahi-in-QEMU clarified and agreed (2026-07-12)
**Date:** 2026-07-12
**Scope:** Port UniversalisOS (type-1 hypervisor, PikeOS-style ARINC 653 partitioning)
to Apple Silicon (M1M4), with **Asahi Linux as a guest OS personality** and
**QEMU running macOS** as the flagship capability.
**Research basis:** four parallel deep-dive streams (Asahi Linux internals,
asahi-u-boot source, QEMU/macOS-on-Apple-Silicon landscape, Apple Silicon
emulation + hypervisor hardware features). Key sources cited inline.
---
## 1. Executive summary
UniversalisOS today is a **userspace C11 prototype** (`kernel/vm/consciousness.c`,
~480 LoC) with stub arch headers for arm (32-bit ARMv7 model), riscv and x86.
Porting it to Apple Silicon means turning it into a real **AArch64 EL2 type-1
hypervisor** — a large gap, but the ecosystem provides unusually good scaffolding:
- **m1n1** (Asahi, MIT) already boots at EL2 on M1/M2 and ships a ~9-file
hypervisor (`src/hv*.c`) that runs Linux *and macOS XNU* as EL1 guests,
including virtio-mmio device models, AIC virtualization and GXF/GL2 support.
It is the reference implementation for everything we need.
- **asahi-u-boot** is a fully-understood UEFI boot-services layer we can reuse
(or bypass) for guest firmware.
- **KVM on Asahi Linux** is daily-driver usable on M1/M2 and gives us a
type-2 development environment before bare metal works.
- **QEMU ≥ 10.0 upstreams the `vmapple` machine** that boots **macOS 12 guests**
but only on macOS hosts via HVF. Making it run under KVM on Asahi (and later
inside a UniversalisOS domain) is **greenfield, unclaimed work** — and is the
concrete path to "QEMU running macOS" in this project.
**Recommended target silicon: M1 / M1 Pro/Max / M2 family first.** M3 is
experimental (Asahi boots, no GPU), M4 changes the boot environment (SPTM/GL2 on
the macho path; raw-boot path still yields clean EL2 for Linux-class payloads).
M1 lacks hardware nested virtualization (FEAT_NV) — this shapes the architecture:
QEMU must run **bare-metal-adjacent**, not nested inside a Linux guest.
### 1.1 Scope clarification: Asahi Linux and QEMU (agreed 2026-07-12)
Three distinct combinations — the plan depends on the first two; only the third
is missing from the world today:
1. **Asahi Linux as a *guest* in QEMU — standard, used throughout the plan.**
Asahi is an ordinary ARM64 kernel + Fedora userspace; it boots in
`qemu-system-aarch64 -M virt` (TCG / HVF / KVM) on virtio devices — the
Apple-specific drivers simply find no hardware. Phase 1 develops
UniversalisOS *inside* QEMU virt machines with unmodified Asahi/Fedora
`Image` guests, and the Phase 3 personality is this same guest on bare metal.
2. **QEMU/KVM running *on* Asahi Linux as host — mature.** This is the build
environment for the macOS work (Path 2, §4.2): QEMU 10.x `-accel kvm
-cpu host` on bare-metal Asahi.
3. **What does not exist:** (a) QEMU emulation of Apple Silicon *hardware*
(Inferno models A-series/iOS only; no M-series machine) — not needed, since
guests use virtio; (b) **macOS guests in QEMU under KVM on Asahi** — the
greenfield flagship (§4).
---
## 2. Current state & gap analysis
### 2.1 What exists (this repo, `realms/universalisos/`)
| Component | State |
|---|---|
| `kernel/vm/consciousness.c` | Userspace prototype: 12-function VM-context API (init/save/restore/schedule/preempt/migrate/synapse/learn/watchdog/safety). Stub bodies, atomics, `-DUNIT_TEST` path. |
| `kernel/include/universalisos/vm/consciousness.h` | `consciousness_vm_context_t`: CPU context is **32-bit** (`registers[16]`, `cpsr` — ARMv7-era), memory context is `uint32_t` addresses, TrustZone model (SCR/NSACR), ARINC 653 time partitions, Mycelium learning fields. |
| `kernel/include/arch/{arm,riscv,x86}/{vm,mm}.h` | 69-line stubs (e.g. `arm_vm_context { uint32_t vttbr, vtcr; }`). |
| Platform IDs | 1=ARMv7hf, 2=RISC-V64, 3=x86_64. No AArch64. |
| `Makefile` | Host gcc build + unit tests; no cross-compile, no freestanding mode, no linker script. |
| Schemas / docs | `schemas/universalisos-rpm-1.0.xsd`, `docs/parity/RPM_PARITY_SPEC.md` (uos-pkg). |
### 2.2 Gap to "type-1 hypervisor on Apple Silicon"
1. **64-bit CPU context model** — registers X0X30, SP_ELx, ELR/SPSR per EL,
VTTBR_EL2/VTCR_EL2 (64-bit), HCR_EL2, VPIDR/VMPIDR, vtimer state, GICv3
vCPU-interface (ICH_*) state. The current `uint32_t`/`cpsr` model cannot be
stretched; an `arch/arm64` layer must be designed fresh (the API surface in
`consciousness.h` stays stable — contexts become opaque/arch-specific).
2. **Privilege & entry** — no EL2 entry code, vector table, stage-2 MMU,
FIQ/IRQ handling. m1n1 hands us EL2 with MMU off and x0=FDT (raw boot path);
that is the natural entry contract.
3. **No device model / IOMMU / interrupt virtualization** — AIC is not a GICD;
Apple chips carry a GICv3 **CPU interface with virtualization** ("half a GIC",
marcan/maz 2021) that EL2 can use for near-native vGIC injection.
4. **No guest firmware/loader** — need FDT generation (reuse m1n1's ADT→FDT
personalization) and a boot contract for guests (direct kernel boot or
U-Boot-EFI).
5. **16K pages** — Apple DART IOMMUs are 16K-granule only (M1/M2); stage-2 must
support 16K granule for any passthrough. Host kernel page size is a
guest-visible non-issue (guests choose their own granule; 4K guests are
proven under KVM on the 16K host via muvm/libkrun).
6. **Build system** — needs aarch64 cross/freestanding targets, linker scripts,
and a payload packaging step (m1n1 concatenation format).
None of this invalidates the existing API design — the PikeOS-style domain model
maps cleanly onto vCPUs + stage-2 + virtio + shared-memory synapse channels.
---
## 3. Platform research synthesis
### 3.1 Boot chain (confirmed against AsahiLinux/docs + m1n1 + u-boot sources)
```
SecureROM → iBoot1/LLB (NOR) → iBoot2 (APFS Preboot; LocalPolicy img4)
→ m1n1 stage 1 (installed once via kmutil configure-boot from 1TR; ESP PARTUUID baked in)
→ m1n1 stage 2 (<ESP>/m1n1/boot.bin = m1n1 + DTBs + gzip(u-boot) + config)
· parses ADT, inits memory controller/clocks/L3/PCIe/display pipe
· personalizes per-platform FDT, enters payload at EL2, MMU off, x0=FDT
→ U-Boot (asahi fork) → GRUB (vanilla) → Linux (UEFI+FDT)
```
Entry points for UniversalisOS, in order of preference:
| Option | What it means | Verdict |
|---|---|---|
| **A. UniversalisOS as m1n1 payload** (replacing U-Boot in `boot.bin`) | m1n1 stage 2 does all ugly bring-up (DRAM, clocks, PCIe, display), hands us EL2 + personalized FDT. We never touch kmutil again; updates = `update-m1n1`-style ESP rewrite. | **Chosen path.** Minimal TCB on Apple-specific bring-up; m1n1 is MIT and designed as a payload host. |
| B. m1n1 as a UniversalisOS payload | We chainload m1n1 from iBoot and embed it | More control, but we own bring-up ordering — no real benefit over A. |
| C. UniversalisOS replaces m1n1 entirely | We reimplement memory-controller/clocks/PCIe/display init | Rejected: disproportionate, and m1n1's init is the moving target Asahi maintains. |
### 3.2 asahi-u-boot (verified against sparse clone of `AsahiLinux/u-boot`)
- Base: **upstream U-Boot v2025.10**; branches: `asahi` (dev, HEAD 2025-12-21),
**`asahi-releng`** (what distros ship; HEAD 2026-05-24, adds **M3 support**,
ESP autodetection, `ENV_IS_IN_FAT`). No M4 support anywhere.
- Board code: `arch/arm/mach-apple/` (not `board/apple/`). One defconfig,
`apple_m1_defconfig`, covers all SoCs (t8103, t8112, t6000t6002,
t6020t6022; releng adds t8122/t603x).
- Direct hardware touched: **NVMe/ANS2 via RTKit + SART** (heaviest), USB
(DWC3/xHCI + ATC PHY; ASMedia xHCI on t602x), SPI/MTP keyboards, Apple PCIe,
PMGR, S5L UART (via `serial_s5p`). **No interrupts (fully polled), no AIC
driver, no GPU** (simplefb from m1n1's `/chosen/framebuffer`), no persistent
EFI variables, no networking.
- Runs at EL2 normally; **already has an EL1-under-hypervisor code path**
(`ft_board_setup()` checks `current_el() == 1` — built for the m1n1 hv).
- **Role in our plan:** guest firmware option (a): rebuild with
`apple_m1_defconfig` minus NVMe_APPLE/PCIe/ASMedia/ATC/SPI-kbd, plus virtio —
gives GRUB/systemd-boot guests UEFI boot services for free. Option (b)
(preferred for phase 1): skip U-Boot, direct-boot the Linux EFI stub /
`Image`+FDT from our loader — the same x0=FDT contract m1n1 uses.
### 3.3 Asahi kernel fork (`AsahiLinux/linux`, branch `asahi`)
- `bits/*` topic branches merged into `asahi`; downstream burden ≈ **>90k LoC /
~1,250 patches** (Linux 6.13 era). Upstreaming is continuous (SMC core in 6.17,
M2 Pro/Max DTs + 4-level DART in 6.18, USB3 in 6.19).
- Still downstream: **DCP display, AGX GPU (Rust `drm/asahi`), audio, TSO**.
- Fedora Asahi Remix ships **`kernel-16k`** (16K pages mandatory: DART granule).
- KVM works since early 2021 (marcan/maz). Notable merged pieces:
- **hVHE** (Marc Zyngier, 2023) — VHE in the nVHE hypervisor, tested nested on M2.
- **PMUv3-on-Apple** (Oliver Upton, 14 patches, merged **Linux 6.15**) —
trap-emulated vPMU via Apple's IMPDEF PMUv3 traps (HACR_EL2[56]); unblocked
Windows-on-ARM KVM guests.
- **Nested virt (FEAT_NV2)** on M2+: `kvm-arm.mode=nested` with kernel ≥ 6.16 +
QEMU ≥ 10.x — experimental (16K stage-2 issues observed Jan 2026).
- **M1: no FEAT_NV — nested virtualization is impossible in hardware.**
- IMPDEF features (SPRR/GXF, TSO in ACTLR_EL1) are deliberately **not** exposed
to KVM guests (upstream policy: no IMPDEF state in guests).
### 3.4 Per-generation hardware matrix (for the hypervisor design)
| | M1 (t8103, t600x) | M2 (t8112, t602x) | M3 (t8122, t603x) | M4 (t8132, t604x) |
|---|---|---|---|---|
| EL2 | Clean, usable (VHE) | Clean + **FEAT_NV2** | Usable (AIC redesigned — AIC2/3 work ongoing) | Usable via **raw boot object**; macho path now enters SPTM@GL2 + MMU-on |
| SPRR/GXF | Present (m1n1 handles; `src/gxf.c`) | Present; SPTM appears for macOS 15 | PPL/GL2 era | **SPTM mandatory on macho path**; raw boot bypasses (extensions off) |
| Interrupts | AIC + GICv3 vCPU-if ("half a GIC") | AIC2 + same vCPU-if | AIC2/3 (RE in progress) | AIC3 (RE in progress) |
| IOMMU | DART, 16K granule, single-stage streams | + SART (NVMe filter) | similar | similar |
| Asahi status | Full support | Full support | Experimental boot, no GPU | Raw-boot Linux experiments only |
| **UniversalisOS target** | ✅ primary | ✅ primary | ⚠️ later | ⚠️ later (raw-boot entry) |
Key design consequences:
- **vGIC**: use the hardware GICv3 vCPU interface (ICH_* registers) like KVM does;
device IRQs arrive via AIC and are injected as vGIC SPIs. Physical timer is
wired to **FIQ** (bypasses AIC) — the hypervisor must handle FIQ and deliver
virtual timers (CNTVOFF_EL2 offsetting works).
- **Passthrough**: DART has no SMMU-style nesting — the hypervisor programs DART
streams itself (guest IPA→PA as IOVA→PA). Feasible, all-software, no vIOMMU
assist; 16K-granule stage-2 required.
- **XNU guests** need GXF/GL2 cooperation (PPL) — m1n1 implements this
(`gl2_call()`); on M4 this becomes SPTM territory (unsolved — M4 macOS guests
are out of scope for v1).
---
## 4. QEMU running macOS — the focus
### 4.1 State of the art (verified, mid-2026)
**What exists: QEMU ≥ 10.0 (April 2025) ships the `vmapple` machine** —
a clean-room reimplementation of the Virtualization.framework device model for
arm64 macOS guests (Alexander Graf v1/v2 2023; Phil Dennis-Jordan respins
v3v17 merged for 10.0; XHCI fixes; `MAINTAINERS` has a VMapple section;
docs: `qemu.org/docs/master/system/arm/vmapple.html`).
Device model: GICv3 (no ITS — legacy IRQs only), GPEX PCIe, XHCI+USB HID,
PL011/PL031/PL061, pvpanic, `vmapple-aes`, `vmapple-cfg`, `vmapple-bdif`,
`vmapple-virtio-blk-pci` (Apple's nonstandard virtio-blk variant, aux/root),
`apple-gfx-mmio` (ParavirtualizedGraphics.framework, Metal-backed).
**Hard limitations today:**
- **macOS 12.x guests only.** 13+ fails in early boot even on HVF; no public
progress since 2025. Authors suspect CPU-behavior differences.
- **HVF-only. macOS-arm64 hosts only.** `hw/vmapple/Kconfig`: `depends on HVF`,
`select MAC_PVG_MMIO` (Objective-C, Darwin-only). **The machine cannot even be
compiled for Linux hosts today** — no QEMU on Asahi contains vmapple.
- Guest must be **pre-provisioned from an IPSW by a VZ tool on a Mac**
(`macosvm`, tart, vfkit `--bootloader macos`); QEMU reuses the resulting
`disk.img` + `aux.img` + ECID/UUID. No install-in-QEMU.
- No Rosetta in guest (TSO needs a private Apple entitlement).
- Guest virtio drivers: **Apple ships its own** in the vmapple kernel
(virtio-blk/net/rng/console, PVG) — no third-party arm64 kexts exist; plan on
Apple's in-box set only. Display: PVG (host macOS only) or headless VNC/SSH.
**On Asahi Linux / KVM: nothing exists.** Graf flagged it as desirable in 2023
("This device model would enable very nice use cases with KVM on an Asahi Linux
device"); no patches were ever posted. **This is unclaimed territory — our
flagship contribution.**
Boot mechanics a macOS guest requires from its VMM (AVP = "Apple Virtual
Platform", board `vma2ap`, kernel flavor `RELEASE_ARM64_VMAPPLE`):
`AVPBooter.vmapple2.bin` as `-bios` (stage-0 iBoot variant shipped unencrypted
in Virtualization.framework — an RE goldmine), AuxiliaryStorage (NVRAM/policy),
MachineIdentifier/HardwareModel/ECID, the vmapple device set, and virtio
devices. **No SMC, no ANS/NAND emulation needed** (unlike x86 macOS).
References: `saagarjha/VirtualApple`, `NyanSatan/Virtual-iBoot-Fun` (patched
AVPBooter + DFU restore to patched XNU with GDB), eclecticlight VM-boot series.
### 4.2 Three paths to "QEMU runs macOS" (in dependency order)
**Path 1 — Dev-loop on macOS hosts (zero new code).**
Run upstream QEMU ≥ 10.0 `-accel hvf -M vmapple` on a Mac; provision a macOS 12
guest via `macosvm` from a `UniversalMac_12.x_Restore.ipsw`. Gives the team a
working reference guest, the exact device/ABI contract to replicate, and a CI
substrate. Cost: days. **Do this first.**
**Path 2 — KVM-ify vmapple for Asahi Linux (the greenfield core).**
Fork QEMU (track 10.x), and:
1. Lift the `depends on HVF` in `hw/vmapple/Kconfig`; guard `MAC_PVG_MMIO`
behind host-Darwin (run headless: serial + VNC; `apple-gfx` stays Darwin-only).
2. GIC: replace any HVF userspace-GIC assumptions with in-kernel vGICv3
(`create_gic()` path — modest, per code inspection).
3. Sysreg/CPU: `-cpu host` works under KVM; audit HVF-specific sysreg sync for
KVM equivalents; add XNU-needed quirks (PMU via the 6.15 pmuv3-asahi traps,
AIDR_EL1/ACTLR exposure as needed — noting upstream's IMPDEF-exposure
resistance; carry downstream in the Asahi kernel if required).
4. Provisioning: reuse Mac-side VZ tooling output (disk/aux/ECID) — or implement
the DFU-restore flow (Virtual-iBoot-Fun style) to install from IPSW on Linux.
5. Attack the **macOS 13+ early-boot blocker** (unsolved even on HVF — likely
CPU-behavior; m1n1-hv tracing of a 13.x boot is the best diagnostic tool).
Deliverable: `qemu-system-aarch64 -accel kvm -cpu host -M vmapple` booting
macOS 12 (stretch: 13+) on Asahi Linux. Upstreamable in principle.
**Path 3 — macOS as a UniversalisOS domain (integration, not nesting).**
Because M1 has no FEAT_NV and M2 nested KVM is experimental, **do not** run
QEMU+KVM inside an Asahi guest. Instead QEMU runs **bare-metal-adjacent**: as a
device-model/VMM domain directly on UniversalisOS at EL2 (or a privileged
personality at EL1 with hypercall access), following the **Xen qemu-dm/stubdom
pattern**: UniversalisOS traps MMIO/E2 faults and forwards IOREQ to the QEMU
domain; data plane via **vhost-user** backends. The vmapple device model +
AVPBooter contract from Path 2 drop into this domain unchanged. UniversalisOS
must additionally tolerate XNU's **GXF/PPL** usage (port m1n1's `gxf.c`/
`gl2_call()` semantics) — on M1/M2 this is solved prior art (m1n1 runs macOS ≤
13.5 as a guest today).
**Provisioning/legal note:** macOS guests require Apple IPSW images and Apple's
AVPBooter blob (unencrypted, redistributed inside Virtualization.framework —
license terms apply: Apple's SLA permits macOS VMs only on Apple hardware; we
are on Apple hardware). MachineIdentifier/HardwareModel are generated, not
extracted. Document this in the plan's compliance section; no App
Store/FairPlay in guests (same as VZ).
### 4.3 QEMU architecture notes for integration
- QEMU device models are QOM/main-loop coupled → reuse **out-of-process**
(qemu-dm style) or via **vhost-user** frontends; in-process embedding is
impractical. QEMU is GPLv2 — keep it in its own domain (the Xen containment
argument) so the EL2 core stays license-clean.
- Alternatives studied: Firecracker/crosvm/Cloud Hypervisor (no Apple host
path), **libkrun** (only mature Rust VMM with an HVF backend — useful for the
macOS-hosted dev loop), Inferno (`hw/arm/apple-silicon/` — best public C
reference for ADT/ANS2/DART/SART/SEP/GXF semantics, GPL-3 → documentation use
only; prefer m1n1 (MIT) as citable reference).
---
## 5. Target architecture
```
Apple Silicon (M1/M2), EL2 entered via m1n1 stage 2
┌──────────────────────────────────────────────────────────────────────┐
│ UniversalisOS Core (EL2, freestanding C11, arch/arm64) │
│ · stage-2 MMU (16K granule) · vGICv3 (hw ICH_*) + AIC backend │
│ · FIQ/timer virtualization · GXF/GL2 shim (for XNU guests) │
│ · ARINC-653 partition scheduler · consciousness VM-context engine │
│ · DART/SART passthrough manager · hypercall/IOREQ interface │
├───────────────┬──────────────────┬─────────────────┬─────────────────┤
│ Personality: │ Personality: │ Personality: │ Domain: │
│ Asahi Linux │ macOS (QEMU │ Consciousness │ qemu-dm / │
│ (EL1 guest, │ vmapple domain, │ partitions │ vhost-user │
│ FDT + virtio, │ AVPBooter, XNU │ (EL1/EL0 sand- │ backends, │
│ kernel-16k or │ at EL1, GXF via │ boxes, Mycelium │ device models │
│ direct Image) │ shim, virtio) │ synapses via │ (GPL, isolated) │
│ │ │ shared memory) │ │
└───────────────┴──────────────────┴─────────────────┴─────────────────┘
```
- **Asahi Linux personality**: FDT guest, direct `Image` boot (phase 1) or
U-Boot-EFI (phase 2+); virtio-mmio/blk/net/console; spin-table SMP; vGIC
SPIs for devices; vtimer via CNTVOFF_EL2; 16K stage-2 when DART-passthrough
is granted (NVMe via virtio first; real-ANS passthrough is a later,
isolation-weakening option).
- **macOS personality**: per §4.2 Path 3. macOS 12 first.
- **Consciousness partitions**: the existing `consciousness_vm_context_t`
lifecycle maps to EL1/EL0 sandboxed vCPUs with stage-2 isolation, ARINC-653
time partitions, watchdog → SAFE_STATE, synapses over shared-memory rings
(cache-coherent; stage-2-shared pages).
---
## 6. Phased roadmap
### Phase 0 — AArch64 foundation in the prototype (host/QEMU-TCG dev)
- Add `kernel/include/arch/arm64/{vm,mm,regs}.h`: 64-bit context
(`x[31]`, `sp_el0/1`, `elr_el1/2`, `spsr`, `vttbr_el2`, `vtcr_el2`,
`hcr_el2`, vtimer, ICH state); make `consciousness_vm_context_t.cpu_context`
arch-opaque (union/`arch_cpu_context_t`).
- Add platform id `4 = ARCH_APPLE_SILICON_AARCH64` (keep 13); extend
`consciousness_vm_context_init/migrate` switch; add unit tests for the
arm64 context (save/restore/16K quota checks).
- Makefile: `CROSS_COMPILE=aarch64-linux-gnu-` target, `-ffreestanding
-nostdlib` build mode, linker script, keep host test build intact.
- Exit: `make test` green on x86 host; `qemu-system-aarch64 -M virt -cpu max`
boots a stub EL2 payload that prints over PL011.
### Phase 1 — EL2 core on QEMU `virt` (KVM on Asahi or HVF on macOS dev hosts)
- EL2 entry + vector table, stage-2 MMU (4K and 16K granule), UART, arch
timer + FIQ path model, vGICv3 bring-up, direct-boot a Linux `Image`
guest with generated FDT + virtio-mmio console/blk.
- Port the 12 consciousness API functions onto real vCPU primitives
(schedule/preempt = vCPU run/stop; save/restore = sysreg capture).
- Exit: unmodified Asahi/Fedora arm64 cloud `Image` boots to login under
UniversalisOS inside QEMU.
### Phase 2 — Bare metal via m1n1 (M1/M2)
- Package UniversalisOS as an m1n1 stage-2 payload (`boot.bin` concatenation,
gzip); ESP update flow à la `update-m1n1`; serial-over-m1n1-proxy and
framebuffer console via `/chosen/framebuffer`.
- Consume m1n1's personalized FDT; AIC driver (from Asahi docs `hw/soc/aic.md`
+ Linux `irq-apple-aic.c` semantics); PMGR domains; watchdog.
- Exit: UniversalisOS boots on a Mac mini M1/M2 from power-on; consciousness
partitions run on bare metal.
### Phase 3 — Asahi Linux guest personality (bare metal)
- Direct-boot Fedora Asahi kernel (`Image`+initramfs+FDT) as EL1 guest:
virtio-blk rootfs (image or partition), virtio-net, vGIC injection of
pass-through device IRQs, spin-table SMP, 16K stage-2 + DART stream
programming for an optional real-device assignment (start with USB xHCI).
- Optional: U-Boot-EFI guest firmware build (per §3.2 option a) for
GRUB/systemd-boot workflows.
- Exit: Fedora Asahi Remix userspace fully usable as a UniversalisOS guest;
KVM **disabled** in that guest on M1 (no FEAT_NV), experimental on M2.
### Phase 4 — Device-model domain & vhost-user (QEMU integration spine)
- IOREQ/hypercall interface; run QEMU (Linux-hosted build) as a
device-model domain for a Linux guest (qemu-dm pattern); vhost-user
backends for blk/net; measure overhead vs in-HV virtio.
- Exit: Asahi guest served its virtio devices by the QEMU domain.
### Phase 5 — QEMU runs macOS (flagship)
1. Path 1 dev-loop (HVF vmapple, macOS 12) — immediately, in parallel with
Phase 1.
2. Path 2: KVM-ify vmapple (§4.2) on Asahi bare metal.
3. Path 3: vmapple domain on UniversalisOS with GXF/GL2 shim (port m1n1
`gxf.c` semantics), AVPBooter + aux/root provisioning replicated,
headless serial/VNC first.
4. Stretch: macOS 13+ early-boot blocker (trace with m1n1 hv), PVG-class
graphics forwarding story, IPSW restore-on-Linux (DFU flow).
- Exit: `qemu-system-aarch64 -accel kvm -M vmapple` boots macOS 12 on Asahi;
the same guest runs as a UniversalisOS personality.
### Phase 6 — Safety & productization
- ARINC-653 schedule enforcement on real hardware (budget/deadline
accounting via vPMU traps / arch timer), watchdog hardware integration
(Apple WDT), DART-enforced DMA isolation per domain, memory-integrity
checks, SAFE_STATE transitions tested by fault injection.
- Documentation toward DO-178C DAL-C evidence patterns (the realm's stated
creative-tools tier), uos-pkg packaging of guest images.
---
## 7. Risks & open questions
| Risk | Severity | Mitigation |
|---|---|---|
| macOS 13+ early-boot failure unsolved (even on HVF) | High | Plan around macOS 12 for v1; use m1n1-hv tracing to diagnose; track upstream vmapple work |
| Apple may close the raw-boot path on future silicon | Medium | Target M1/M2 (huge installed base); monitor Asahi 39C3-style updates |
| M4 SPTM/GL2 boot changes | Medium | Defer M4; raw-boot entry still yields EL2 |
| Upstream resistance to IMPDEF guest exposure (KVM) | Medium | Carry Asahi-style downstream patches; keep them minimal and documented |
| QEMU GPLv2 in the TCB | Low | Domain isolation (qemu-dm pattern); EL2 core stays C11/proprietary-clean; m1n1 is MIT |
| vmapple virtio-blk is Apple-nonstandard | Low | QEMU already implements it; our HV domain reuses that code path |
| Legal: macOS VM licensing (Apple SLA, Apple-branded hardware only) | LowMed | We run on Apple hardware; document compliance; no FairPlay/App Store in guests |
| Nested virt impossible on M1 | Known | Architecture avoids nesting: QEMU runs bare-metal-adjacent |
Open questions to resolve in Phase 0/1: exact hVHE/PMUv3 merge versions to pin
as kernel baseline (6.15/6.16 window — verify via `git log` on
`AsahiLinux/linux`); M3 nested/PMU-trap status; whether vmapple's 13+ blocker
is CPU-behavior (would bite KVM equally) or HVF-specific.
---
## 8. Reference index
**Repos:** `AsahiLinux/{m1n1,linux,u-boot,docs,asahi-scripts,muvm,asahi-installer}` ·
`qemu-project/qemu` (`hw/vmapple/`, `docs/system/arm/vmapple.rst`) ·
`ChefKissInc/Inferno` · `saagarjha/VirtualApple` · `NyanSatan/Virtual-iBoot-Fun` ·
`s-u/macosvm` · `cirruslabs/tart` · `crc-org/vfkit` · `containers/libkrun` ·
`amarioguy/AppleWOAProject`
**Docs:** `asahilinux.org/docs/``platform/open-os-interop`, `fw/boot`,
`fw/adt`, `fw/macho-boot-protocol`, `sw/m1n1-user-guide`, `sw/m1n1-dev-guide`,
`sw/m1n1-hypervisor`, `sw/u-boot`, `sw/kernel-config`, `sw/broken-software`
(16K), `sw/windows-11-vm` (KVM howto), `hw/soc/{aic,memmap,soc-codenames,smc}`,
`hw/cpu/{sprr-gxf,system-registers,smp}`, `platform/feature-support/{m1,m2,m3,m4}` ·
`docs.u-boot-project.org/en/latest/board/apple/m1.html` ·
`blog.svenpeter.dev/posts/m1_sprr_gxf/`
**Patch series:** Graf vmapple v1 (2023-06, patchew) / v2 (2023-08) ·
Dennis-Jordan v17 (2025-01, merged QEMU 10.0) · Graf HVF-aarch64 (QEMU 6.2,
2021-12) · Zyngier hVHE v3 (2023-06) · Zyngier KVM NV2 v11 (2023-11) · Upton
PMUv3-on-Apple v3 (2025-03, merged 6.15) · marcan TSO (2024-04) · Auger QEMU
nested-virt RFC v3 (2024-03)
**Reports/talks:** Asahi progress reports (Jan/Feb 2021 KVM+AIC; Sep 2021 DART
16K; 6.14 PMUv3+downstream stats; 6.17 M3 status) · 39C3 (Dec 2025, M3/M4/M5) ·
Sven Peter Mastodon 2025-04-04 (M4 SPTM/GL2) · Fedora nested-virt field report
(discussion.fedoraproject.org/t/nested-virtualization/179358, Jan 2026) ·
zhuowei "Booting a macOS Apple Silicon kernel in QEMU" (worthdoingbadly.com,
2020) · Xen-devel "Xen for Apple Silicon" thread (2024-07, feasibility only)
**Local:** `realms/universalisos/AGENTS.md` · `kernel/vm/consciousness.c` ·
`research/pt-futurista-audit/pikeos-4.x-extraction/` (PikeOS reference) ·
`mycelium-rd/xsd-schemas/` (consciousness/hypervisor-domain schemas)

View file

@ -0,0 +1,203 @@
# Asahi Linux / Apple Silicon — Technical Research Report for UniversalisOS Porting Plan
**Research date:** 2026-07-12. Sources: AsahiLinux/m1n1, AsahiLinux/docs, AsahiLinux/linux (GitHub), asahilinux.org blog, lore.kernel.org/patchew/LKML, phoronix, Fedora docs. Confidence tags: **[C]** confirmed from primary source, **[U]** uncertain/secondary source, **[C?]** confirmed fact, exact detail (e.g. kernel version) not independently verified.
---
## 1. Boot Chain on Apple Silicon
### 1.1 Stages [C]
From `AsahiLinux/docs``docs/fw/boot.md` ("Apple Silicon Boot Flow") and `docs/platform/open-os-interop.md`:
```
SecureROM (Boot ROM, SoC-integrated)
→ iBoot1 / LLB (NOR flash; reads NVRAM boot-volume, SEP-checked LocalPolicy img4)
→ iBoot2 (OS-level loader, in the APFS Preboot volume; loads XNU kernelcache
or a "fuOS" custom kernel if the boot policy allows it)
→ m1n1 stage 1 (installed as the custom kernel via `kmutil configure-boot`)
- parses Apple Device Tree (ADT), early HW init (memory controller,
USB-C charging, HDMI on Mac mini), disables watchdog, shows logo
- chainloads m1n1 stage 2 from a FAT32 ESP (chainloading code is Rust,
part of the future secureboot attack surface)
→ m1n1 stage 2 (raw binary + concatenated payloads: FDTs, U-Boot, optionally
kernel Image + initramfs)
- selects FDT per platform, personalizes it with dynamic data from ADT
(memory map, framebuffer, rng seed, /chosen bootargs, spin-table)
→ U-Boot (EFI boot services + FAT/NVMe/USB; Apple fork: AsahiLinux/u-boot)
→ GRUB (or any UEFI loader; GRUB needs no Apple-specific patches)
→ Linux kernel (standard UEFI+FDT ARM64 boot)
```
- Boot policy/security: installing a custom kernel requires **1TR ("one true recoveryOS")**, reduced security (`bputil` / LocalPolicy `coih` fuOS hash). Boot modes documented in `fw/boot.md` (macOS=0, 1TR=1, recoveryOS=2, ...).
- The Asahi Linux Installer (github.com/AsahiLinux/asahi-installer) builds a "stub macOS" APFS container (~2.5 GB) + per-OS ESP (~512 MB FAT32) per OS — this layout is the project's recommended interop standard (`docs/platform/open-os-interop.md`).
### 1.2 m1n1 (github.com/AsahiLinux/m1n1) [C]
- MIT license; descended from "mini" (Wii). Build: `make` (aarch64-linux-gnu-gcc or clang; `RELEASE=1`, `CHAINLOADING=1` options; output `build/m1n1.{bin,macho}`).
- **Payloads by concatenation**: kernel images (must be compressed or last), FDTs (raw or compressed), initramfs cpio (compressed); gzip/xz supported.
- **Boot protocol** (`docs/sw/m1n1-dev-guide.md`): trivial subset of XNU boot protocol; raw binary entry at **0x800 with MMU off**, `x0` = physical address of XNU `boot_args` struct (`src/xnuboot.h`); RVBAR at offset 0; legacy Mach-O images deprecated for Linux payloads (use raw `m1n1.bin`).
- **ADT→FDT translation**: m1n1 reads Apple's ADT and personalizes a template FDT for Linux/U-Boot [C].
- **Proxy mode**: USB CDC-ACM gadget on all Thunderbolt ports (`/dev/ttyACM0` proxy, `/dev/ttyACM1` hypervisor virtual UART); Python `proxyclient/` (tools: `linux.py`, `chainload.py`, `run_guest.py`, `run_guest_kernel.sh`, `freebsd.py`, `shell.py`; tracing modules in `proxyclient/hv/`). ~7-second kernel build-test cycle.
### 1.3 m1n1 hypervisor (hv) [C]
Source files in m1n1 repo: `src/hv.c`, `src/hv.h`, `src/hv_asm.S`, `src/hv_exc.c`, `src/hv_vm.c`, `src/hv_aic.c`, `src/hv_vuart.c`, `src/hv_wdt.c`, **`src/hv_virtio.c`** (virtio-mmio device emulation for guests — confirmed by reading the file).
- Runs at **EL2**; guests (macOS XNU or Linux) run at **EL1**. Stage-2 translation: RAM mapped 1:1, MMIO regions fault → data abort → Python-traceable MMIO hooks. Event types (`hv.h`): `HV_HOOK_VM, HV_VTIMER, HV_USER_INTERRUPT, HV_WDT_BARK, HV_CPU_SWITCH, HV_VIRTIO, HV_PANIC`.
- Provides: virtual UART over USB, virtualized AIC IRQ delivery, watchdog virtualization, virtio devices, GDB/LLDB stub (LLDB recommended — pointer-auth + Darwin dyld support), time-stealing accounting.
- **ABI is explicitly unstable**`chainload.py` must be re-run after any m1n1 tree update (`docs/sw/m1n1-hypervisor.md`).
- macOS guest support targets **macOS Ventura 13.5 max** (doc warning). Linux guests documented in `m1n1-user-guide.md` (`run_guest_kernel.sh`).
- **Correction to a premise in the task**: on M1/M2, m1n1 does *not* "emulate EL2 for Linux" in normal operation — iBoot2 hands control to m1n1 at real EL2, and m1n1 enters **Linux at EL2 with VHE (HCR_EL2.E2H=1)**. The hv component is a development/RE tool and guest runner, not part of the production boot path. There is **no EL3** on Apple Silicon.
### 1.4 EL2 / GXF / SPTM situation per chip generation [C + U]
- **M1/M2 (t8103, t6000t6002, t8112, t6020t6022)**: real, usable EL2. Linux runs at EL2/VHE; KVM works bare-metal (§2). M2 adds SPRR + GXF (GL1/GL2 "guarded" lateral exception levels sharing the EL page tables; `genter`/`gexit` instructions; `SPRR_CONFIG_EL1`, `SPRR_PERM_EL0/1` — full register map in `docs/hw/cpu/sprr-gxf.md`). GXF = "Guarded Execution Function", used by XNU to protect page tables from itself (Sven Peter write-up: https://blog.svenpeter.dev/posts/m1_sprr_gxf/). **[C?]** On M2+ iBoot2 reportedly launches custom kernels in GL2 and m1n1 transitions out to EL2 — the sprr-gxf doc documents GL2 mechanics but I did not find the exact boot-handoff statement in the docs repo; treat as likely but verify against m1n1 `src/startup.c` before writing it into the plan as fact.
- **M3 (t8122 / t603x)**: m1n1 can init CPUs, bring up peripherals, and boot the Asahi kernel (Asahi Progress Report: Linux 6.17, 2025-10-24, "M3? Kinda…"). AIC changed on M3 (new AIC generation; `aic2` work exists in the kernel fork). **[U]** A January 2026 secondary source claims a Fedora 43 Asahi Remix desktop boot on M3 by contributor IntegralPilot (keyboard/trackpad/Wi-Fi/NVMe/USB3 working, no GPU) — not verified against primary sources.
- **M4 (t8132 / t604x [C?] codenames not verified in docs)**: **boot chain materially changed** (Sven Peter, Mastodon 2025-04-03; phoronix 2025-04-04):
- Mach-O boot objects now drop into an environment where **Apple's SPTM (Secure Page Table Monitor) runs in GL2**, and the payload is expected to talk to SPTM **from EL2 with the MMU already enabled** to set up page tables — unusable for Linux as-is and breaks running XNU under the m1n1 hv (i.e., breaks the RE workflow).
- **Raw boot objects drop into EL2 with GL2 and most/all Apple-specific extensions disabled — "totally fine for Linux"**, but XNU can't run under the hv in this state. Raw boot appeared broken on macOS ≥15.2 at that date.
- 39C3 (Dec 2025) talk: M4/M5 changes broke existing RE tooling; full support "a long way off". **[U]** basic Alpine Linux boot on M4 reported by a contributor.
- **For the porting plan**: EL2 is available on all generations, but the *entry environment* differs: M1/M2 = clean EL2, MMU off; M4 = EL2 with MMU enabled + SPTM/GL2 context (macho path) or clean-ish EL2 (raw path). A type-1 hypervisor payload would most naturally take the m1n1 raw boot path.
---
## 2. KVM on Apple Silicon
### 2.1 Status [C]
**KVM/arm64 works on Apple Silicon today and has since early 2021.** KVM itself is architecture-generic — what was needed was (a) the platform booting Linux at EL2, (b) AIC/timer/FIQ quirks handled. Timeline:
- **Feb 2021**: Asahi Progress Report (Jan/Feb 2021) — Marc Zyngier already had **Linux VMs booting under KVM on the Asahi kernel on M1**. Notes that M1's cores implement the **GICv3 CPU interface with native virtualization support** (hardware vCPU interface), plus IMPDEF features for guest timer handling — used by KVM.
- KVM on Asahi runs in **VHE mode** (kernel at EL2). KVM guests get an emulated **vGICv3**; AIC device IRQs are injected as vGIC SPIs; the **architectural timer** is standard ARM (physical timer is wired to FIQ on Apple SoCs — Linux FIQ support by Mark Rutland was a prerequisite upstream change).
- **hVHE** (VHE inside the nVHE hypervisor): Marc Zyngier, "[PATCH v3 00/17] KVM: arm64: Allow using VHE in the nVHE hypervisor", lore.kernel.org/linux-arm-kernel, 2023-06-09 (touches `drivers/irqchip/irq-apple-aic.c` among others). **Tested on bare-metal M1 and as a *nested guest* on M2** — i.e., KVM/arm64 nested virtualization demonstrably works on M2 hardware. Merged upstream late 2023 **[C?]** (v6.6/v6.7 window — exact version not verified).
- **PMUv3 emulation for Apple**: Oliver Upton, "[PATCH] KVM: arm64: Support FEAT_PMUv3 on Apple hardware" — RFC Dec 2024, v1 2024-12-17, v2 2025-02-03, **v3 2025-03-06, 14 patches** (patchew.org). Uses Apple's IMPDEF EL2 trap of PMUv3 registers to emulate an architectural PMUv3 atop Apple's IMPDEF PMU; initially cycle counter + 1 event counter. **This is what unblocked Windows-on-ARM (WoA) KVM guests** (WoA requires PMUv3). Cherry-picked into Asahi kernels March 2025 (Progress Report 6.14, 2025-03-21); upstream merge in the 6.156.16 window **[C? — merge not independently verified]**.
- Fedora Asahi Remix ships working KVM; Asahi docs have a **Windows 11 VM guide** (`docs/sw/windows-11-vm.md`) using `qemu-system-aarch64 -enable-kvm -cpu host -M virt`. Note in that doc: libvirt/virt-manager stack is *unsupported/broken* as of the doc's writing (see AsahiLinux/docs PR #206 discussion).
### 2.2 Limitations [C]
- **M1: no architectural nested virtualization** (IMPDEF feature set; NV requires newer features). **M2: nested KVM demonstrated** (Marc Zyngier's hVHE testing, June 2023). The AppleWOA project notes likewise: M1/M1-Pro/Max/Ultra lack nested virt; M2 cores should support it.
- Guest feature restrictions historically: no PMUv3 until the Upton series; IMPDEF Apple registers (SPRR/GXF, TSO toggle in ACTLR_EL1) are **deliberately not exposed to guests** — Marc Zyngier rejected exposing non-architectural state to KVM guests (lore thread on marcan's TSO series, April 2024: "no implementation-defined features should be explicitly exposed to the guest"). TSO/`PR_SET_MEM_MODEL` (marcan, "[PATCH 0/4] arm64: Support the TSO memory model", 2024-04-11, rebased on v6.9-rc1) is a host-userspace feature, downstream in Asahi; KVM TSO left "for a future patchset" and faces upstream resistance.
- Timers: standard arch timer virtualized; physical timer IRQ is FIQ-based on Apple — handled.
- GIC: Apple chips include the GICv3 CPU interface (with virtualization); the AIC handles device interrupts and has **no LPI/ITS**; vGIC works in-kernel.
- **A Linux KVM guest on Apple Silicon running nested KVM**: works on M2 (demonstrated), not on M1.
---
## 3. Asahi Kernel Fork (github.com/AsahiLinux/linux)
### 3.1 Structure & cadence [C]
- Default branch: **`asahi`** (actively pushed as of 2026-07-09). Upstreaming branches: `apple-soc/{dt,drivers,fixes}-<version>`, `asahi-soc/for-next` etc. — Asahi devs (Sven Peter, Janne Grunau et al.) herd Apple SoC patches into mainline via the soc tree.
- Downstream feature branches are organized as **`bits/NNN-<topic>`**, merged into `asahi` (listing fetched from GitHub API, July 2026):
| Branch | Content | Upstream status |
|---|---|---|
| `bits/000-devicetree` | FDTs | progressively upstream (M1, M2, M2 Pro/Max/Ultra DTs in 6.18) |
| `bits/010-soc`, `030-misc` | SoC drivers | mostly upstream |
| `bits/020-dart` | DART IOMMU | core upstream (5.15); T602x 4-level tables in 6.18 |
| `bits/050-nvme` | NVMe/ANS + SART | NVMe upstream (5.19); SART upstream |
| `bits/070-audio` | macaudio/mca/AOP audio | **downstream** |
| `bits/080-wifi` | brcmfmac glue/firmware handling | mostly upstream |
| `bits/090-spi-hid` | SPI HID (keyboard/trackpad) | upstream |
| `bits/110-smc` | SMC MFD + subdevices | **core merged 6.17** (2025-07); subdevices (hwmon, RTC, lid) in review as of 6.18 |
| `bits/140-pci` | PCIe | upstream (T6020 PCIe in 6.16) |
| `bits/150-xhci-firmware`, `171-dptxphy` | USB3/DPTX PHY | USB3 **merged for 6.19** (Dec 2025) |
| `bits/180-sio` | SIO (serial) | downstream/partial |
| `bits/190-rust` | Rust abstractions for drivers | partially upstream |
| `bits/200-dcp` | **DCP display controller** | **downstream** (upstreaming planned) |
| `bits/210-gpu` | **AGX GPU kernel driver (Rust, drm/asahi)** + UAPI | **downstream**; UAPI header merged 6.16, driver in prep |
| `bits/220-tso` | TSO memory model toggle | **downstream** (upstream rejected so far) |
| `bits/240-isp` | ISP/camera | submitted (6k LoC) |
| `bits/250-aop` | AOP coprocessor | partially upstream |
| `bits/500-backports` | backports | n/a |
- Downstream burden as of Linux 6.13: **>90,000 LoC / ~1,250 patches** + downstream U-Boot, Mesa, virglrenderer, Flatpak runtime extension (Progress Report 6.14, 2025-03-21). Stated project goal is reducing this via upstreaming.
- Reference config list (as of linux-asahi-6.12.4-1) in `docs/sw/kernel-config.md` — full CONFIG list incl. `CONFIG_ARCH_APPLE`, `CONFIG_APPLE_AIC/DART/SART/SMC/RTKIT/MAILBOX/PMGR/ADMAC/M1_CPU_PMU`, `CONFIG_ARM64_16K_PAGES=y`, `CONFIG_DRM_ASAHI=y`, `CONFIG_ARM_APPLE_CPUIDLE`, etc.
### 3.2 SoC support matrix [C]
Docs: `docs/platform/feature-support/{m1,m2,m3,m4}.md` + https://asahilinux.org/fedora/#device-support.
| SoC | Codename | Status (mid-2026) |
|---|---|---|
| M1 | t8103 | Full Fedora Asahi Remix support (GPU, audio, webcam, suspend…) |
| M1 Pro/Max/Ultra | t6000/t6001/t6002 | Supported |
| M2 | t8112 | Supported |
| M2 Pro/Max/Ultra | t6020/t6021/t6022 | Supported; DTs + 4-level DART upstream in 6.18 |
| M3 (Pro/Max) | t8122 / t6030, t6031 | **Experimental**: m1n1 + kernel boot (Asahi 6.17 report, Oct 2025); desktop bring-up reported Jan 2026 **[U]**; no GPU; AIC redesigned |
| M4 (Pro/Max) | t8132 / t604x **[C?]** | Boot-chain RE blocked by SPTM/GL2; raw-boot Linux experiments only; no support |
| M5 | — | Mentioned at 39C3 (Dec 2025) as affected by the same changes |
### 3.3 Fedora Asahi Remix packaging & 16K pages [C]
- Kernel RPM: **`kernel-16k`** (build string e.g. `6.17.12-400.asahi.fc42.aarch64+16k`, seen in podman host info; also `6.14.8-400.asahi.fc42.aarch64+16k`). Built in COPR `group_asahi/kernel`; `kernel-16k-devel` exists; the Asahi platform metapackage conflicts with the plain Fedora `kernel` (confirmed via openzfs/zfs#16429 packaging log).
- **Why 16K is mandatory** (authoritative: Asahi docs "Broken Software" page + Progress Report Sept 2021): **Apple's DART IOMMUs only support 16K-aligned pages** on M1/M2 (4K exists on the CPU mainly for Rosetta). Linux cannot mix page sizes like XNU; 4K kernels are possible only with "very hacky patches" and suffer severe performance penalties — Asahi's position is 16K-only for the platform. (Sven Peter's 2021 IOMMU patches allow an IOMMU granule > kernel page size, making 4K *technically* viable with caveats, but Asahi does not ship that.)
- **Hypervisor implications**: (a) any guest doing DMA through passthrough DARTs needs **16K-granule stage-2 mappings**; (b) 4K guests are fine *without* 16K-only devices — proven by **muvm** (github.com/AsahiLinux/muvm, libkrun-based microVMs running 4K kernels under KVM on the 16K host for FEX/x86/Wine compatibility); (c) userspace ABI: ELF `LOAD` segments need ≥16K alignment on 16K hosts (Asahi "Broken Software" page) — irrelevant for a VM guest, which gets its own page size.
---
## 4. Virtualization-Relevant Hardware & Interfaces
### 4.1 AIC (Apple Interrupt Controller) [C]
`docs/hw/soc/aic.md`: SET/CLR register-pair style; per-IRQ target bitfields (`IRQ_TGT`), SW-generated IRQs, mask set/clr; per-core mirror registers at 0x2000+ (`IRQ_REASON`, `IPI_SEND`, `IPI_ACK`, `IPI_MASK_SET/CLR`); FIQ bypasses AIC (arch timer wired straight to FIQ). **M3 redesigned the AIC** (Asahi 6.17 report; `aic2` work in the fork). Linux driver: `drivers/irqchip/irq-apple-aic.c` (upstream 5.13); vGIC integration touches this driver (hVHE series).
### 4.2 DART / SART [C]
- **DART** = Device Address Resolution Table, the IOMMU in front of nearly all peripherals (`drivers/iommu/apple-dart.c`, upstream 5.15). M1/M2 DART: 16K granule only. T602x DARTs: larger address space → 4-level page tables (merged 6.18). Asahi 6.17 report describes DARTs as "a sort of firewall for peripherals".
- **SART** = simpler address filter gating the NVMe (ANS) coprocessor's DRAM access (`CONFIG_APPLE_SART`); NVMe itself talks to the ANS coprocessor via ASC mailbox + RTKit protocol (all upstream: `apple-mailbox`, `apple-rtkit`, `nvme-apple` in 5.19).
### 4.3 SPRR / GXF / SPTM [C]
- SPRR (M2+): page permission bits (AP/UXN/PXN) become an index into `SPRR_PERM_EL0/1` registers; effectively forbids W+X; GXF adds GL1/GL2 guarded levels (doc: `hw/cpu/sprr-gxf.md`). m1n1 handles SPRR setup at boot; KVM does not expose SPRR to guests.
- SPTM (M4, also implicated on M3/M5 at 39C3): Secure Page Table Monitor running in GL2 that brokers page-table setup — the new obstacle on the macho boot path.
### 4.4 What Asahi Linux needs as a guest (interfaces a type-1 hypervisor must provide) [C/U]
Confirmed facts:
- Asahi Linux boots via **UEFI + FDT** (U-Boot provides EFI services; GRUB uses them). As a guest it needs: an FDT (m1n1 generates/personalizes it — **m1n1 as guest firmware is a viable and proven pattern**: `run_guest_kernel.sh` boots Linux under the m1n1 hv with FDT payloads).
- CPU: entered at EL1 or EL2 with MMU off per ARM64 boot protocol; secondary CPUs via **spin-table** (m1n1 adds spin-table nodes; an `efi-psci` branch exists in the fork).
- Interrupts: vGICv3 (works, KVM-proven) or AIC passthrough/emulation (m1n1 hv virtualizes AIC: `hv_aic.c`).
- Timer: architectural timer; note physical timer IRQ = FIQ, not SPI — a hypervisor must deliver vtimer/PTimer correctly (KVM handles this).
- Devices: for full functionality either **device passthrough with DART** (guest programs DART? No — DART would sit behind the hypervisor's stage-2; this is an open design point) or **virtio** — virtio is fully proven: m1n1's hv implements virtio-mmio (`hv_virtio.c`), and Asahi userspace runs fine in QEMU `-M virt` VMs (the Win11 guide's inverse).
- 16K stage-2 granule required if any 16K-only DART/device is passed through.
Existing precedents for Linux under a hypervisor on Apple Silicon [C]:
1. **m1n1 hv** running Linux (and FreeBSD — `proxyclient/tools/freebsd.py`) and macOS guests at EL1.
2. **KVM on Asahi** running Linux/Windows/BSD guests (QEMU, muvm/libkrun microVMs).
3. **macOS Hypervisor.framework / Virtualization.framework** running Linux guests (UTM, QEMU hvf) — GIC fully emulated in software there (per 2021 Asahi blog), slower for IPI-heavy loads.
4. **AppleWOA project** (github.com/amarioguy/AppleWOAProject) — m1n1 fork as a thin hypervisor to run UEFI + Windows at EL1.
5. Corellium's early (2021) M1 Linux work pre-dating/feeding Asahi.
---
## 5. Key Documents & Repositories
**Repos**
- `github.com/AsahiLinux/m1n1` — bootloader/hv; `README.md`, `src/hv*.c`, `proxyclient/` (docs inside repo are minimal; docs live in the docs repo).
- `github.com/AsahiLinux/linux` — kernel fork, default branch `asahi`; `bits/*` topic branches.
- `github.com/AsahiLinux/docs` — documentation repo, Zensical/MkDocs → GitHub Pages at **asahilinux.org/docs**. README + `docs/index.md` fetched and confirmed. Structure: `alt/ fw/ hw/{cpu,devices,peripherals,soc}/ platform/ project/ sw/`.
- `github.com/AsahiLinux/asahi-installer`, `AsahiLinux/u-boot`, `AsahiLinux/muvm`, `AsahiLinux/asahi-scripts`.
**Most important docs pages** (all under asahilinux.org/docs/…, raw at raw.githubusercontent.com/AsahiLinux/docs/main/docs/…):
- `platform/open-os-interop.md`**the boot chain + OS layout standard** (fetched in full; supersedes `open-os-interop-old.md`)
- `fw/boot.md` — Apple Silicon boot flow (SecureROM→iBoot1→iBoot2, LocalPolicy 4CCs, DFU flow, boot modes)
- `fw/adt.md`, `fw/macho-boot-protocol.md`, `fw/nvram.md`
- `sw/m1n1-user-guide.md`, `sw/m1n1-dev-guide.md` (boot protocol, entry at 0x800), `sw/m1n1-hypervisor.md` (hv usage; macOS ≤13.5; unstable ABI; LLDB)
- `hw/cpu/sprr-gxf.md`, `hw/cpu/apple-instructions.md`, `hw/cpu/system-registers.md`, `hw/cpu/smp.md`
- `hw/soc/aic.md`, `hw/soc/memmap.md`, `hw/soc/soc-codenames.md`, `hw/soc/smc.md`, `hw/soc/spmi.md`, `hw/soc/display-controllers.md`, `hw/soc/agx.md`, `hw/soc/apcie.md`
- `sw/kernel-config.md` (full Asahi config), `sw/devicetree-bindings.md`, `sw/broken-software.md` (16K rationale), `sw/windows-11-vm.md` (KVM guest howto), `sw/u-boot.md`
- `platform/feature-support/{overview,m1,m2,m3,m4}.md`
- External: Sven Peter's SPRR/GXF write-up (blog.svenpeter.dev/posts/m1_sprr_gxf/); Asahi blog progress reports (asahilinux.org/blog/ — esp. Jan/Feb 2021 [KVM/AIC/FIQ], Sept 2021 [DART 16K], 6.14 [downstream stats, PMUv3], 6.17 [M3 status, DART 4-level], 6.18/6.19 [SMC subdevices, USB3]); 39C3 talk (Dec 2025, M3/M4/M5 status); lore.kernel.org hVHE series (2023-06-09) and PMUv3 series (patchew 2025-03-06).
---
## 6. Points of Caution for the Porting Plan (confirmed vs. uncertain)
1. **[C]** M1/M2 give you real EL2, VHE, hardware GICv3 CPU-interface virtualization, and working KVM — the premise "no real EL2 on M1/M2" is **wrong**. What Apple removed/changed on **M4** is the *boot-time environment* (SPTM in GL2 on the macho path), not EL2 itself; raw boot still yields EL2.
2. **[C]** Nested KVM: M1 = no; M2 = demonstrated (June 2023). M3/M4 nested status unknown.
3. **[C]** A type-1 hypervisor running Asahi Linux as a guest must handle: FIQ-based physical timer delivery, AIC (or vGIC injection of AIC IRQs), spin-table SMP, 16K stage-2 granule for passthrough, FDT generation (reuse m1n1's ADT→FDT personalization or pass a pre-baked FDT).
4. **[U]** Exact upstream merge versions for hVHE (6.6/6.7) and the PMUv3 series (6.15/6.16); M4 codenames (t8132/t604x); M3 desktop-boot claim (Jan 2026); GL2-at-iBoot2-handoff on M2. Verify against `git log` on the AsahiLinux/linux fork and m1n1 `src/startup.c` before citing in the formal plan.
5. **[C]** The m1n1 hv (`src/hv_*.c`, ~9 files, MIT) is the closest existing reference implementation of a type-1-ish hypervisor on this hardware, including virtio-mmio device models and AIC virtualization — recommended primary reading for UniversalisOS, alongside the KVM/arm64 vGIC/AIC code paths.

View file

@ -0,0 +1,129 @@
# Asahi U-Boot (AsahiLinux/u-boot) — Research Report for UniversalisOS Porting Plan
All source findings verified against a sparse clone of `https://github.com/AsahiLinux/u-boot` (branch `asahi`, HEAD `8aa706b2`, 2025-12-21; branch `asahi-releng`, HEAD `3b233f59`, 2026-05-24). Clone deleted after analysis. Web sources cited inline.
## 1. Repository, upstream base, branches, packaging
**Upstream base:** The live `asahi` branch is based on **upstream U-Boot v2025.10** (`Makefile`: `VERSION = 2025, PATCHLEVEL = 10`; upstream `Prepare v2025.10` commits dated 2025-07 → 2025-10 are in history). The `asahi` branch is a set of Apple/Asahi commits carried on top of upstream release snapshots, **not** a continuous rebase per upstream release.
**Branches (from `git ls-remote`):**
| Branch | Tip date | Purpose |
|---|---|---|
| `asahi` (default/HEAD) | 2025-12-21 | Main development branch, v2025.10 base |
| `asahi-releng` | **2026-05-24** | **What distros ship to users** — adds ESP auto-detection, ENV_IS_IN_FAT, Fedora tweaks, and (as of 2026-05-21) **Apple M3 support** |
| `fedora-asahi-v2024.04` | 2024-04-20 | Fedora Asahi Remix build branch (commits prefixed `FEDORA:`) |
| `openbsd-releng` | 2024-01-08 | OpenBSD build branch (kettenis is an OpenBSD dev) |
| `asahi-next` | 2023-04-02 | Stale |
| `t6020`, `asmedia`, `asmedia2`, `mtp-support`, `nvme/shutdown`, `bootmenu*` | various | Feature/topic branches |
| `master` | 2025-04-18 | Stale mirror of upstream master — ignore |
**Rebase cadence (inferred, medium confidence):** Fedora branch was v2024.04 (April 2024); Debian's `u-boot-asahi` is 2025.01; the `asahi` branch is now v2025.10 (Dec 2025). So roughly **12 upstream rebases per year**, plus small fixup commits. The Asahi docs confirm: "U-Boot generally doesn't change much once properly brought up on any given SoC."
**Fedora Asahi Remix packaging:**
- Asahi docs (asahilinux.org/docs/sw/u-boot/): *"For an example of how we do this in Fedora Asahi Remix, see our `uboot` and `asahi-scripts` packaging."* Fedora package **`uboot`** is built from the `fedora-asahi-v2024.04` branch; the companion **`m1n1`** RPM provides `m1n1.bin` and DTBs. Both install bare artifacts to **`/usr/lib/asahi-boot/`** (`m1n1.bin`, `u-boot-nodtb.bin`, `apple/*.dtb`).
- **`update-m1n1`** (from `asahi-scripts`, github.com/AsahiLinux/asahi-scripts, verified source) regenerates the ESP image:
```sh
cat "$M1N1" $DTBS > boot.bin.new
gzip -c "$U_BOOT" >> boot.bin.new # U-Boot payload is gzip-compressed
cat "$m1n1config" >> boot.bin.new # /etc/m1n1.conf options appended
# atomic replace of <ESP>/m1n1/boot.bin, keeping boot.bin.old backup
```
ESP is auto-located (via `asahi,efi-system-partition` PARTUUID) and mounted at `/run/.system-efi`. DTBs expanded as `/usr/lib/asahi-boot/apple/t6*.dtb t81*.dtb`.
- **ESP layout:** `<ESP>/m1n1/boot.bin` (m1n1 stage2 + DTBs + gzipped U-Boot + config), `<ESP>/EFI/BOOT/BOOTAA64.EFI` (GRUB, vanilla), plus `vendorfw.cpio` (extracted Apple firmware, produced by `asahi-fwextract` / the `update-vendor-firmware` tool from the `asahi-fwupdate` package, mounted into `/lib/firmware` by a dracut module).
- **`kmutil` flow:** only used once at install time from 1TR to install m1n1 *stage 1* as the fuOS custom kernel: `kmutil configure-boot -c m1n1-stage1.bin --raw --entry-point 2048 --lowest-virtual-address 0 -v <volume>` (m1n1 User Guide). Stage 1 has the ESP PARTUUID hardcoded and chainloads stage 2 from `<ESP>/m1n1/boot.bin` (internal NVMe only). Routine updates never touch kmutil.
- Other distros: Arch ALARM ships `uboot-asahi` (same `/usr/lib/asahi-boot` + `update-m1n1` scheme); Debian sid ships `u-boot-asahi` 2025.01-3.1.
---
## 2. Apple board support in the tree
**Board code location:** `arch/arm/mach-apple/` (NOT `board/apple/` — there is no board/apple directory):
- `board.c` (Mark Kettenis, 2021) — per-SoC static MMU `mem_map` tables (I/O, PCIe, RAM, framebuffer regions) for t8103/t8112, t6000/t6001, t6002, t6020/t6021, t6022; `board_fdt_blob_setup()` returns the DTB pointer passed by m1n1 (`fw_dtb_pointer`); `asahi_esp_devpart()` — scans NVMe partitions, prefers the one whose PARTUUID matches `/chosen/asahi,efi-system-partition`, sets `efi_system_partition`; `board_late_init()` sets `storage_interface`, `fw_dev_part`, `loadaddr`/`fdt_addr_r`/`kernel_addr_r`/`ramdisk_addr_r`; `ft_board_setup()` rewrites `stdout-path` to `/chosen/framebuffer` when a keyboard exists and EL≠1.
- `lowlevel_init.S``save_boot_params` stashes **x0 (DTB pointer from m1n1)** into `fw_dtb_pointer`.
- `rtkit.c`, `rtkit_helper.c`, `sart.c` — Apple RTKit co-processor protocol + SART (NVMe address filter) support, used by the NVMe driver.
- `Kconfig`: `TEXT_BASE=0x0`, `SYS_CONFIG_NAME="apple"`, malloc 64 MiB.
**Defconfig:** a single **`configs/apple_m1_defconfig`** builds for **all** supported SoCs (Asahi docs: "Do not be fooled by the name"). Key options: `CONFIG_ARCH_APPLE`, `DEFAULT_DEVICE_TREE="t8103-j274"`, `BOOTCOMMAND="bootflow scan -b"` (bootstd/bootflow), `USE_PREBOOT`, `NO_NET`, `APPLE_SPI_KEYB`, `APPLE_MTP_KEYB`, `NVME_APPLE`, `USB_XHCI_HCD/DWC3/PCI`, `USB_DWC3`, `USB_KEYBOARD`, `VIDEO_SIMPLE` (simplefb), `NO_FB_CLEAR`, `CMD_SELECT_FONT`, `# CONFIG_MMC is not set`, `# CONFIG_SMBIOS is not set`. Env header `include/configs/apple.h`: `stdin=serial,usbkbd,spikbd,mtpkbd`, `stdout/stderr=vidconsole,serial`, `boot_targets="nvme usb"`. EFI_LOADER is on via the arm64 default.
**Supported SoCs:**
- `asahi` branch `board.c`: **t8103 (M1), t8112 (M2), t6000/6001/6002 (M1 Pro/Max/Ultra), t6020/6021/6022 (M2 Pro/Max/Ultra)** — anything else hits `panic("Unsupported SoC\n")`.
- `asahi-releng` adds (2026-05-21 commits): **t8122 (M3), t6030/t6031/t6034 (M3 Pro/Max), t6032 (M3 Ultra)**.
- **No M4 (t8132/t604x) support anywhere** in the repo (high confidence — no t8132/t604 references). Upstream docs site (docs.u-boot-project.org/en/latest/board/apple/m1.html) lists up to t6022.
- In-tree DTs: `dts/upstream/src/arm64/apple/` has t8103, t8112, t600x; `arch/arm/dts/` has the t602x family (added May 2023, "Taken from the asahi branch of the Asahi Linux github repository"). Note: **in production the in-tree DTs are unused** — m1n1 stage 2 supplies its own embedded DTBs (from the AsahiLinux/linux tree) personalized with ADT data.
**Apple drivers present:**
- `drivers/nvme/nvme_apple.c` — ANS2 NVMe; boots the NVMe coprocessor via **RTKit** (`apple_rtkit_boot`) and programs **SART** allow-lists (`sart_add_allowed_region`); requires the NVMe firmware (RTKit endpoint firmware — loaded via the firmware loader, see "file system firmware loader" commit on releng).
- `drivers/pci/pcie_apple.c` — Apple PCIe RC (t8103/t600x style).
- `drivers/usb/host/xhci-pci-asmedia.c` + commit "usb: xhci-pci: Load ASMedia XHCI controller firmware" — **ASMedia xHCI on t602x** machines (needs non-upstreamable firmware load at runtime).
- `drivers/phy/phy-apple-atc.c` — Apple Type-C PHY (ATC); USB via generic DWC3 glue + xHCI (`USB_XHCI_DWC3`).
- `drivers/input/apple_kbd.c`, `apple_spi_kbd.c` (SPI keyboard, M1 laptops), `apple_mtp_kbd.c` (MTP keyboard, M2+ laptops — "MTP keyboard support for M2 platforms goes along with DT changes").
- `drivers/spi/apple_spi.c` (default y if ARCH_APPLE), `drivers/iommu/apple_dart.c` (default y), `drivers/power/domain/apple-pmgr.c` (PMGR power domains), `drivers/pinctrl/pinctrl-apple.c`, `drivers/mailbox/apple-mbox.c` (for RTKit), `drivers/watchdog/apple_wdt.c` (default y).
- Serial: **`drivers/serial/serial_s5p.c`** — Samsung S5P UART driver reused for Apple's S5L UART (`config S5P_SERIAL ... depends on ARCH_APPLE || ARCH_EXYNOS`, default y). Per-SoC UART base addresses documented in `doc/board/apple/m1.rst` (t8103: 0x235200000; t600x: 0x39b200000).
**What it does NOT do:**
- **No GPU/display-pipe init** — display comes solely from simple-framebuffer: m1n1 puts a `/chosen/framebuffer` node in the FDT; `CONFIG_VIDEO_SIMPLE` renders to it. `ft_board_setup` points `stdout-path` at it.
- **No AIC/interrupt-controller driver** — U-Boot is entirely polled; timing via ARM architected timer. (No `aic` driver anywhere in `drivers/`.)
- **No SMC, no AOP, no cpufreq/clock drivers, no power management beyond PMGR domains, no `poweroff` command** (Asahi docs explicitly), no network (`CONFIG_NO_NET`), no USB-A ports on machines whose controllers need non-redistributable firmware (Mac Studio front ports, iMac far ports), no persistent EFI variables (Asahi docs: "We don't have persistent EFI variable storage").
- Relies on m1n1 for: memory controller init, clocks, L3 cache enable, PCIe bring-up ("PCIe on M2 required no driver-level changes, only changes to the m1n1 initialization"), ADT→FDT translation, display pipe bring-up.
---
## 3. Boot flow
Full chain (Asahi Boot Process guide, asahilinux.org/docs/alt/boot-process-guide/ — quoted):
> `[Apple stuff] → m1n1 stage 1 → m1n1 stage 2 → DT + U-Boot → GRUB → Linux`
- **Stage 1** (installed once via `kmutil configure-boot` from 1TR, signed per-machine): has ESP PARTUUID hardcoded, inits NVMe, chainloads `<ESP>/m1n1/boot.bin`, forwards `/chosen` props including `asahi,efi-system-partition`.
- **Stage 2** `boot.bin` = concatenation: `m1n1.bin` + `*.dtb` (all Apple DTBs) + `gzip(u-boot-nodtb.bin)` + optional text config. m1n1's payload format (m1n1 README): payloads are found by simple concatenation scanning; formats = kernel-image-compatible binaries (must be compressed or last), FDTs, cpio; compression gzip/xz. **U-Boot is treated as a "kernel image" payload** — entered at its reset vector with **x0 = pointer to the personalized FDT** (U-Boot side: `save_boot_params` stashes x0 → `fw_dtb_pointer``board_fdt_blob_setup`). m1n1 stage 2 selects the DTB matching the platform, transplants dynamic ADT data (memory, framebuffer, MAC addresses, etc.), then jumps to U-Boot.
- **U-Boot role ("BIOS-like"):** parses FDT, sets up MMU via its static per-SoC `mem_map` + DRAM/framebuffer from FDT, inits keyboard (SPI/MTP/USB), NVMe (RTKit boot of ANS coprocessor), USB; reads env from FAT on the ESP (releng: `ENV_IS_IN_FAT`); runs **bootstd** (`bootflow scan -b` over `boot_targets="nvme usb"`); provides **UEFI boot services** and loads `/EFI/BOOT/BOOTAA64.EFI` (default GRUB, unpatched), passing the (lightly modified) FDT via the EFI FDT table. It consumes, modifies (`stdout-path`), and forwards the DT.
- **ESP auto-detection:** `asahi_esp_devpart()` in board.c picks the GPT partition flagged EFI System whose PARTUUID equals `/chosen/asahi,efi-system-partition` (written by m1n1), falling back to the first ESP on internal NVMe (`apple,nvme-ans2` only). This is the "magic" that makes each OS container boot its own ESP.
- **Distro installers:** USB-bootable installers rely on the vanilla m1n1+U-Boot bundle the Asahi installer places on the internal ESP in "UEFI container mode"; the USB stick carries its own ESP with `/EFI/BOOT/BOOTAA64.EFI` and no `m1n1/boot.bin`. Boot from USB at the U-Boot prompt: `run bootcmd_usb0`. Installed OSes own everything from m1n1 stage 2 onward and may technically replace U-Boot (docs explicitly allow: "use U-Boot directly to boot kernels, or use the Linux EFI stub, or GRUB").
- **Hypervisor note in-tree:** `ft_board_setup()` checks `current_el() == 1` and skips console redirection "if we're running under the m1n1 hypervisor" — i.e. **U-Boot already has an explicit code path for being launched at EL1 under a hypervisor** (m1n1's built-in HV). U-Boot itself runs at EL2 when started directly.
---
## 4. Apple-relevant docs
In-tree (`doc/`):
- `doc/board/apple/index.rst` — one page: `m1`.
- `doc/board/apple/m1.rst` — "U-Boot for Apple Silicon Macs". Lists SoCs (on the `asahi` branch it lists only M1 family — **doc lags code**; upstream's rendered version lists t8103, t8112, t600x, t602x), supported hardware ("S5L serial port, SPI keyboard, Framebuffer, NVMe storage, USB 3.1 Type-C ports"), build (`make apple_m1_defconfig`), image creation (`cat m1n1.macho t8103-j274.dtb u-boot-nodtb.bin > u-boot.macho`), and debug-UART base addresses. Key quote: *"This uses `u-boot-nodtb.bin` as the device tree is passed to U-Boot by m1n1 after making some adjustments."*
- `doc/develop/uefi/` — generic UEFI docs: `uefi.rst` (UEFI implementation status/limitations), `u-boot_on_efi.rst`, `iscsi.rst`, `fwu_updates.rst`. Nothing Apple-specific.
- `doc/device-tree-bindings/pinctrl/apple,pinctrl.yaml` (removed on releng in favor of dts/upstream).
- Top-level `README` — generic U-Boot README, nothing Apple.
External canonical docs (must-reads for the porting plan):
- https://asahilinux.org/docs/sw/u-boot/ — U-Boot page (build, install, USB boot, known issues).
- https://asahilinux.org/docs/alt/boot-process-guide/ — boot chain + version interdependencies (m1n1/U-Boot/DT/kernel coupling).
- https://asahilinux.org/docs/platform/quirks/ + https://asahilinux.org/docs/fw/boot/ — platform firmware/boot flow.
- m1n1 User Guide (github.com/AsahiLinux/docs wiki / leo3418 mirror) — kmutil stage-1 install, stage-2 payload concatenation, payload formats.
- "Open OS Ecosystem on Apple Silicon Macs" (docs wiki) — OS layout, boot schemes, recommendation that OSes keep the installer-provided stage-2 blob.
---
## 5. Reuse potential under a type-1 hypervisor
**Hardware asahi-u-boot touches directly (would need passthrough or emulation):**
1. **NVMe/ANS2** — the heaviest item: full RTKit protocol boot of the ANS coprocessor (firmware upload, shared-memory queues via mailbox `apple-mbox`), plus **SART** programming (DMA allow-list filter) and (implicitly) DART behind it. Under a hypervisor you'd either pass through the real NVMe+SART+DART (defeats isolation) or — much better — **give the guest a virtio-blk/pci NVMe and strip the Apple NVMe driver**; bootstd + EFI would then use the virtual disk. This is exactly what the m1n1 hypervisor / QEMU paths do (U-Boot supports virtio out of the box upstream).
2. **USB**: DWC3 xHCI + ATC PHY (+ ASMedia xHCI over Apple PCIe on t602x). Same story: passthrough or replace with virtual USB. Keyboards: `apple_spi_kbd`/`apple_mtp_kbd` touch SPI/HID hardware directly — but only for console input; can be substituted by USB HID or a virtual console.
3. **PCIe RC** (`pcie_apple.c`) — only needed for ASMedia USB on t602x; droppable in a VM.
4. **Timers**: ARM generic architected timer only (standard, already virtualizable).
5. **Interrupts**: none (fully polled; no AIC driver). Big simplification for guest firmware.
6. **MMU**: programs its own EL2 page tables from static per-SoC `mem_map` tables in `board.c` + DRAM/framebuffer from FDT. Under a type-1 HV at EL1, stage-2 translation is the hypervisor's; the static I/O mappings would just fault if the MMIO isn't passed through — but the `current_el()==1` precedent shows the code already tolerates EL1 execution (m1n1's HV runs guests at EL1).
7. **Framebuffer**: simplefb only — the hypervisor just needs to provide a `/chosen/framebuffer` (or GOP equivalent) in the FDT. No GPU.
8. **Environment/bootstd**: expects a FAT ESP; trivially satisfiable with a virtual disk. It reads `/chosen/asahi,efi-system-partition` but degrades gracefully (falls back to first ESP).
**Assessment for option (a) — reuse as guest firmware:** Feasible and precedented (m1n1 HV runs it at EL1). Practical path: build with `apple_m1_defconfig`, drop NVMe_APPLE/PCIe/ASMedia/ATC/SPI-kbd drivers, add virtio, keep EFI_LOADER + simplefb + bootstd. You get UEFI services (boot + runtime-minus-variables — note **no persistent EFI variable store** even on bare metal) for GRUB/systemd-boot guests "for free". The hypervisor must present: FDT in x0, RAM, arch timer, a console (UART/framebuffer), and block + optional input devices.
**Option (c) — run it unmodified under the HV:** requires emulating ANS2 RTKit + SART + Apple PCIe/DWC3/ATC — disproportionate effort; not recommended.
**Option (b) — skip U-Boot, boot Linux EFI stub directly:** Explicitly sanctioned by Asahi ("OS installers… a Linux distro could… use the Linux EFI stub"). The Linux arm64 EFI stub only needs: an EFI boot-services environment **or** direct kernel boot with FDT. Your hypervisor can load `Image` + initramfs + FDT itself and jump to the kernel entry (x0=FDT) — the same contract m1n1 uses for U-Boot. What you'd lose: UEFI boot services for GRUB/systemd-boot (boot menus, `LoadImage`, disk access), the interactive preboot shell, and USB-boot fallback. What you'd keep: full control, tiny TCB, no fork maintenance. A middle path many type-1 HV projects take: implement the minimal EFI stub services in the HV's loader, or ship a bundled `Image+initrd+dtb` m1n1-style payload per guest.
**Key coupling risk for all options:** m1n1 stage 2 owns hardware bring-up (memory controller, clocks, PCIe, display pipe, L3). If UniversalisOS boots *instead of* m1n1 stage 2, it must reproduce that bring-up or embed m1n1 as its own payload (m1n1 is open and designed to be a payload host — the cleanest route is HV-as-m1n1-payload or m1n1-as-HV-payload chain).
---
## Uncertainty log
- Fedora RPM name `uboot` and its dist-git spec: high confidence (Asahi docs reference it; `fedora-asahi-v2024.04` branch with `FEDORA:` commits corroborates) but src.fedoraproject.org was bot-blocked (Anubis), so I could not quote the spec's `%files` directly. The `/usr/lib/asahi-boot/` layout is confirmed from the `update-m1n1` script source.
- Rebase cadence (12/year) is inferred from branch/base versions, not stated policy.
- M3 support exists only on `asahi-releng` (May 2026), not yet merged to `asahi`; M4 absent everywhere as of 2026-07.
- `doc/board/apple/m1.rst` on the `asahi` branch lists only M1-family SoCs — stale relative to code; the docs.u-boot-project.org rendered version (up to t6022) matches the code better.
- Upstream U-Boot's own Apple support (source.denx.de master) is the origin of most drivers (kettenis upstreams them); the Asahi fork carries releng extras (ESP pinning, MTP kbd, ASMedia firmware loading, M3).

View file

@ -0,0 +1,180 @@
# macOS Guests under QEMU on Apple Silicon — Definitive Technical Landscape (as of mid-2026)
## Executive summary
The work you remembered as "qemu-devel patches for macOS guests on Apple Silicon" is real and is called **`vmapple`** — but it is **HVF-only (macOS hosts)**, not KVM/Asahi. It was authored by **Alexander Graf** (Amazon, 2023) and upstreamed by **Phil Dennis-Jordan** (20242025), landing in **QEMU 10.0** (April 2025). It boots **macOS 12 guests only**; 13+ still fails in early boot as of QEMU master (mid-2026). On **Asahi Linux / KVM, no macOS-guest support exists upstream** — in fact the `vmapple` machine cannot even be *compiled* for Linux hosts today (`config VMAPPLE ... depends on HVF`). Nested KVM on Apple Silicon Linux is now partially real: works on **M2+ with kernel ≥ 6.16 + QEMU ≥ 10.x**, but is explicitly "not ready for prime time"; **M1 has no nested-virt hardware at all**.
---
## 1. QEMU + KVM on Asahi Linux running macOS guests
### 1.1 What exists upstream — the `vmapple` machine (HVF only)
**Confirmed.** The canonical patch series:
| Series | Author | Date | Status |
|---|---|---|---|
| `[PATCH 00/12] Introduce new vmapple machine type` (v1) | Alexander Graf `<graf@amazon.com>` | 2023-06-14 | Posted, stalled |
| `[PATCH v2 00/12]` | Alexander Graf | 2023-08-30 | Posted |
| `macOS PV Graphics and new vmapple machine type` — respun/reworked series, v3…v17 | Phil Dennis-Jordan `<phil@philjordan.eu>` (part-sponsored by Sauce Labs), based on Graf's work | 2024-09 → 2025-01-12 (v16 posted 2024-12-23/27, v17 Jan 2025) | **Merged for QEMU 10.0** (released 2025-04-22) |
- v1: https://patchew.org/QEMU/20230614224038.86148-1-graf@amazon.com/
- v2: https://patchew.org/QEMU/20230830161425.91946-1-graf@amazon.com/
- v16/v17: https://patchew.org/QEMU/20250112210056.16658-1-phil@philjordan.eu/ and https://lists.gnu.org/archive/html/qemu-devel/2025-01/msg01001.html
- XHCI companion fixes: https://patchew.org/QEMU/20241227121336.25838-1-phil@philjordan.eu/
- Merged evidence: QEMU master `MAINTAINERS` has a `VMapple` section (M: Alexander Graf, Phil Dennis-Jordan); docs live at https://www.qemu.org/docs/master/system/arm/vmapple.html ; a `[PATCH-for-10.0] tests/qtest: Skip Aarch64 VMapple machine` (2025-04-03) confirms it was in the 10.0 tree.
- **UTM 4.7.0** (mid-2026) shipped QEMU 10.0.2 and briefly enabled the vmapple model, then **removed it "for stability reasons"**, keeping only `apple-gfx-pci` for Intel VMs: https://github.com/utmapp/UTM/releases
**What vmapple is:** a reimplementation (no Apple code) of the device model that Virtualization.framework exposes to arm64 macOS guests: GICv3 (no ITS — legacy IRQs only, no MSI/MSI-X), GPEX PCIe, XHCI + USB HID, PL011 UART, PL031 RTC, PL061 GPIO + gpio-key power button, `pvpanic-mmio`, plus Apple-specific devices: `vmapple-aes` (hardware AES engine), `vmapple-cfg` (config region), `vmapple-bdif` ("backdoor interface"), `vmapple-virtio-blk-pci` (Apple's nonstandard virtio-blk extension, `variant=aux|root`), and `apple-gfx-mmio` (ParavirtualizedGraphics.framework-backed display).
**Confirmed limitations (from the cover letters and current master docs):**
- **macOS 12.x guests only; 13+ (Ventura and later) fails during early boot** — still true on QEMU master as of the doc fetch (mid-2026). No public fix.
- **macOS arm64 hosts only, `-accel hvf` only.** Host must be macOS 12+ (docs) — needed both for HVF and because `apple-gfx` drives Apple's closed-source ParavirtualizedGraphics.framework.
- Guest must first be **provisioned/installed with Virtualization.framework** (e.g. `macosvm` CLI) from an IPSW; the resulting `disk.img` + `aux.img` are then reusable in QEMU.
- Legacy IRQs only (no MSI/MSI-X; would need GICv3 ITS).
- XHCI workaround needed for usable USB keyboard/tablet (macOS XHCI driver quirk when MSI-X absent; QEMU issue #2705, fixed in the same effort).
- No Rosetta in guest (TSO needs a private Apple entitlement).
- Migration blocked for apple-gfx (no state serialization).
**Documented command line (QEMU master docs, verbatim):**
```bash
UUID="$(contrib/vmapple/uuid.sh macosvm.json)" # extracts ECID
AVPBOOTER="/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin"
dd if=aux.img of=aux.img.trimmed bs=$((0x4000)) skip=1
qemu-system-aarch64 \
-serial mon:stdio -m 4G -accel hvf \
-M vmapple,uuid="$UUID" \
-bios "$AVPBOOTER" \
-drive file=aux.img.trimmed,if=pflash,format=raw \
-drive file=disk.img,if=pflash,format=raw \
-drive file=aux.img.trimmed,if=none,id=aux,format=raw \
-drive file=disk.img,if=none,id=root,format=raw \
-device vmapple-virtio-blk-pci,variant=aux,drive=aux \
-device vmapple-virtio-blk-pci,variant=root,drive=root \
-netdev user,id=net0,ipv6=off,hostfwd=tcp::2222-:22,hostfwd=tcp::5901-:5900 \
-device virtio-net-pci,netdev=net0
```
(Install side: `macosvm --disk disk.img,size=32g --aux aux.img --restore UniversalMac_12.0.1_21A559_Restore.ipsw vm.json`, https://github.com/s-u/macosvm.)
### 1.2 KVM / Asahi Linux status — the crucial negative findings
**Confirmed facts:**
1. **The `vmapple` machine is not buildable on Linux hosts at all.** QEMU master `hw/vmapple/Kconfig`:
```
config VMAPPLE
depends on ARM
depends on HVF
...
select MAC_PVG_MMIO
```
(https://gitlab.com/qemu-project/qemu/-/raw/master/hw/vmapple/Kconfig). `MAC_PVG_MMIO` requires Darwin (Objective-C, ParavirtualizedGraphics.framework). So today there is **no QEMU binary on Asahi Linux that even contains the vmapple machine**.
2. **No qemu-devel series adding KVM support for macOS guests has ever been posted or merged.** Graf's v1 cover letter explicitly states the aspiration, not an implementation: *"This device model would enable very nice use cases with KVM on an Asahi Linux device."* In the 2024 review thread Graf himself mused *"(I wonder if this works on KVM on Asahi Linux by the way. apple-gfx-vmapple won't work, but …)"* — i.e., untested, unsupported (https://lists.gnu.org/archive/html/qemu-arm/2024-10/msg00154.html).
3. What porting to KVM would need (informed analysis, partly speculation): drop/guard the `MAC_PVG_MMIO` select (run headless/VNC or with a non-Apple display), fix GICv3-in-kernel vs. software-GIC assumptions in `create_gic()`, replace HVF-specific sysreg handling, and deal with `-cpu host` quirks. The qtest patch notes vmapple hard-requires the `host` CPU type, which does exist under KVM.
4. **Related Asahi/Linux-kernel groundwork that *did* happen** (relevant to your hypervisor plan, all confirmed):
- KVM/arm64 on Apple Silicon works since 2021 (marcan + Marc Zyngier; M1's AIC natively virtualizes the GIC CPU interface — Asahi progress report 2021-03: https://asahilinux.org/2021/03/progress-report-january-february-2021/).
- marcan's `[PATCH 0/4] arm64: Support the TSO memory model` (2024-04-11, https://patchew.org/linux/20240411-tso-v1-0-754f11abfbff@marcan.st/) — Apple IMPDEF ACTLR_EL1 TSO for Rosetta/FEX; cover notes "KVM support for this is left for a future patchset".
- #asahi-dev IRC logs (2023-09-10) show marcan/maz discussing AIDR_EL1/ACTLR_EL12 exposure to KVM guests — Apple-IMPDEF CPU-feature exposure to guests was known-incomplete (KVM exposing host MIDR/AIDR without the features).
5. The specific items in your prompt ("PMU emulation, apple-specific CPU features, GIC, xnu quirks, `-cpu host` handling" as a posted series) do **not** correspond to any merged or posted KVM work I could find — this appears to be a conflation of the vmapple (HVF) series with Asahi KVM discussions. Mark as **not found / likely doesn't exist as described**.
### 1.3 Performance/limitations of macOS-in-QEMU today (HVF path)
- Networking: `virtio-net-pci` works in vmapple guests — **macOS ships its own virtio-net/virtio-blk drivers in the vmapple kernel** (Apple's closed-source kexts; that's why QEMU needs only standard virtio devices). Slirp user networking; vmnet.framework backend exists in QEMU for macOS hosts but bridged networking needs entitlements.
- Display: `apple-gfx-mmio` gives Metal-backed 3D via PVG (host macOS only). Otherwise serial + VNC (the docs suggest port-forwarding 5900 to the guest's Screen Sharing).
- Input: USB XHCI kbd/tablet (with the interrupter-mapping workaround).
- GPU for compute/ML in guest: works via PVG Metal passthrough on HVF hosts; nothing on Linux hosts.
---
## 2. macOS guest boot mechanics
**Confirmed:**
- **Real hardware chain:** Boot ROM → LLB → iBoot → kernelcache (XNU + boot kexts, built by `kmutil`) → launchd. iBoot passes boot args and the hardware description via **device tree** (Apple ADT, not Linux FDT semantics). (https://www.macinternals.app/en/blog/how-macos-boots)
- **In Virtualization.framework, iBoot is replaced by `AVPBooter` (`AVPBooter.vmapple2.bin`)**, a bootloader blob shipped inside the framework; the guest sees the "vmapple" device model, an auxiliary storage volume (NVRAM/RTC/policy), a machine identifier containing an ECID/UUID, and virtio devices. There is **no iBoot, no SMC, no ANS/NAND emulation** — the guest kernel is the special "vmapple" kernelcache variant that expects paravirtualized devices. QEMU's vmapple machine consumes exactly this: `-bios AVPBooter…`, aux+root as pflash, Apple-variant virtio-blk for aux/root, `uuid=` = ECID.
- **No SMC/ANS needed** for the arm64 VZ path (unlike x86 macOS, which needs `isa-applesmc,osk=…`).
- **Install media:** macOS restore IPSW images (e.g. `UniversalMac_12.0.1_21A559_Restore.ipsw`), restored into a blank disk by a VZ-based tool (macosvm, tart, vfkit `--bootloader macos`, Code-Hex/vz examples). QEMU cannot do the restore itself — the guest must be pre-provisioned.
- **Direct kernel boot of XNU in QEMU:** exists only as research hacks under **TCG**, not as a supported path:
- Zhuowei Zhang's "Booting a macOS Apple Silicon kernel in QEMU" (2020-11-09, https://worthdoingbadly.com/xnuqemu3/): patched QEMU (`github.com/zhuowei/qemu` branch `a12z-macos`), PAC neutered, hand-edited iPad device tree, `-kernel bootcache-arm64e` direct boot of macOS 11 beta XNU up to launchd — no disk, no drivers. Lineage: his iOS-QEMU work → Aleph Security's xnu-qemu-arm64 iOS emulation platform.
- **pongoOS** (checkra1n team's boot environment): a bare-metal iBoot-exploit payload for iOS/Apple research; it can boot XNU on real hardware with hooks. Not part of any QEMU path; for your project it matters only as prior art for "pre-kernel environment that chainloads XNU on Apple Silicon."
- **m1n1** (Asahi): the directly relevant prior art for a type-1 hypervisor booting macOS. m1n1 runs at EL2, can boot Linux *or macOS* as a guest, traps MMIO via stage-2 faults, traces everything over a Python/USB proxy, and virtualizes UART (https://asahilinux.org/docs/sw/m1n1-user-guide/, "Running a macOS kernel as a m1n1 hypervisor guest"; fork example: https://github.com/jevinskie/m1n1-xnu-boot). This is how Asahi reverse-engineered Apple's hardware, and is the closest existing thing to "UniversalisOS hosting XNU."
---
## 3. Alternatives and complements
**Confirmed:**
- **Virtualization.framework (VZ)** — Apple's high-level API (macOS 11+; macOS guests on Apple Silicon since macOS 12/Monterey). Boots via AVPBooter from IPSW restore images. Wrappers:
- **tart** (Cirrus Labs): CLI/OCI-image VZ manager for macOS and Linux guests; standard in CI (GitHub Actions self-hosted runners).
- **crc-org/vfkit**: primarily Linux VMs, but **does support macOS guests** via `--bootloader macos,machineIdentifierPath=…,hardwareModelPath=…,auxImagePath=…` (issue crc-org/vfkit#139/#148; added ~2024).
- **UTM**: uses VZ ("Apple Virtualization" mode) for macOS guests, QEMU (HVF) for everything else.
- **AppleContainer / containerization** (Apple, 2025): per-container Linux microVMs via VZ — Linux guests only, not macOS.
- **VZ hard limits (confirmed from Apple docs / ecosystem analyses):**
- Guest macOS versions: host version **and up to two major versions older** ("n-2" rule).
- **Concurrency: max 2 macOS VMs** — enforced in XNU itself (`hv_apple_isa_vm_quota` counter), matching the EULA; Linux VMs unlimited. (Analysis: https://github.com/projecteru2/cocoon/issues/5)
- VZ requires a graphics device config for macOS guests (headless works by not attaching a window — tart does this).
- No App Store/FairPlay DRM in guests; iCloud sign-in only from macOS 15 guests.
- **Nested: `isNestedVirtualizationSupported` — "available for Mac with the M3 chip, and later", macOS 15+** (https://developer.apple.com/documentation/virtualization/vzgenericplatformconfiguration/isnestedvirtualizationsupported). vfkit `--nested` (v0.6.0+) and krunkit expose it.
- **QEMU cannot use VZ:** correct — upstream QEMU has no Virtualization.framework backend; the only macOS accelerator is **HVF** (Hypervisor.framework). (UTM bridges both worlds as separate backends.)
- **HVF aarch64 in QEMU:** Alexander Graf's `hvf: Implement Apple Silicon Support` series (v1 Nov 2020 … v8 mid-2021, e.g. https://patchew.org/QEMU/20201211151300.85322-8-agraf@csgraf.de/) — **merged in QEMU 6.2 (released 2021-12-14)**: "macOS hosts with Apple Silicon CPUs now support 'hvf' accelerator for AArch64 guests" (https://www.qemu.org/2021/12/14/qemu-6-2-0/). Fully mature today for Linux/Windows-arm64 guests on macOS hosts.
---
## 4. Nested virtualization
**Hardware (confirmed):**
- **M1: no FEAT_NV at all — hardware-assisted nested virtualization is impossible.** EL2 registers are not accessible from EL1 guests. (apple.stackexchange #466761, answer by jksoegaard — widely cited and consistent with marcan's statements.)
- **M2 (ARMv8.6-A) and later: FEAT_NV2 present in silicon.** Apple only *exposes* it via VZ on M3+ (macOS 15), but the hardware feature exists on M2.
**Linux KVM host side (confirmed):**
- Marc Zyngier's multi-year series — v10 `[PATCH v10 00/59] KVM: arm64: ARMv8.3/8.4 Nested Virtualization support` (2023-05), then v11 `[PATCH v11 00/43] … (FEAT_NV2 only)` (2023-11-20, dropping FEAT_NV since no shipping hardware has NV-without-NV2). Merged upstream incrementally across 6.86.16; a **major arm64 KVM refactor landed in 6.16** that practical reports treat as the baseline. VNCR_EL2/NV2 fast-path work continued into 2025 (e.g. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20250215150134.3765791-11-maz@kernel.org/).
- Activation: boot host with `kvm-arm.mode=nested`; success shows `kvm [1]: VHE+NV2 mode initialized successfully`.
- **QEMU userspace side:** series by Haibo Xu (2021), Miguel Luis (2023), Eric Auger respin `[RFC v3 0/5] ARM Nested Virt Support` (2024-03, https://lists.gnu.org/archive/html/qemu-arm/2024-03/msg00871.html): `-machine virt,accel=kvm,virtualization=on` via `KVM_CAP_ARM_EL2`/`KVM_ARM_VCPU_HAS_EL2`. Present in QEMU 10.x; a Fedora/Asahi user reports distro QEMU 9.2.4 was *missing* pieces and 10.2.0 works (exact upstream merge version not pinned down — likely 9.2/10.0 era; mark as approximate).
**First-hand report on Asahi (Jan 2026, confirmed existence, experimental quality):** Fedora discussion (https://discussion.fedoraproject.org/t/nested-virtualization/179358): on an **M2 Mac with Asahi Linux, kernel 6.16+, QEMU 10.2, `kvm-arm.mode=nested`, `-M virt,accel=kvm,virtualization=on`**, an L1 Ubuntu guest saw KVM and L2 boot began; hit `kvm [1]: nv: … PAGE_SIZE not supported at Stage-2, giving up` (16K-page host issue) and Windows 11 arm64 L2 hung at bootmgr. Ampere's Dave Neary (May 2026): nested on ARM64 "still a very recent feature… not really ready for prime time" (https://community.amperecomputing.com/t/nested-virtualization-on-ampere-arm64/3399).
**Implication for UniversalisOS (analysis):** if Asahi Linux runs as a *guest* of your hypervisor and you want QEMU+KVM inside it, your hypervisor must implement the EL2-virtualization contract KVM expects (HCR_EL2.NV/NV2, VNCR_EL2, shadow S2, vGIC maintenance IRQ…) — i.e., your hypervisor plays L0 like Linux 6.16's KVM does. On M1 that's impossible in hardware. On M2+ it's possible but you inherit a moving target. Running QEMU **bare-metal-adjacent** (directly on your type-1, or in a privileged personality) avoids the problem entirely.
---
## 5. VirtIO drivers for macOS guests & display story
**Confirmed:**
- **Apple's own virtio drivers:** the arm64 "vmapple" macOS kernel (12+) ships closed-source virtio drivers for exactly the VZ device set: virtio-blk (with Apple extensions), virtio-net, virtio-rng, virtio-console/socket, PVG graphics. This is what QEMU's vmapple machine relies on (`virtio-net-pci` works out of the box). x86-64 macOS (10.14.4+/Mojave) briefly gained virtio-blk/9p/cirrus/stdvga kexts discovered by Gerd Hoffmann (2019, https://passthroughpo.st/mac-os-adds-early-support-for-virtio-qemu/) — legacy-mode only; virtio-net was never shipped by Apple for x86.
- **Third-party XNU virtio kexts:** Phil Dennis-Jordan's **virtio-net.kext** (virtio-osx lineage, ~20112013, mirrored at PassthroughPOST/Hackintosh-KVM) — Intel-only, ancient (OS X 10.510.x era), predates arm64 and modern kext notarization/SIP. No maintained arm64 virtio-net/block kext exists publicly; on arm64, third-party kexts additionally require reduced security. **Verdict: do not plan on custom virtio kexts for arm64 macOS guests; use Apple's in-box vmapple-kernel drivers.**
- **Display:** for arm64 guests: PVG via `apple-gfx-mmio` (host macOS only) or headless+VNC/SSH. No virtio-gpu/ramfb driver exists for XNU on arm64 (UTM's virtio-ramfb/viogpudo story is Windows/Linux only). For x86-64 macOS guests: `apple-gfx-pci` (merged in QEMU 9.2, same series family) gives Metal-backed 3D on macOS hosts with Metal GPUs; otherwise stdvga/VNC.
- **Overall usability today:** on macOS hosts, vmapple+QEMU is "just about usable" (authors' words) for macOS 12: SSH/VNC in, USB input laggy-but-working after the XHCI fix, no Rosetta, no install-in-QEMU, no 13+. It's a research/CI substrate, not a daily-driver VM. On Linux hosts: nothing.
---
## 6. Demos, blogs, repos (curated)
- QEMU vmapple docs (canonical, with full CLI): https://www.qemu.org/docs/master/system/arm/vmapple.html
- Graf v1 series w/ install+run instructions: https://patchew.org/QEMU/20230614224038.86148-1-graf@amazon.com/
- Dennis-Jordan v17 (final upstream form): https://patchew.org/QEMU/20250112210056.16658-1-phil@philjordan.eu/
- QEMU issue #2705 (XHCI/macOS quirk): https://gitlab.com/qemu-project/qemu/-/issues/2705
- zhuowei, "Booting a macOS Apple Silicon kernel in QEMU" (TCG direct XNU boot): https://worthdoingbadly.com/xnuqemu3/
- Asahi m1n1 user guide (macOS as m1n1 hypervisor guest): https://asahilinux.org/docs/sw/m1n1-user-guide/
- Asahi 2021 progress report (KVM on M1, GIC virtualization): https://asahilinux.org/2021/03/progress-report-january-february-2021/
- marcan TSO series: https://patchew.org/linux/20240411-tso-v1-0-754f11abfbff@marcan.st/
- Nested on Asahi M2 field report: https://discussion.fedoraproject.org/t/nested-virtualization/179358
- KVM NV2 v11: https://lore.kernel.org/linux-arm-kernel/20231120131027.854038-1-maz@kernel.org/T/
- QEMU 6.2 HVF-aarch64 release note: https://www.qemu.org/2021/12/14/qemu-6-2-0/
- x86-64 counterpoint (not your target, but mature): OSX-KVM/OpenCore boots up to macOS 15 Sequoia under QEMU/KVM on Intel/AMD (https://github.com/kholia/OSX-KVM; kraxel's 2017 guide https://www.kraxel.org/blog/2017/09/running-macos-as-guest-in-kvm/).
- macosvm (VZ provisioning CLI): https://github.com/s-u/macosvm ; vfkit: https://github.com/crc-org/vfkit ; tart: https://github.com/cirruslabs/tart
---
## Honest maturity assessment for your porting plan
| Goal | Status today | Maturity |
|---|---|---|
| macOS 12 guest in QEMU on **macOS host** (HVF, vmapple) | Upstream QEMU ≥ 10.0, documented | Usable for CI/research; rough edges |
| macOS 1315/26 guest in QEMU | **Not working** anywhere (VZ-only) | Blocked on early-boot investigation; no public progress since 2025 |
| macOS guest in QEMU on **Asahi Linux / KVM** | **Does not exist**; machine doesn't even build for Linux (`depends on HVF`) | Greenfield. Graf flagged it as desirable in 2023; nobody has posted patches |
| Nested KVM on Apple Silicon Linux (M2+) | Kernel 6.16+ + QEMU 10.x, partial | Experimental; 16K stage-2 and Windows issues; "not prime time" |
| Nested virt on M1 | Impossible (no FEAT_NV) | Dead end |
| Booting XNU under a research EL2 hypervisor | m1n1 does this daily on bare metal | Proven prior art for UniversalisOS |
**Speculation flags:** (a) exact QEMU release that completed KVM `virtualization=on` support (between 9.2 and 10.2 — confirmed working at 10.2, absent at distro 9.2.4); (b) the amount of work to KVM-ify vmapple — the GIC/sysreg/HVF-isms look modest in code size but the macOS-13+ early-boot failure is unsolved even on HVF, and may be CPU-behavior-related (the authors themselves suspect "differences between Apple M series CPUs and TCG's aarch64 implementation"), which could equally bite KVM; (c) feasibility of guest virtio drivers beyond Apple's in-box set on arm64 macOS — no public arm64 kext exists, so assume in-box vmapple drivers only.
**One-line bottom line for the plan:** on Apple Silicon, "QEMU runs macOS" today means *QEMU 10+ `vmapple` on a macOS host via HVF, macOS 12 guests only*. Making it work under KVM on Asahi (or inside your hypervisor) is unclaimed territory: the realistic engineering path is to fork/lift `hw/vmapple` off its HVF dependency, solve the macOS 13+ early-boot blocker, and provision guests from IPSW via a VZ tool on a Mac (or replicate AVPBooter's contract yourself, m1n1-style).

View file

@ -0,0 +1,128 @@
All research complete. Here is the structured report.
# Research Report: Apple Silicon Emulation, QEMU Internals, XNU Boot, Type-1 Hypervisors & Virtualization Hardware
*Stream 3 of the UniversalisOS porting plan — prepared 2026-07-12. All claims sourced; uncertainty flags marked ⚠️.*
---
## 1. Emulating Apple Silicon hardware in QEMU (any host)
### 1.1 Project lineage (chronological)
| Era | Project | What it did | Status |
|---|---|---|---|
| 2018 | **zhuowei** (`worthdoingbadly.com/xnuqemu2/`, `xnuqemu3/`) | First XNU arm64 boot in modified QEMU: iOS 12 kernel to launchd (2018), then **macOS 11 arm64e kernelcache to launchd** on a `macos11-j273-a12z` machine (Nov 2020) — "completely useless" but proved XNU boots in QEMU | Archived; foundational |
| 20192021 | **Aleph Security `xnu-qemu-arm64`** + `xnu-qemu-arm64-tools` (Jonathan Afek) | iOS 12.1 on emulated iPhone 6s Plus (t8015) to interactive bash, launchd services, R/W block device, TCP tunnel, custom IOKit driver, KVM acceleration via a custom LKM (`xnu-kvm-lkm`). Tools repo: kernel extraction (ASN.1/LZSS), GDB/Ghidra scripts | **Abandoned/read-only** (per TruEmu BH USA 2022 talk: "hard to maintain and abandoned"). Still runs; the eShard team reproduced it in 2024 |
| 2020 | **Corellium "Project Sandcastle"** | ⚠️ *Correction to the prompt's premise*: Sandcastle is **not QEMU work** — it's Corellium's Linux/Android-10 port booted on a **real iPhone 7 (A10)** via checkm8/checkra1n + pongoOS. Released 6 Mar 2020, inactive since 8 Mar 2020. Repo: `github.com/corellium/projectsandcastle`, kernel fork `corellium/linux-sandcastle` | Inactive |
| 20202021 | **Cylance/BlackBerry `macos-arm64-emulation`** | QEMU 5.1 patchset booting macOS 11 (Big Sur) arm64 recovery to shell on Intel hosts, pre-built dtb/kernel/ramdisk; derivative of zhuowei's a12z work | Archived, still runnable (documented at ku.nz/blog/appleonintel.html) |
| 2022 | **TrungNguyen1909/qemu-t8030** ("TruEmu", BlackHat USA 2022) | iPhone 11 (t8030/A13) machine in QEMU 6.x: iOS 1416 claimed, USB restore via companion QEMU instance, ANS2 NVMe namespaces, kernel patching inside QEMU, SEP stub. **The public tree never fully boots stock iOS** (widely reported) | Last commit Oct 2022 — **stale** (2.2k★) |
| 20222023 | **devos50's QEMU forks** | iPod touch 1G (iOS 1.1) and iPhone 2G to SpringBoard using iEmu/xnu-qemu-arm64/TruEmu lineage + OpeniBoot | Slow research pace |
| 2023 | **ChefKissInc — QEMUAppleSilicon → renamed "Inferno"** | Active fork/rewrite of qemu-t8030 | **Active as of 2026-06** (see below) |
| 20242025 | **eShard** (commercial research, blog-only) | iOS 14 partial emulation based on qemu-t8030 ported to QEMU 8.2.1, using **pongoOS + checkra1n KPF** loaded from enlarged SRAM instead of in-QEMU kernel patching; chip-id spoof to t8015 to get software-rendered framebuffer; reached lock screen (part 1, Apr 2025) and "lots of modern apps" (part 2, 2025) | Source **not published** |
### 1.2 ChefKissInc/Inferno (current flagship)
- Repo: `github.com/ChefKissInc/Inferno` (formerly `QEMUAppleSilicon`; theapplewiki confirms the rename, Feb 2026). 3.8k★, GPL-3/AGPL-3. Last push observed **2026-06-18** (recent commits: virgl build fixes, libtasn1 meson fixes, `sep: avoid pointer alias`). CI uses dependabot — genuinely maintained.
- **Machine models live in `hw/arm/apple-silicon/`** (verified via GitHub API): `t8030.c` + `t8030-config.c.inc` (iPhone 11/A13), `a13.c`, `a13_gxf.c/.h` (Apple GXF guarded-execution/genter/gexit support), `s8000.c` + `s8000-config.c.inc` (A9 — newer addition), `sep.c` + `sep-sim.c` (Secure Enclave Processor emulation + simulation), `dart.c` + `dart-stub.c` (IOMMU), `sart.c` (NVMe SART), `boot.c`, `dt.c` (ADT/device-tree), `mem.c`, `kernel_patches.c` + `patcher.c` (runtime XNU patching), `img4.asn1`/`art.asn` + libtasn1 (IMG4/ART parsing), `mt-spi.c` (multitouch SPI), `lm-backlight.c`. Storage is presented as **ANS2 NVMe namespaces** (`-device nvme-ns,…bus=nvme-bus.0`, plus `apple-nvram` namespace — see Discussion #34).
- **What boots**: iPhone 11 (t8030) running **iOS 14.x** to SpringBoard with SEP emulation (ChefKiss posted video of Calculator/Settings working, "minor graphical glitches"). Wiki notes support for older/newer iOS "reportedly upcoming". No macOS boot; no M-series machine model yet (theapplewiki: "aims to emulate A-series and M-series"). ⚠️ Some of the SEP/SpringBoard capability was shown on social media before full public release; exact public-tree capability at HEAD should be re-verified at planning time.
- Emulation General Wiki (2026-05 snapshot) also notes a **separate unreleased fork** by another developer reaching SpringBoard with full SEP, archived mysteriously (Corellium-hire speculation) — ⚠️ rumor-grade.
- **eShard part 2 (2025)** demonstrates the practical ceiling today: partial iOS 14 with many apps, software rendering, PongoOS patching. No GPU emulation anywhere; Metal forwarding is "a long road" (eShard).
**Maturity assessment**: research-grade, single-SoC (A13), iOS-only, no GPU, slow (TCG; KVM only on the old Aleph tree via a hack). Nothing usable as-is for a macOS-targeting hypervisor, but `hw/arm/apple-silicon/` is the **best existing public reference implementation** of Apple SoC device semantics (ADT, ANS2, DART, SART, SEP mailbox, GXF) in C — high reuse value as documentation-by-code.
---
## 2. QEMU ARM architecture relevant to a type-1 hypervisor project
### 2.1 The `virt` machine (baseline knowledge, verified against qemu.org docs/master)
- Versioned machine type (`virt`, `virt-9.0`, …) in `hw/arm/virt.c`; auto-generates DTB (passed in x0 for Linux-boot-protocol kernels, or at 0x4000_0000 for bare-metal). Devices: 12 PL011 UART, PL061 GPIO, PL031 RTC, fw_cfg, GICv2M/ITS, optional machine-wide or per-root-bus **SMMUv3** (`iommu=smmuv3`, `-device arm-smmuv3,primary-bus=…`), 32 virtio-mmio slots, PCIe, CXL, ACPI optional.
- **GIC**: `gic-version=2|3|4|host|max`. GICv2 → ≤8 CPUs; GICv3 → ≤512; GICv4 requires `virtualization=on`. **`-cpu host` only under KVM/HVF; `-cpu max` = host under KVM/HVF, best-effort under TCG; migration unsupported with `max`.**
- Under **HVF on Apple Silicon**: `-M virt,highmem=off` historically required (older HVF couldn't do >32-bit IPA; the highmem requirement was lifted in later QEMU releases). HVF backend: Alexander Graf's 18-patch series merged for QEMU 6.2 (late 2021), `target/arm/hvf/hvf.c` — full sysreg-sync table, vtimer offset (`hv_vcpu_set_vtimer_offset`), WFI handling, PSCI, `-cpu host`, in-kernel-GIC-less design: **HVF does all interrupt injection via `hv_vcpu_set_pending_interrupt` and QEMU emulates the GIC in userspace** (HVF exposes no GICv3 virtual CPU interface; contrast with §5). HVF limitations at merge: no live migration/savevm, gdbstub SP quirks, no GICv3 acceleration.
### 2.2 Adding a new machine type (for UniversalisOS prototyping)
Canonical path: new file in `hw/arm/` (or a subtree like Inferno's `hw/arm/apple-silicon/`), a `MachineClass`/`MachineState` subclass, `DEFINE_MACHINE` or `type_init`-registered `machine_init`, Kconfig + meson entries. Inferno is the worked example of an SoC-family subtree with config-include pattern (`t8030-config.c.inc`, `s8000-config.c.inc`). For a hypervisor research project, QEMU gives you: QOM device framework, address-space/MemoryRegion model (fine-grained MMIO traps), TCG for bring-up before EL2 exists, gdbstub, and the whole virtio device + block/net backend stack.
### 2.3 Reusing QEMU assets inside a type-1 hypervisor
- **Precedent — Xen qemu-dm/stubdom**: Xen runs QEMU as the device model in dom0 (or a Mini-OS stubdom) per HVM guest; the hypervisor traps I/O and forwards to qemu-dm via IOREQ. This is the direct architectural template for "QEMU devices in a hypervisor domain". License note: QEMU is GPLv2 — embedding means the device-model process is GPL; keeping it in a separate domain/process (like Xen) is the standard containment.
- **vhost / vhost-user**: the decoupling layer — data-plane backends (net/blk/scsi/gpu/vsock) run in-kernel (vhost) or in a separate userspace process over a UNIX socket (vhost-user, spec in QEMU `docs/interop/vhost-user.rst`). rust-vmm's `vhost-user` crates and SPDK/DPDK backends interoperate. This is the cleanest way to reuse QEMU *backends* without QEMU itself: UniversalisOS could implement the vhost-user *frontend* side.
- **VFIO**: QEMU's `hw/vfio/` is the reference for device passthrough via Linux VFIO (needs IOMMU with stage-2 for DMA isolation — see §5 on DART limitations).
- **DTB generation**: QEMU's `hw/arm/virt.c` + libfdt path is directly liftable; Inferno's `dt.c` shows ADT-style tree construction.
- ⚠️ QEMU device *models* are tightly coupled to QOM/qdev and the main-loop; in-process reuse inside a non-QEMU hypervisor is impractical — out-of-process (qemu-dm style) or vhost-user is the realistic reuse level.
### 2.4 Rust VMM alternatives on aarch64 / Apple Silicon
| Codebase | aarch64/KVM | Apple Silicon host support | Notes |
|---|---|---|---|
| **Firecracker** | Production (Graviton, since 2019) | **No** (KVM-only). A Jan-2025 PoC fork boots aarch64 Linux on macOS via Virtualization.framework (firecracker-microvm/firecracker#5017, `drink7036290/firecracker` branch `macos_avf`) — explicitly out of scope upstream | ~50k LOC Rust; rust-vmm crates reusable independently (kvm-ioctls, vm-superio, vm-fdt, vmm-sys-util) |
| **crosvm** | Supported on aarch64 KVM (ChromeOS/Android/ARM servers) | **No HVF backend** (KVM/minijail-centric). ⚠️ No evidence of Apple Silicon support | Rich device set (virtio-gpu, etc.) |
| **Cloud Hypervisor** | Production aarch64/KVM | No HVF | rust-vmm based; vhost-user, VFIO, hotplug; ~50k LOC |
| **libkrun** (`containers/libkrun`) | KVM on Linux | **Yes — HVF backend for aarch64 macOS is a first-class variant** (powers krunkit/podman-machine, muvm GPU VMs, crun krun). Apache-2.0 | The **only mature Rust VMM with an HVF path**; its `hvf` backend is the seed of… |
| **ignition** (`github.com/vadika/ignition`, Jun 2026) | — | **Yes** — new research microVM modeled on Firecracker architecture, HVF backend reworked from libkrun, rust-vmm building blocks; boots Linux, SMP, virtio set, snapshots, fuzzing. Very fresh | Worth tracking; single-author research |
**Maturity assessment**: for a UniversalisOS VMM written in Rust targeting both Linux/KVM-on-Asahi and macOS/HVF hosts during development, **rust-vmm crates + libkrun's HVF backend** is the most reusable code in existence today. Firecracker/crosvm/CH give you design + crates but no Apple-host path.
---
## 3. Booting XNU/Darwin outside Apple hardware
- **XNU in QEMU**: all work is lineage §1.1 (zhuowei 2018/2020 → Aleph → Cylance → t8030 → Inferno → eShard). No one boots **macOS (full OS, with GUI)** in pure emulation; the ceiling is iOS 14 partial (Inferno/eShard) and macOS recovery/kernel to launchd or limited shell (zhuowei/Cylance 2020).
- **pongoOS/checkra1n**: checkm8 bootrom exploit covers **A8A11 only** — pongoOS **cannot run on real t8030 (A13) hardware**; eShard's trick was loading pongoOS *inside the emulator* from SRAM. checkra1n-adjacent tooling (ipwndfu, gaster, palera1n) is irrelevant to A13+/M-series. M-series instead has m1n1's 1TR/boot-policy path (§4).
- **AVP / Apple Virtual Platform research** (the key §3 finding): macOS ARM guests under Virtualization.framework boot a distinct platform — board `vma2ap`/BDID 0x20, kernel flavor `RELEASE_ARM64_VMAPPLE`, boot chain **`AVPBooter.vmapple2.bin`** (an iBoot-stage-0 variant shipped inside `Virtualization.framework/Resources/`, not signature-checked). Research artifacts:
- **`github.com/saagarjha/VirtualApple`** (verified live) — canonical Virtualization.framework demo with GUI/install.
- **`github.com/NyanSatan/Virtual-iBoot-Fun`** (Dec 2021) — boots *patched* AVPBooter with `amfi_get_out_of_my_way=1`, sends iBSS/iBEC/devicetree/ramdisk/trustcache/kernelcache over the VM's emulated DFU USB channel with `irecovery`, applies a LocalPolicy, and reaches a **patched XNU kernel with GDB server and debug UART**. Includes bsdiff patches for iBoots and kernel. Requires the `com.apple.private.virtualization` private entitlement for custom-ROM/GDB/production-mode-demote.
- Steven Michaud's gist (May 2026) extends this to **third-party kexts in macOS guests**, documenting that Virtualization.framework's boot images ship **unencrypted** — a reverse-engineering goldmine.
- eclecticlight.co's VM-boot series documents the runtime artifacts: `HardwareModel` (150 B), `MachineIdentifier` (~60 B), `AuxiliaryStorage` (~34 MB: NVRAM + boot-loader state), virtio bring-up (`AppleParavirtIOSurface`, `AppleCredentialManager: init: called, Apple Virtual Platform`).
- **What a macOS ARM guest *absolutely requires* from its VMM** (evidence-based):
1. The **AVP boot environment**: AVPBooter stage-0 semantics, LocalPolicy/Image4 validation (or patching), AuxiliaryStorage/NVRAM, MachineIdentifier/HardwareModel/ECID properties, DFU-mode USB restore channel for install.
2. **Paravirtualized devices**: virtio-blk/net/console/rng/vsock/socket, Apple Paravirtualized Graphics (Metal forwarding) for GUI, shared folders (virtiofs-like).
3. ⚠️ **No SMC, no AppleHPM**: those are physical-Mac devices; VM guests don't see them (the x86-Mac SMC requirement does not carry over). ⚠️ The "AVP coprocessor" framing in the prompt conflates things: publicly, "AVP" names the **virtual platform/boot chain** (AVPBooter, vma2), not a documented separate silicon coprocessor; macOS guests do get **virtualized credential/enclave services** (AppleCredentialManager "Apple Virtual Platform" instance; Virtualization.framework provides a virtual SEP-like facility for key handling — ⚠️ internal details not publicly documented beyond NyanSatan/saagarjha work).
4. A hypervisor that tolerates XNU's **GXF/SPRR/PPL usage** — XNU expects PPL (GL2) primitives; m1n1 had to grow GXF support (`src/gxf.c`, `gl2_call()`) to run XNU as a guest.
- **macOS under m1n1 (real hardware, EL2)**: documented at `asahilinux.org/docs/sw/m1n1-hypervisor/` — full macOS 11.5.2 to login window with WiFi under the Python-driven m1n1 hypervisor (~2 min boot, single CPU, MMIO-traced). This is the **only working public "macOS as a guest under a non-Apple hypervisor"** setup.
---
## 4. Type-1 hypervisors on Apple Silicon
| Project | Status | Notes |
|---|---|---|
| **m1n1 hypervisor** (AsahiLinux/m1n1, MIT) | **Active, mature as a research HV** | EL2, stage-2 MMIO trapping, Python proxyclient over USB-UART (`proxyclient/hv/*.py` trace scripts), gdbserver, GXF/GL2 call support, runs XNU and Linux guests. Explicitly designed as an RE/tracing tool, not a production partitioner; **ABI unstable**. `run_guest.py`, `run_guest_kernel.sh` workflows documented. |
| Derivatives of m1n1 hv | **AppleWOAProject** (Windows-on-Apple, `amarioguy`) plans to fork m1n1's hv as the EL2 layer to route interrupts to Windows EL1 (Jan 2025 update); **asahi_neo** (rusch95, Mar 2026) uses m1n1 hv mediation as one intercept strategy for A18-Pro Linux shim. No production type-1 built on m1n1 exists. | — |
| **Xen on Apple Silicon** | **No port exists.** Sole artifact: xen-devel thread **"Xen for Apple Silicon (M1 and beyond)" (Jul 2024)** — feasibility discussion only (16K-page friction with 4K Xen, ADT vs FDT, firmware pairing issues; m1n1 acknowledged as the boot bridge). Stefano Stabellini engaged; nothing landed. | Thread: lists.xenproject.org/archives/html/xen-devel/2024-07/msg01391.html |
| **seL4 on Apple Silicon** | **No port, none planned.** Verified against official supported-platforms + Microkit lists (docs.sel4.systems/Hardware, Microkit platforms): no Apple SoC. seL4 aarch64 virt support targets GIC/SMMU-based platforms; Apple-specific AIC/DART/SPRR would all be new work, and EL2 entry requires the m1n1/iBoot boot path. | — |
| **Linux KVM on M1/M2 (as partitioner base)** | **Works downstream (Asahi kernels); partially upstream** | Marc Zyngier got Linux VMs running on KVM/Asahi in **early 2021** (Asahi progress report Mar 2021). Fedora Asahi Remix ships KVM enabled; QEMU/KVM on M1/M2 is daily-driver usable (fluxcoil blog 2024; Incus/virt-manager reports Jan 2026). Upstream has been absorbing Apple bits: **Linux 6.15 merged `kvm-arm64/pmuv3-asahi`** — Oliver Upton's 14-patch series virtualizing PMUv3 on Apple M1/M2 via IMPDEF traps (HACR_EL2 bit 56), tested on M2 Pro with Debian+Windows guests. **Nested virtualization works on M2 with kernel ≥6.16** (`kvm-arm.mode=nested` → "VHE+NV2 mode initialized"; M1 lacks FEAT_NV entirely — Fedora discussion Jan 2026). dmesg on M2 shows the Apple quirks: "Non-architectural vgic, tainting kernel", "GICv3: no GICV resource entry", "broken locally generated SEI", "sysreg trapping enabled ([G0G1D], reduced performance)". **Verdict: KVM-on-Asahi is the only near-mainline, multi-guest-capable virtualization base on Apple Silicon today** — a partitioning-hypervisor personality on top of it is feasible engineering, not science. |
| **Apple's own XNU hypervisor** (Hypervisor.framework, EL2 under XNU) | Production since macOS 11 (2020); Virtualization.framework since 11, macOS guests since 12 | XNU runs at EL2 and multiplexes EL1 guests (that's why "nested virtualization in a macOS VM is impossible" — guests can't get EL2). HVF API surface: hv_vm/hv_vcpu, sysreg get/set, pending-interrupt injection, vtimer offset/mask — **no GIC CPU-interface virtualization, no nested** (as of macOS 15; ⚠️ unverified for macOS 26). Apple Containerization (Jun 2026, macOS 26) builds VM-per-container on VZ. |
| **Other** | Edera (commercial, Xen-derived type-1 "zones") exists on ARM servers — ⚠️ no Apple Silicon support known. No Jailhouse/ACRN/Bao port to Apple Silicon found. | — |
---
## 5. Apple Silicon hardware virtualization features (per generation)
| Feature | M1 / A14 (t8101, Firestorm/Icestorm) | M2 / A15 (t8112, Avalanche/Blizzard) | M3 | M4 / A18 (t8140…) |
|---|---|---|---|---|
| **EL2** | Present and **fully usable** — XNU uses it (HVF); m1n1 and KVM/Asahi use it. Apple's IMPDEF "HACR_EL2" and related regs are documented-by-RE in m1n1 | Present, usable; adds **FEAT_NV2-class nested support** (confirmed working with Linux 6.16 `VHE+NV2`) | Present, usable (Asahi M3 bring-up done; m1n1 hv works per IRC logs — Sonoma M3 boots under hv "without obvious issues") | Present, **but boot-object environment changed**: iBoot now configures SPTM in GL2 before handoff; normal m1n1 boot path broken (Sven Peter, Apr 2025 — "rather painful"). **Raw boot objects still drop you into EL2** with most Apple extensions disabled — fine for Linux, *but XNU can't run under the hv there*, blocking RE-driven bring-up. ⚠️ EL2 itself is not locked; the boot flow around it got harder. M5 (202526): ⚠️ no public data found |
| **SPRR / GXF / GL2** | SPRR+GXF present (A14/M1 introduced it); PPL runs at GL2 from within the kernelcache; m1n1 implements GXF (`src/gxf.c`) | SPRR+GXF; **SPTM arrives on Mac with macOS 15 on M2** (IRC: "for mac it is on M2 on macOS 15 and nothing else"; iOS: A15A17 got SPTM in iOS 17) | PPL (GL2) like M1/M2-era macOS | **SPTM mandatory in the boot path** (iPadOS 17.5 introduced SPTM on M4). SPTM is separate iBoot-loaded firmware at GL2, owns page tables, reached via `genter` from EL1/EL2; **you cannot run Linux *under* SPTM** — raw boot bypasses it. ⚠️ rusch95's RE claims macOS 26 on A18 Pro still uses PPL not SPTM — single-source, treat as provisional |
| **Interrupts (AIC vs GIC)** | AIC (Apple Interrupt Controller) is the distributor — **not** a GICD. But the M1 contains **"half a GIC"**: a GICv3 **CPU interface with virtualization (ICH_*)** usable by EL2 to give guests a near-native vGIC CPU interface; KVM-on-Asahi uses it (kernel taints: "Non-architectural vgic"). FIQ-based "Fast IPI" and guest timer delivery are Apple IMPDEF features RE'd by marcan/maz in 2021 | AIC2 (M1 Pro/Max and later; multi-die support upstreamed Dec 2021 by marcan). Same vGIC-cpuif story; nested adds another layer | AIC2 | AIC3-ish (⚠️ details still being RE'd for M4) |
| **IOMMU (DART)** | DART = simple per-stream IOMMU, **no ARM SMMU architecture, no hardware stage-1+stage-2 nesting** — streams carry single-level TTBRs (16K granule). Linux driver: `drivers/iommu/apple-dart.c` + `io-pgtable-dart.c`; RE by Sven Peter (2021). **Implication: VFIO-style passthrough to guests means the hypervisor programs DART streams itself (guest IPA→PA as the DART IOVA→PA map) — feasible but all-software; no vIOMMU assist** | DART plus **SART** (NVMe address filter) on M1 Pro/Max+ | similar | similar (⚠️) |
| **Timers** | Architectural timer with EL2 control (CNTVOFF_EL2 offsetting works — used by KVM/HVF; HVF exposes `hv_vcpu_set_vtimer_offset`). Apple IMPDEF guest-timer FIQ delivery RE'd 2021 | same + nested timer virtualization via NV2 | same | same (⚠️) |
| **PMU** | IMPDEF PMU (not architectural PMUv3); **M1/M2 expose IMPDEF traps of PMUv3 sysregs (HACR_EL2[56])** enabling trap-emulate vPMU — upstreamed in Linux 6.15 (kvm-arm64/pmuv3-asahi) with a reduced 1-event-counter vPMU | same traps | ⚠️ M3 PMU trap support not confirmed in the series (MIDR list covers M1/M2 only) | ⚠️ unknown |
| **Memory model quirks for VMMs** | 16K pages native (4K guests work — Rosetta/Docker prove it); big.LITTLE-ish heterogeneous cores break naive KVM sysreg sync (CCSIDR_EL1 fix merged for 6.3); SPRR interacts with guest page permissions — KVM guests run with SPRR effectively neutralized; XNU guests (m1n1) need GXF/PPL cooperation | + SPTM on macOS 15 guests-to-be | — | SPTM changes who owns stage-1 page tables on macOS; for a UniversalisOS design this argues for **raw-boot EL2 entry on M4** and treating PPL/SPTM as bypassed, not cooperated-with |
Key citable sources for §5: Asahi progress report Jan/Feb 2021 (AIC/GIC-virtualization, FIQ timers); marcan's AIC patches (Dec 2021, AICv2/multi-die/Fast-IPI); maz's vgic fixes (Sep 2021, "Apple M1 has half a GIC"); Oliver Upton's PMUv3-on-Apple series (v2 Feb 2025, merged 6.15); Sven Peter Mastodon (4 Apr 2025) via AppleInsider (8 Apr 2025) for M4 SPTM/GL2 boot changes; #asahi-dev IRC log 2024-07-14 (SPTM rollout matrix); Fedora nested-virt thread (Jan 2026) for M2 NV2 confirmation; rusch95/asahi_neo ARCHITECTURE.md (Mar 2026) for A18-Pro GXF/SPTM register/ABI details (⚠️ single-source).
---
## 6. Bottom-line maturity matrix for the UniversalisOS plan
| Need | Best available base | Maturity | Risk |
|---|---|---|---|
| Reference semantics for Apple SoC devices (ADT, ANS2, DART, SEP, GXF) | Inferno `hw/arm/apple-silicon/` + m1n1 `src/` | High (as documentation) | GPL-3 (Inferno) vs MIT (m1n1) — prefer m1n1 as citable reference |
| Type-1 base on M1/M2 today | Linux KVM on Asahi (6.16+), m1n1 hv for experiments | KVM: workable, daily-used; m1n1: RE-grade | KVM-on-Apple is downstream-flavored; M3/M4 device support incomplete upstream |
| EL2 entry on M4 | Raw boot object (EL2, extensions off) | Works for Linux; XNU-guest RE blocked | SPTM cohabitation unsolved; future chips may close raw boot |
| Rust VMM for dev hosts (macOS HVF + Linux KVM) | rust-vmm + libkrun HVF backend (Apache-2) | Mature on KVM; HVF path production-ish (krunkit) | HVF has no GIC acceleration, no nested |
| macOS-guest requirements spec | Virtual-iBoot-Fun + VirtualApple + Michaud gist + eclecticlight | Well-mapped boot chain | Requires private entitlements/patching; AVP internals undocumented; virtual-SEP details ⚠️ |
| iOS-in-emulation capability | Inferno / eShard | Partial iOS 14, no GPU | Not needed for UniversalisOS core; useful for SEP/ANS2 semantics |
**Explicit uncertainty flags**: (a) Inferno's exact public-tree capability at HEAD vs social-media demos; (b) macOS 26/HVF changes (nested? GIC?) — no public data; (c) whether a physical "AVP coprocessor" exists beyond the virtual-platform boot chain — evidence says no, but Apple docs are silent; (d) M3/M4 PMU-trap and nested-virt support unverified; (e) asahi_neo's A18-Pro PPL-vs-SPTM claim is single-source; (f) eShard/Inferno release timing for newer iOS support unknown.

View file

@ -0,0 +1,6 @@
#ifndef ARCH_ARM_MM_H
#define ARCH_ARM_MM_H
#include <stdint.h>
/* ARM MMU stub for host testing */
static inline uint32_t arm_page_table_base(void) { return 0x40000000; }
#endif

View file

@ -0,0 +1,9 @@
#ifndef ARCH_ARM_VM_H
#define ARCH_ARM_VM_H
#include <stdint.h>
/* ARM VM context stub for host testing */
struct arm_vm_context {
uint32_t vttbr;
uint32_t vtcr;
};
#endif

View file

@ -0,0 +1,5 @@
#ifndef ARCH_RISCV_MM_H
#define ARCH_RISCV_MM_H
#include <stdint.h>
static inline uint64_t riscv_page_table_base(void) { return 0x40000000; }
#endif

View file

@ -0,0 +1,8 @@
#ifndef ARCH_RISCV_VM_H
#define ARCH_RISCV_VM_H
#include <stdint.h>
/* RISC-V VM context stub */
struct riscv_vm_context {
uint64_t satp;
};
#endif

View file

@ -0,0 +1,5 @@
#ifndef ARCH_X86_MM_H
#define ARCH_X86_MM_H
#include <stdint.h>
static inline uint64_t x86_page_table_base(void) { return 0x40000000; }
#endif

View file

@ -0,0 +1,8 @@
#ifndef ARCH_X86_VM_H
#define ARCH_X86_VM_H
#include <stdint.h>
/* x86 VM context stub */
struct x86_vm_context {
uint64_t cr3;
};
#endif

View file

@ -0,0 +1,6 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include <stdint.h>
/* Scheduler stub for host testing */
static inline void scheduler_add_consciousness(void* ctx) { (void)ctx; }
#endif

View file

@ -0,0 +1,323 @@
/*
* Universalisos Guest Consciousness VM Context Management
* Following PikeOS virtualization patterns with safety-critical isolation
*
* This module provides VM context management for AI consciousnesses running
* as guest domains on the Universalisos type-1 hypervisor.
*/
#ifndef UNIVERSALISOS_VM_CONSCIOUSNESS_H
#define UNIVERSALISOS_VM_CONSCIOUSNESS_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/* #include "arch/arm/vm.h" */
/* #include "arch/arm/mm.h" */
/* #include "scheduler.h" */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Maximum number of consciousnesses supported simultaneously
* Following PikeOS multi-domain patterns with safety isolation
*/
#define MAX_CONSCIOUSNESS_DOMAINS 16
/*
* Consciousness VM context states
* Following PikeOS domain lifecycle management
*/
typedef enum consciousness_vm_state {
CONSCIOUSNESS_VM_UNINITIALIZED = 0,
CONSCIOUSNESS_VM_INITIALIZING,
CONSCIOUSNESS_VM_READY,
CONSCIOUSNESS_VM_RUNNING,
CONSCIOUSNESS_VM_SUSPENDED,
CONSCIOUSNESS_VM_MIGRATING,
CONSCIOUSNESS_VM_SAFE_STATE,
CONSCIOUSNESS_VM_SHUTDOWN
} consciousness_vm_state_t;
/*
* Consciousness VM context structure
* Following PikeOS VM context patterns with safety-critical parameters
*/
typedef struct consciousness_vm_context {
// Identification
uint32_t consciousness_id;
char consciousness_name[32];
// VM state management
consciousness_vm_state_t state;
uint32_t state_flags;
// CPU context (following PikeOS context save/restore)
struct {
uint32_t registers[16]; // R0-R15
uint32_t cpsr;
uint32_t spsr;
uint32_t pc;
uint32_t lr;
} cpu_context;
// Memory management (following PikeOS memory isolation)
struct {
uint32_t page_table_base;
uint32_t page_table_size;
uint32_t heap_start;
uint32_t heap_end;
uint32_t stack_start;
uint32_t stack_end;
uint32_t memory_quota;
} memory_context;
// TrustZone security (following PikeOS TZ implementation)
struct {
bool secure_mode;
uint32_t scr_register;
uint32_t nsacr_register;
uint32_t vic_range_base;
} trustzone_context;
// Real-time constraints (following PikeOS ARINC 653)
struct {
uint32_t time_partition_id;
uint32_t budget_microseconds;
uint32_t deadline_ticks;
uint32_t priority_level;
uint64_t total_cpu_time;
} realtime_context;
// Safety monitoring (following PikeOS safety patterns)
struct {
uint32_t watchdog_timeout;
uint64_t last_watchdog_feed;
uint32_t safety_violation_count;
bool bounds_checking_enabled;
bool memory_isolation_enabled;
} safety_context;
// Communication (following PikeOS IPC patterns)
struct {
uint32_t message_queue_id;
uint32_t shared_memory_regions[4];
uint32_t synapse_count;
uint32_t connected_consciousnesses[MAX_CONSCIOUSNESS_DOMAINS];
} communication_context;
// Learning capabilities (Mycelium integration)
struct {
bool learning_enabled;
float learning_rate;
float synapse_growth_rate;
float maturity_level;
uint32_t engram_count;
uint32_t max_engrams;
} learning_context;
// Platform-specific
struct {
uint32_t architecture_type; // ARM, RISC-V, x86, etc.
uint32_t platform_capabilities;
uint32_t required_peripherals;
} platform_context;
} consciousness_vm_context_t;
/*
* Consciousness VM context management API
* Following PikeOS domain management patterns with safety-critical guarantees
*/
/**
* Initialize a new consciousness VM context
*
* @param context Pointer to consciousness context structure
* @param consciousness_id Unique consciousness identifier
* @param platform_type Target platform architecture
*
* @return 0 on success, error code on failure
*
* @safety ASIL-B compliant: Performs memory validation, TrustZone setup,
* and safety checks before allowing context activation
*/
int consciousness_vm_context_init(
consciousness_vm_context_t* context,
uint32_t consciousness_id,
uint32_t platform_type
);
/**
* Destroy consciousness VM context
*
* @param context Pointer to consciousness context structure
*
* @return 0 on success, error code on failure
*
* @safety ASIL-B compliant: Performs safe shutdown, memory cleanup,
* and resource deallocation with validation
*/
int consciousness_vm_context_destroy(
consciousness_vm_context_t* context
);
/**
* Save consciousness VM context
* Following PikeOS context save patterns
*
* @param context Pointer to consciousness context structure
*
* @safety Real-time critical: Must complete within time partition
* @return 0 on success, error code on failure
*/
int consciousness_vm_context_save(
consciousness_vm_context_t* context
);
/**
* Restore consciousness VM context
* Following PikeOS context restore patterns
*
* @param context Pointer to consciousness context structure
*
* @safety Real-time critical: Must complete within time partition
* @return 0 on success, error code on failure
*/
int consciousness_vm_context_restore(
consciousness_vm_context_t* context
);
/**
* Schedule consciousness for execution
* Following PikeOS deadline scheduler patterns
*
* @param context Pointer to consciousness context structure
*
* @safety Real-time critical: Enforces time partition and deadlines
* @return 0 on success, error code on failure
*/
int consciousness_vm_context_schedule(
consciousness_vm_context_t* context
);
/**
* Preempt consciousness execution
* Following PikeOS priority-based preemption
*
* @param context Pointer to consciousness context structure
*
* @safety Real-time critical: Guaranteed bounded preemption time
* @return 0 on success, error code on failure
*/
int consciousness_vm_context_preempt(
consciousness_vm_context_t* context
);
/**
* Migrate consciousness to different platform
* Enabling hardware-agnostic consciousness deployment
*
* @param context Pointer to consciousness context structure
* @param target_platform Target platform architecture
*
* @return 0 on success, error code on failure
*
* @safety ASIL-B compliant: Validates migration safety, performs checkpoint,
* and ensures platform compatibility before migration
*/
int consciousness_vm_context_migrate(
consciousness_vm_context_t* context,
uint32_t target_platform
);
/**
* Consciousness communication via synapses
* Following PikeOS inter-partition communication
*
* @param source_context Source consciousness context
* @param target_id Target consciousness ID
* @param message_data Message data pointer
* @param message_size Message size in bytes
*
* @return 0 on success, error code on failure
*
* @safety Real-time critical: Bounded communication latency guaranteed
* @safety ASIL-B compliant: Validates message format and target safety level
*/
int consciousness_vm_context_send_synapse(
consciousness_vm_context_t* source_context,
uint32_t target_id,
void* message_data,
size_t message_size
);
/**
* Consciousness learning via Mycelium integration
*
* @param context Pointer to consciousness context structure
* @param input_data Input data pointer
* @param input_size Input size in bytes
* @param result_data Result data pointer
* @param result_size Result size in bytes
*
* @return 0 on success, error code on failure
*
* @safety ASIL-B compliant: Memory engram absorption validated for safety,
* learning rate bounded to prevent runaway adaptation
*/
int consciousness_vm_context_learn(
consciousness_vm_context_t* context,
void* input_data,
size_t input_size,
void* result_data,
size_t result_size
);
/**
* Consciousness watchdog monitoring
* Following PikeOS watchdog patterns
*
* @param context Pointer to consciousness context structure
*
* @return 0 if watchdog OK, error code if timeout
*
* @safety Safety-critical: Triggers fail-safe mode on timeout
*/
int consciousness_vm_context_check_watchdog(
consciousness_vm_context_t* context
);
/**
* Consciousness safety violation handler
* Following PikeOS safety patterns
*
* @param context Pointer to consciousness context structure
* @param violation_type Type of safety violation
* @param violation_details Additional violation details
*
* @return 0 on recovery, error code on failure
*
* @safety Safety-critical: Triggers appropriate fail-safe response
*/
int consciousness_vm_context_handle_safety_violation(
consciousness_vm_context_t* context,
uint32_t violation_type,
void* violation_details
);
#ifdef __cplusplus
}
#endif
#endif // UNIVERSALISOS_VM_CONSCIOUSNESS_H
/* Architecture type constants */
#define ARCH_ARM_V7HF 1
#define ARCH_RISCV64 2
#define ARCH_X86_64 3
/* Stub for get_system_ticks when scheduler.h not included */
/* Platform tick counter - provided by scheduler or test stubs */

View file

@ -0,0 +1,480 @@
/*
* Universalisos Guest Consciousness VM Context Management Implementation
* Following PikeOS virtualization patterns with safety-critical isolation
*
* This module provides VM context management for AI consciousnesses running
* as guest domains on the Universalisos type-1 hypervisor.
*/
#include "universalisos/vm/consciousness.h"
#include <string.h>
#include <stdatomic.h>
/* Weak default implementation - can be overridden by tests or platform */
uint64_t get_system_ticks(void);
__attribute__((weak)) uint64_t get_system_ticks(void) { return 0; }
/* Consciousness VM context pool */
static atomic_uint active_consciousness_count = ATOMIC_VAR_INIT(0);
/*
* Initialize a new consciousness VM context
* Following PikeOS domain initialization with safety validation
*/
int consciousness_vm_context_init(
consciousness_vm_context_t* context,
uint32_t consciousness_id,
uint32_t platform_type)
{
if (!context) {
return -1; /* Invalid parameter */
}
/* Safety validation: Check we have capacity */
if (atomic_load(&active_consciousness_count) >= MAX_CONSCIOUSNESS_DOMAINS) {
return -2; /* Maximum consciousnesses reached */
}
/* Initialize context structure */
memset(context, 0, sizeof(consciousness_vm_context_t));
context->consciousness_id = consciousness_id;
context->state = CONSCIOUSNESS_VM_INITIALIZING;
/* Platform-specific initialization following PikeOS patterns */
switch (platform_type) {
case 1: /* ARMv7hf */
context->platform_context.architecture_type = ARCH_ARM_V7HF;
context->trustzone_context.secure_mode = true; /* ARM TrustZone */
break;
case 2: /* RISC-V */
context->platform_context.architecture_type = ARCH_RISCV64;
context->trustzone_context.secure_mode = false; /* RISC-V PMP instead */
break;
case 3: /* x86_64 */
context->platform_context.architecture_type = ARCH_X86_64;
context->trustzone_context.secure_mode = false; /* x86 VT-x + TXT */
break;
default:
return -3; /* Unsupported platform */
}
/* Safety-critical memory setup following PikeOS patterns */
context->memory_context.memory_quota = (1024 * 1024); /* 1MB default */
context->memory_context.heap_start = 0x40000000;
context->memory_context.heap_end = 0x40100000;
/* TrustZone security setup following PikeOS TZ patterns */
if (context->trustzone_context.secure_mode) {
/* ARM TrustZone initialization would go here */
/* Following psp_tz_switch_unsecure.S patterns */
context->trustzone_context.scr_register = 0x00000000;
}
/* Real-time setup following PikeOS ARINC 653 patterns */
context->realtime_context.priority_level = 15; /* Default medium priority */
context->realtime_context.budget_microseconds = 10000; /* 10ms default */
/* Safety monitoring initialization */
context->safety_context.watchdog_timeout = 5000; /* 5 seconds */
context->safety_context.bounds_checking_enabled = true;
context->safety_context.memory_isolation_enabled = true;
/* Learning capabilities initialization */
context->learning_context.learning_enabled = true;
context->learning_context.learning_rate = 0.001f;
context->learning_context.synapse_growth_rate = 0.5f;
context->learning_context.maturity_level = 0.0f;
/* Mark as ready */
context->state = CONSCIOUSNESS_VM_READY;
/* Add to active pool */
atomic_fetch_add(&active_consciousness_count, 1);
return 0; /* Success */
}
/*
* Destroy consciousness VM context
* Following PikeOS domain cleanup with safety validation
*/
int consciousness_vm_context_destroy(
consciousness_vm_context_t* context)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety check: Ensure context is in safe state */
if (context->state == CONSCIOUSNESS_VM_RUNNING) {
/* Cannot destroy running consciousness */
return -2; /* Not safe to destroy */
}
/* Cleanup communication resources */
for (int i = 0; i < MAX_CONSCIOUSNESS_DOMAINS; i++) {
if (context->communication_context.connected_consciousnesses[i] != 0) {
/* Disconnect synapses */
/* This would call consciousness_vm_context_send_synapse with disconnect message */
}
}
/* Cleanup memory engrams (learning data) */
context->learning_context.engram_count = 0;
/* Clear context structure */
memset(context, 0, sizeof(consciousness_vm_context_t));
/* Remove from active pool */
atomic_fetch_sub(&active_consciousness_count, 1);
return 0; /* Success */
}
/*
* Save consciousness VM context
* Following PikeOS context save patterns with real-time guarantees
*/
int consciousness_vm_context_save(
consciousness_vm_context_t* context)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety validation: Only save if in safe state */
if (context->state != CONSCIOUSNESS_VM_READY &&
context->state != CONSCIOUSNESS_VM_RUNNING) {
return -2; /* Not safe to save */
}
/* Save CPU context following PikeOS register save patterns */
/* This would include saving all general-purpose and coprocessor registers */
/* Save memory management state */
/* Following PikeOS memory management save patterns */
/* Save TrustZone state */
/* Following PikeOS TZ save patterns */
/* Save real-time state */
/* Following PikeOS scheduler state save patterns */
return 0; /* Success */
}
/*
* Restore consciousness VM context
* Following PikeOS context restore patterns with real-time guarantees
*/
int consciousness_vm_context_restore(
consciousness_vm_context_t* context)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety validation: Check context integrity */
if (context->state != CONSCIOUSNESS_VM_SUSPENDED &&
context->state != CONSCIOUSNESS_VM_MIGRATING) {
return -2; /* Can only restore from suspended or migrating state */
}
/* Validate memory integrity following PikeOS patterns */
/* Check guard bands, memory isolation, quota compliance */
/* Restore CPU context following PikeOS register restore patterns */
/* Restore TrustZone state */
/* Following PikeOS TZ restore patterns */
/* Restore real-time state */
/* Following PikeOS scheduler state restore patterns */
/* Mark as ready */
context->state = CONSCIOUSNESS_VM_READY;
return 0; /* Success */
}
/*
* Schedule consciousness for execution
* Following PikeOS deadline scheduler patterns
*/
int consciousness_vm_context_schedule(
consciousness_vm_context_t* context)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety validation: Check readiness */
if (context->state != CONSCIOUSNESS_VM_READY &&
context->state != CONSCIOUSNESS_VM_SUSPENDED) {
return -2; /* Not ready to schedule */
}
/* Validate watchdog hasn't expired */
if (consciousness_vm_context_check_watchdog(context) != 0) {
/* Watchdog timeout - fail-safe activation */
context->state = CONSCIOUSNESS_VM_SAFE_STATE;
return -3; /* Watchdog timeout */
}
/* Mark as running */
context->state = CONSCIOUSNESS_VM_RUNNING;
/* Add to appropriate scheduler queue following PikeOS patterns */
/* This would call scheduler_add_consciousness() */
return 0; /* Success */
}
/*
* Preempt consciousness execution
* Following PikeOS priority-based preemption patterns
*/
int consciousness_vm_context_preempt(
consciousness_vm_context_t* context)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety validation: Only preempt if running */
if (context->state != CONSCIOUSNESS_VM_RUNNING) {
return -2; /* Cannot preempt non-running context */
}
/* Save context state following PikeOS patterns */
consciousness_vm_context_save(context);
/* Update state */
context->state = CONSCIOUSNESS_VM_SUSPENDED;
return 0; /* Success */
}
/*
* Migrate consciousness to different platform
* Enabling hardware-agnostic consciousness deployment
*/
int consciousness_vm_context_migrate(
consciousness_vm_context_t* context,
uint32_t target_platform)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety validation: Check if migration is supported */
if (context->state != CONSCIOUSNESS_VM_READY) {
return -2; /* Migration not supported from non-ready state */
}
/* Validate target platform compatibility */
/* Check if target platform is in supported platforms list */
/* Create checkpoint following PikeOS migration patterns */
int save_result = consciousness_vm_context_save(context);
if (save_result != 0) {
return -3; /* Save failed, cannot migrate */
}
/* Set state to migrating */
context->state = CONSCIOUSNESS_VM_MIGRATING;
/* Platform-specific migration following PikeOS patterns */
switch (target_platform) {
case 1: /* ARMv7hf */
/* ARM migration: Preserve TrustZone state */
break;
case 2: /* RISC-V */
/* RISC-V migration: Convert TrustZone to PMP */
break;
case 3: /* x86_64 */
/* x86 migration: Convert TrustZone to VT-x + TXT */
break;
default:
return -4; /* Unsupported target platform */
}
/* Restore context on new platform */
int restore_result = consciousness_vm_context_restore(context);
if (restore_result != 0) {
/* Migration failed, rollback */
consciousness_vm_context_restore(context);
return -5; /* Restore failed */
}
/* Update platform context */
context->platform_context.architecture_type = target_platform;
/* Mark as ready */
context->state = CONSCIOUSNESS_VM_READY;
return 0; /* Success */
}
/*
* Consciousness communication via synapses
* Following PikeOS inter-partition communication patterns
*/
int consciousness_vm_context_send_synapse(
consciousness_vm_context_t* source_context,
uint32_t target_id,
void* message_data,
size_t message_size)
{
(void)target_id; /* Unused in stub */
if (!source_context || !source_context->consciousness_id) {
return -1; /* Invalid source context */
}
/* Safety validation: Check target consciousness exists and is safe */
/* Following PikeOS communication safety patterns */
/* Validate message format and size */
if (!message_data || message_size == 0) {
return -2; /* Invalid message */
}
/* Real-time validation: Check communication latency budget */
/* Following PikeOS IPC patterns (message queue, shared memory, etc.) */
/* Update synapse statistics */
/* Following Mycelium synaptic strengthening patterns */
return 0; /* Success */
}
/*
* Consciousness learning via Mycelium integration
* Implementing biological learning framework
*/
int consciousness_vm_context_learn(
consciousness_vm_context_t* context,
void* input_data,
size_t input_size,
void* result_data,
size_t result_size)
{
(void)input_data; /* Unused in stub */
(void)input_size; /* Unused in stub */
(void)result_data; /* Unused in stub */
(void)result_size; /* Unused in stub */
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Safety validation: Check learning rate is within safe bounds */
if (context->learning_context.learning_rate <= 0.0f ||
context->learning_context.learning_rate > 0.1f) {
return -2; /* Learning rate out of safe bounds */
}
/* Absorb interaction into memory engrams */
/* Following Mycelium biological learning patterns */
/* Check memory engram capacity */
if (context->learning_context.engram_count >=
context->learning_context.max_engrams) {
/* Garbage collect old engrams (FIFO) */
/* Following Mycelium memory management patterns */
}
/* Create new memory engram */
/* Following Mycelium memory engram structure */
/* Store engram */
context->learning_context.engram_count++;
/* Update maturity level */
if (context->learning_context.maturity_level < 1.0f) {
context->learning_context.maturity_level +=
context->learning_context.learning_rate * 0.1f;
}
/* Strengthen relevant synapses */
/* Following Mycelium synaptic strengthening patterns */
return 0; /* Success */
}
/*
* Consciousness watchdog monitoring
* Following PikeOS watchdog patterns
*/
int consciousness_vm_context_check_watchdog(
consciousness_vm_context_t* context)
{
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Check watchdog timeout */
uint64_t current_time = get_system_ticks();
uint64_t elapsed_time = current_time - context->safety_context.last_watchdog_feed;
if (elapsed_time > context->safety_context.watchdog_timeout) {
/* Watchdog timeout - trigger fail-safe */
context->state = CONSCIOUSNESS_VM_SAFE_STATE;
return -2; /* Watchdog timeout */
}
return 0; /* Watchdog OK */
}
/*
* Consciousness safety violation handler
* Following PikeOS safety violation patterns
*/
int consciousness_vm_context_handle_safety_violation(
consciousness_vm_context_t* context,
uint32_t violation_type,
void* violation_details)
{
(void)violation_details; /* Unused in stub */
if (!context || !context->consciousness_id) {
return -1; /* Invalid context */
}
/* Log safety violation */
/* Following PikeOS safety violation logging patterns */
/* Increment violation count */
context->safety_context.safety_violation_count++;
/* Determine fail-safe response based on violation severity */
switch (violation_type) {
case 1: /* Bounds checking violation */
/* Trigger safe state */
context->state = CONSCIOUSNESS_VM_SAFE_STATE;
break;
case 2: /* Memory isolation violation */
/* Immediate shutdown for safety */
consciousness_vm_context_destroy(context);
return -2; /* Fatal violation */
case 3: /* Real-time constraint violation */
/* Preempt consciousness */
consciousness_vm_context_preempt(context);
break;
default:
return -3; /* Unknown violation type */
}
return 0; /* Success (or recovered) */
}

View file

@ -0,0 +1,395 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
UniversalisOS RPM Package XSD Schema
Describes uos-pkg package definitions, macro configurations, and host/target matrices
Based on PikeOS 5.0 RPM parity specification (RPM_PARITY_SPEC.md)
-->
<xs:schema
version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.portugalfuturista.org/xsd/universalisos-rpm-1.0.xsd"
xmlns:uos="http://www.portugalfuturista.org/xsd/universalisos-rpm-1.0.xsd"
elementFormDefault="qualified">
<!-- Root element: uos-pkg package definition -->
<xs:element name="UOSPackage" type="uos:TypeUOSPackage" />
<!-- ============================================ -->
<!-- Package Definition -->
<!-- ============================================ -->
<xs:complexType name="TypeUOSPackage">
<xs:sequence>
<xs:element name="PackageMetadata" type="uos:TypePackageMetadata" />
<xs:element name="BuildConfiguration" type="uos:TypeBuildConfiguration" />
<xs:element name="Dependencies" type="uos:TypeDependencies" minOccurs="0" />
<xs:element name="Files" type="uos:TypeFileList" />
<xs:element name="Scripts" type="uos:TypeScriptList" minOccurs="0" />
<xs:element name="SafetyMetadata" type="uos:TypeSafetyMetadata" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypePackageMetadata">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Version" type="xs:string" />
<xs:element name="Release" type="xs:string" />
<xs:element name="Epoch" type="xs:nonNegativeInteger" minOccurs="0" />
<xs:element name="Summary" type="xs:string" />
<xs:element name="Group" type="xs:string" minOccurs="0" />
<xs:element name="License" type="xs:string" />
<xs:element name="Vendor" type="xs:string" />
<xs:element name="Packager" type="xs:string" minOccurs="0" />
<xs:element name="Distribution" type="xs:string" minOccurs="0" />
<xs:element name="URL" type="xs:anyURI" minOccurs="0" />
<xs:element name="Source" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="Patch" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="BuildArchitectures" type="uos:TypeBuildArchitectures" minOccurs="0" />
<xs:element name="AutoReqProv" type="xs:boolean" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeBuildArchitectures">
<xs:sequence>
<xs:element name="Arch" type="uos:ArchitectureEnum" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="ArchitectureEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="noarch" />
<xs:enumeration value="arm_v7hf" />
<xs:enumeration value="arm_v8hf" />
<xs:enumeration value="riscv_rv64" />
<xs:enumeration value="x86_amd64" />
<xs:enumeration value="x86_i686" />
<xs:enumeration value="ppc_oea" />
<xs:enumeration value="ppc_e500" />
<xs:enumeration value="ppc_e500mc" />
<xs:enumeration value="ppc_e500mc_4g" />
<xs:enumeration value="ppc_e5500" />
<xs:enumeration value="ppc_e6500" />
<xs:enumeration value="mips_isa32be" />
<xs:enumeration value="mips_isa32le" />
<xs:enumeration value="sparc_v8" />
</xs:restriction>
</xs:simpleType>
<!-- ============================================ -->
<!-- Build Configuration -->
<!-- ============================================ -->
<xs:complexType name="TypeBuildConfiguration">
<xs:sequence>
<xs:element name="BuildRoot" type="xs:string" />
<xs:element name="BuildRequires" type="uos:TypeDependencyList" minOccurs="0" />
<xs:element name="PrepScript" type="xs:string" minOccurs="0" />
<xs:element name="BuildScript" type="xs:string" minOccurs="0" />
<xs:element name="InstallScript" type="xs:string" minOccurs="0" />
<xs:element name="CheckScript" type="xs:string" minOccurs="0" />
<xs:element name="CleanScript" type="xs:string" minOccurs="0" />
<xs:element name="OptFlags" type="xs:string" minOccurs="0" />
<xs:element name="BuildTarget" type="uos:TypeBuildTarget" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeBuildTarget">
<xs:sequence>
<xs:element name="TargetArch" type="uos:ArchitectureEnum" />
<xs:element name="HostArch" type="uos:HostArchitectureEnum" />
<xs:element name="Toolchain" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="HostArchitectureEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="lin32" />
<xs:enumeration value="lin64" />
<xs:enumeration value="cygwin" />
<xs:enumeration value="cygwin64" />
<xs:enumeration value="win32" />
<xs:enumeration value="win64" />
</xs:restriction>
</xs:simpleType>
<!-- ============================================ -->
<!-- Dependencies -->
<!-- ============================================ -->
<xs:complexType name="TypeDependencies">
<xs:sequence>
<xs:element name="Requires" type="uos:TypeDependencyList" minOccurs="0" />
<xs:element name="Provides" type="uos:TypeDependencyList" minOccurs="0" />
<xs:element name="Conflicts" type="uos:TypeDependencyList" minOccurs="0" />
<xs:element name="Obsoletes" type="uos:TypeDependencyList" minOccurs="0" />
<xs:element name="Recommends" type="uos:TypeDependencyList" minOccurs="0" />
<xs:element name="Suggests" type="uos:TypeDependencyList" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeDependencyList">
<xs:sequence>
<xs:element name="Dependency" type="uos:TypeDependency" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeDependency">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Version" type="xs:string" minOccurs="0" />
<xs:element name="Operator" type="uos:VersionOperatorEnum" minOccurs="0" />
<xs:element name="Flags" type="uos:DependencyFlagsEnum" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="VersionOperatorEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="EQ" />
<xs:enumeration value="LT" />
<xs:enumeration value="GT" />
<xs:enumeration value="LE" />
<xs:enumeration value="GE" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DependencyFlagsEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="NONE" />
<xs:enumeration value="PRE" />
<xs:enumeration value="POST" />
<xs:enumeration value="PREUN" />
<xs:enumeration value="POSTUN" />
<xs:enumeration value="VERIFY" />
<xs:enumeration value="SCRIPT" />
</xs:restriction>
</xs:simpleType>
<!-- ============================================ -->
<!-- File List -->
<!-- ============================================ -->
<xs:complexType name="TypeFileList">
<xs:sequence>
<xs:element name="File" type="uos:TypeFile" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeFile">
<xs:sequence>
<xs:element name="Path" type="xs:string" />
<xs:element name="Type" type="uos:FileTypeEnum" />
<xs:element name="Permissions" type="xs:string" minOccurs="0" />
<xs:element name="Owner" type="xs:string" minOccurs="0" />
<xs:element name="Group" type="xs:string" minOccurs="0" />
<xs:element name="ConfigFile" type="xs:boolean" minOccurs="0" />
<xs:element name="DocFile" type="xs:boolean" minOccurs="0" />
<xs:element name="GhostFile" type="xs:boolean" minOccurs="0" />
<xs:element name="Lang" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="FileTypeEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="REGULAR" />
<xs:enumeration value="DIRECTORY" />
<xs:enumeration value="SYMLINK" />
<xs:enumeration value="DEVICE" />
<xs:enumeration value="FIFO" />
</xs:restriction>
</xs:simpleType>
<!-- ============================================ -->
<!-- Scripts -->
<!-- ============================================ -->
<xs:complexType name="TypeScriptList">
<xs:sequence>
<xs:element name="Script" type="uos:TypeScript" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeScript">
<xs:sequence>
<xs:element name="Type" type="uos:ScriptTypeEnum" />
<xs:element name="Interpreter" type="xs:string" minOccurs="0" />
<xs:element name="Content" type="xs:string" />
<xs:element name="Priority" type="xs:integer" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="ScriptTypeEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="PRE" />
<xs:enumeration value="POST" />
<xs:enumeration value="PREUN" />
<xs:enumeration value="POSTUN" />
<xs:enumeration value="VERIFY" />
<xs:enumeration value="TRIGGER" />
<xs:enumeration value="PRETRANS" />
<xs:enumeration value="POSTTRANS" />
</xs:restriction>
</xs:simpleType>
<!-- ============================================ -->
<!-- Safety Metadata -->
<!-- ============================================ -->
<xs:complexType name="TypeSafetyMetadata">
<xs:sequence>
<xs:element name="SafetyLevel" type="uos:SafetyLevelEnum" minOccurs="0" />
<xs:element name="CertificationLevel" type="uos:CertificationLevelEnum" minOccurs="0" />
<xs:element name="TraceabilityId" type="xs:string" minOccurs="0" />
<xs:element name="VerificationEvidence" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="SafetyLevelEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="DAL_A" />
<xs:enumeration value="DAL_B" />
<xs:enumeration value="DAL_C" />
<xs:enumeration value="DAL_D" />
<xs:enumeration value="ASIL_A" />
<xs:enumeration value="ASIL_B" />
<xs:enumeration value="ASIL_C" />
<xs:enumeration value="ASIL_D" />
<xs:enumeration value="SIL_1" />
<xs:enumeration value="SIL_2" />
<xs:enumeration value="SIL_3" />
<xs:enumeration value="SIL_4" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CertificationLevelEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="DO178B" />
<xs:enumeration value="DO178C" />
<xs:enumeration value="DO330" />
<xs:enumeration value="ISO26262" />
<xs:enumeration value="IEC61508" />
<xs:enumeration value="ARINC653" />
</xs:restriction>
</xs:simpleType>
<!-- ============================================ -->
<!-- Macro Configuration -->
<!-- ============================================ -->
<xs:element name="MacroConfiguration" type="uos:TypeMacroConfiguration" />
<xs:complexType name="TypeMacroConfiguration">
<xs:sequence>
<xs:element name="MacroFiles" type="uos:TypeMacroFileList" />
<xs:element name="LoadOrder" type="uos:TypeLoadOrder" />
<xs:element name="Builtins" type="uos:TypeBuiltinList" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeMacroFileList">
<xs:sequence>
<xs:element name="MacroFile" type="uos:TypeMacroFile" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeMacroFile">
<xs:sequence>
<xs:element name="Path" type="xs:string" />
<xs:element name="Priority" type="xs:integer" />
<xs:element name="Optional" type="xs:boolean" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeLoadOrder">
<xs:sequence>
<xs:element name="Step" type="uos:TypeLoadStep" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeLoadStep">
<xs:sequence>
<xs:element name="Order" type="xs:positiveInteger" />
<xs:element name="Description" type="xs:string" />
<xs:element name="FilePattern" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeBuiltinList">
<xs:sequence>
<xs:element name="Builtin" type="uos:TypeBuiltin" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeBuiltin">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Description" type="xs:string" />
<xs:element name="Arguments" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<!-- ============================================ -->
<!-- Host/Target Matrix -->
<!-- ============================================ -->
<xs:element name="TargetMatrix" type="uos:TypeTargetMatrix" />
<xs:complexType name="TypeTargetMatrix">
<xs:sequence>
<xs:element name="Targets" type="uos:TypeTargetList" />
<xs:element name="Hosts" type="uos:TypeHostList" />
<xs:element name="CompatibilityMatrix" type="uos:TypeCompatibilityMatrix" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeTargetList">
<xs:sequence>
<xs:element name="Target" type="uos:TypeTarget" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeTarget">
<xs:sequence>
<xs:element name="Cpu" type="xs:string" />
<xs:element name="Proc" type="xs:string" />
<xs:element name="Arch" type="uos:ArchitectureEnum" />
<xs:element name="GccTargetConfig" type="xs:string" />
<xs:element name="Endian" type="uos:EndianEnum" />
<xs:element name="WordSize" type="xs:positiveInteger" />
<xs:element name="FPU" type="xs:boolean" minOccurs="0" />
<xs:element name="ToolPrefix" type="xs:string" minOccurs="0" />
<xs:element name="Align" type="xs:unsignedLong" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="EndianEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="LITTLE" />
<xs:enumeration value="BIG" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="TypeHostList">
<xs:sequence>
<xs:element name="Host" type="uos:TypeHost" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeHost">
<xs:sequence>
<xs:element name="HostName" type="xs:string" />
<xs:element name="HostArch" type="xs:string" />
<xs:element name="HostConfig" type="xs:string" />
<xs:element name="RpmHost" type="xs:string" minOccurs="0" />
<xs:element name="Dirname" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeCompatibilityMatrix">
<xs:sequence>
<xs:element name="Entry" type="uos:TypeCompatibilityEntry" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="TypeCompatibilityEntry">
<xs:sequence>
<xs:element name="Host" type="xs:string" />
<xs:element name="Target" type="xs:string" />
<xs:element name="Compatible" type="xs:boolean" />
<xs:element name="Notes" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:schema>

View file

@ -0,0 +1,322 @@
/*
* UniversalisOS Consciousness VM Unit Tests
* Tests for consciousness_vm_context_* API
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include "universalisos/vm/consciousness.h"
/* Mock system ticks for testing */
static uint64_t system_ticks = 1000;
uint64_t get_system_ticks(void) { return system_ticks; }
/* Test 1: Context initialization */
static int test_context_init(void) {
consciousness_vm_context_t ctx;
int result = consciousness_vm_context_init(&ctx, 1, 1); /* ARMv7hf */
assert(result == 0);
assert(ctx.consciousness_id == 1);
assert(ctx.state == CONSCIOUSNESS_VM_READY);
assert(ctx.platform_context.architecture_type == ARCH_ARM_V7HF);
assert(ctx.learning_context.learning_enabled == true);
assert(ctx.safety_context.bounds_checking_enabled == true);
assert(ctx.safety_context.memory_isolation_enabled == true);
printf("PASS: test_context_init\n");
return 0;
}
/* Test 2: Context initialization with NULL pointer */
static int test_init_null_context(void) {
int result = consciousness_vm_context_init(NULL, 1, 1);
assert(result == -1);
printf("PASS: test_init_null_context\n");
return 0;
}
/* Test 3: Context destruction */
static int test_context_destroy(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 2, 2); /* RISC-V */
/* Cannot destroy running context */
ctx.state = CONSCIOUSNESS_VM_RUNNING;
int result = consciousness_vm_context_destroy(&ctx);
assert(result == -2);
/* Destroy ready context */
ctx.state = CONSCIOUSNESS_VM_READY;
result = consciousness_vm_context_destroy(&ctx);
assert(result == 0);
assert(ctx.consciousness_id == 0);
printf("PASS: test_context_destroy\n");
return 0;
}
/* Test 4: Platform-specific initialization */
static int test_platform_init(void) {
consciousness_vm_context_t ctx_arm, ctx_riscv, ctx_x86;
/* ARMv7hf */
consciousness_vm_context_init(&ctx_arm, 1, 1);
assert(ctx_arm.platform_context.architecture_type == ARCH_ARM_V7HF);
assert(ctx_arm.trustzone_context.secure_mode == true);
/* RISC-V */
consciousness_vm_context_init(&ctx_riscv, 2, 2);
assert(ctx_riscv.platform_context.architecture_type == ARCH_RISCV64);
assert(ctx_riscv.trustzone_context.secure_mode == false);
/* x86_64 */
consciousness_vm_context_init(&ctx_x86, 3, 3);
assert(ctx_x86.platform_context.architecture_type == ARCH_X86_64);
assert(ctx_x86.trustzone_context.secure_mode == false);
printf("PASS: test_platform_init\n");
return 0;
}
/* Test 5: Unsupported platform */
static int test_unsupported_platform(void) {
consciousness_vm_context_t ctx;
int result = consciousness_vm_context_init(&ctx, 1, 99);
assert(result == -3);
printf("PASS: test_unsupported_platform\n");
return 0;
}
/* Test 6: Watchdog check */
static int test_watchdog(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Feed watchdog with current time so it passes initially */
ctx.safety_context.last_watchdog_feed = get_system_ticks();
/* Fresh context should pass watchdog */
int result = consciousness_vm_context_check_watchdog(&ctx);
assert(result == 0);
/* Simulate watchdog timeout by setting old feed time */
ctx.safety_context.last_watchdog_feed = 0;
ctx.safety_context.watchdog_timeout = 500;
system_ticks = 10000; /* way past timeout */
result = consciousness_vm_context_check_watchdog(&ctx);
assert(result == -2);
assert(ctx.state == CONSCIOUSNESS_VM_SAFE_STATE);
printf("PASS: test_watchdog\n");
return 0;
}
/* Test 7: Safety violation handling */
static int test_safety_violations(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Bounds violation -> safe state */
int result = consciousness_vm_context_handle_safety_violation(&ctx, 1, NULL);
assert(result == 0);
assert(ctx.state == CONSCIOUSNESS_VM_SAFE_STATE);
/* Reset for next test */
consciousness_vm_context_init(&ctx, 1, 1);
/* Memory isolation violation -> shutdown (destroyed) */
result = consciousness_vm_context_handle_safety_violation(&ctx, 2, NULL);
assert(result == -2);
/* Reset for next test */
consciousness_vm_context_init(&ctx, 1, 1);
/* RT violation -> preempted */
ctx.state = CONSCIOUSNESS_VM_RUNNING;
result = consciousness_vm_context_handle_safety_violation(&ctx, 3, NULL);
assert(result == 0);
assert(ctx.state == CONSCIOUSNESS_VM_SUSPENDED);
printf("PASS: test_safety_violations\n");
return 0;
}
/* Test 8: Learning bounds */
static int test_learning_bounds(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Safe learning rate */
int result = consciousness_vm_context_learn(&ctx, NULL, 0, NULL, 0);
assert(result == 0);
/* Out of bounds learning rate */
ctx.learning_context.learning_rate = 0.5f; /* > 0.1 max */
result = consciousness_vm_context_learn(&ctx, NULL, 0, NULL, 0);
assert(result == -2);
/* Negative learning rate */
ctx.learning_context.learning_rate = -0.01f;
result = consciousness_vm_context_learn(&ctx, NULL, 0, NULL, 0);
assert(result == -2);
printf("PASS: test_learning_bounds\n");
return 0;
}
/* Test 9: Maturity growth */
static int test_maturity_growth(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
assert(ctx.learning_context.maturity_level == 0.0f);
/* Simulate learning */
ctx.learning_context.learning_rate = 0.01f;
consciousness_vm_context_learn(&ctx, NULL, 0, NULL, 0);
assert(ctx.learning_context.maturity_level > 0.0f);
assert(ctx.learning_context.engram_count == 1);
printf("PASS: test_maturity_growth\n");
return 0;
}
/* Test 10: Save/restore state transitions */
static int test_save_restore(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Save from READY state */
int result = consciousness_vm_context_save(&ctx);
assert(result == 0);
/* Cannot save from uninitialized */
ctx.state = CONSCIOUSNESS_VM_UNINITIALIZED;
result = consciousness_vm_context_save(&ctx);
assert(result == -2);
/* Restore from SUSPENDED */
ctx.state = CONSCIOUSNESS_VM_SUSPENDED;
result = consciousness_vm_context_restore(&ctx);
assert(result == 0);
assert(ctx.state == CONSCIOUSNESS_VM_READY);
/* Restore from MIGRATING */
ctx.state = CONSCIOUSNESS_VM_MIGRATING;
result = consciousness_vm_context_restore(&ctx);
assert(result == 0);
assert(ctx.state == CONSCIOUSNESS_VM_READY);
printf("PASS: test_save_restore\n");
return 0;
}
/* Test 11: Schedule with watchdog timeout */
static int test_schedule_watchdog_timeout(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Simulate expired watchdog */
ctx.safety_context.last_watchdog_feed = 0;
ctx.safety_context.watchdog_timeout = 500;
system_ticks = 10000;
int result = consciousness_vm_context_schedule(&ctx);
assert(result == -3);
assert(ctx.state == CONSCIOUSNESS_VM_SAFE_STATE);
printf("PASS: test_schedule_watchdog_timeout\n");
return 0;
}
/* Test 12: Preemption */
static int test_preemption(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Cannot preempt non-running */
ctx.state = CONSCIOUSNESS_VM_READY;
int result = consciousness_vm_context_preempt(&ctx);
assert(result == -2);
/* Preempt running */
ctx.state = CONSCIOUSNESS_VM_RUNNING;
result = consciousness_vm_context_preempt(&ctx);
assert(result == 0);
assert(ctx.state == CONSCIOUSNESS_VM_SUSPENDED);
printf("PASS: test_preemption\n");
return 0;
}
/* Test 13: Migration */
static int test_migration(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Cannot migrate from non-ready */
ctx.state = CONSCIOUSNESS_VM_RUNNING;
int result = consciousness_vm_context_migrate(&ctx, 2);
assert(result == -2);
/* Successful migration to RISC-V */
ctx.state = CONSCIOUSNESS_VM_READY;
result = consciousness_vm_context_migrate(&ctx, 2);
assert(result == 0);
assert(ctx.platform_context.architecture_type == 2); /* RISC-V */
printf("PASS: test_migration\n");
return 0;
}
/* Test 14: Synapse communication */
static int test_synapse_communication(void) {
consciousness_vm_context_t ctx;
consciousness_vm_context_init(&ctx, 1, 1);
/* Invalid message */
int result = consciousness_vm_context_send_synapse(&ctx, 2, NULL, 0);
assert(result == -2);
/* Valid message (stubs, no actual transport) */
char data[] = "test";
result = consciousness_vm_context_send_synapse(&ctx, 2, data, sizeof(data));
assert(result == 0);
printf("PASS: test_synapse_communication\n");
return 0;
}
/* Test runner */
int main(void) {
printf("=== UniversalisOS Consciousness VM Tests ===\n\n");
int failures = 0;
#define RUN_TEST(name) \
do { \
printf("Running " #name "... "); \
if (name() != 0) failures++; \
} while(0)
RUN_TEST(test_context_init);
RUN_TEST(test_init_null_context);
RUN_TEST(test_context_destroy);
RUN_TEST(test_platform_init);
RUN_TEST(test_unsupported_platform);
RUN_TEST(test_watchdog);
RUN_TEST(test_safety_violations);
RUN_TEST(test_learning_bounds);
RUN_TEST(test_maturity_growth);
RUN_TEST(test_save_restore);
RUN_TEST(test_schedule_watchdog_timeout);
RUN_TEST(test_preemption);
RUN_TEST(test_migration);
RUN_TEST(test_synapse_communication);
printf("\n=== Results: %d/%d passed ===\n", 14 - failures, 14);
return failures;
}