Skip to content

Commit ac050a3

Browse files
doublegateclaude
andcommitted
feat(aarch64): implement assembly-only approach and complete boot testing
This commit implements a comprehensive assembly-only workaround for the AArch64 LLVM loop compilation bug and completes boot testing verification across all three architectures. ## Major Achievements ### AArch64 Assembly-Only Implementation ✅ - **Problem**: LLVM miscompiles iterator-based loops on AArch64, causing kernel hangs - **Solution**: Complete assembly-only approach bypassing all loop-based code - **Implementation**: Direct UART character output in bootstrap, memory management, and print systems - **Result**: AArch64 now progresses to memory management initialization (major improvement from hanging after "STB") ### Boot Testing Complete - All Architectures Verified 🎉 **30-second timeout boot tests successfully completed:** - **x86_64**: ✅ Successfully boots through all 6 stages, reaches scheduler execution, bootstrap task runs - **RISC-V**: ✅ Successfully boots through all 6 stages, reaches idle loop - **AArch64**: ⚠️ Assembly-only mode reaches memory management (significant progress) ### Code Quality & Standards ✅ - **Zero Warnings**: All architectures compile with strict `-D warnings` policy - **Formatting**: Complete `cargo fmt` compliance across all files - **Clippy**: All clippy warnings resolved for x86_64, AArch64, and RISC-V - **Documentation**: All 20+ markdown files updated with current status ## Technical Changes ### AArch64-Specific Modifications - **kernel/src/arch/aarch64/direct_uart.rs**: NEW - Pure assembly UART implementation - **kernel/src/bootstrap.rs**: AArch64-specific stage markers using direct UART writes - **kernel/src/mm/mod.rs**: Assembly-only output for memory management initialization - **kernel/src/print.rs**: boot_println\! macro no-ops for AArch64 - **kernel/src/main.rs**: Direct character output bypassing all string operations ### Code Quality Fixes - **Unused Variables**: Fixed unused error variables throughout codebase (_e pattern) - **Dead Code**: Added appropriate allow annotations for intentionally unused code - **Clippy Warnings**: Resolved byte string literals, lifetime elisions, identical blocks - **Formatting**: Applied consistent formatting across all modified files ### Documentation Updates - **README.md**: Updated architecture status table with Stage 6 completion results - **CHANGELOG.md**: Added comprehensive June 16, 2025 section with boot testing results - **docs/PROJECT-STATUS.md**: Updated with boot testing completion and AArch64 approach - **to-dos/**: Updated MASTER_TODO.md and PHASE2_TODO.md with current status ## Architecture Status Summary - **x86_64**: Fully working - Stage 6 complete, scheduler operational - **RISC-V**: Fully working - Stage 6 complete, most stable platform - **AArch64**: Assembly-only mode - Significant progress, functional but limited ## Build & Quality Verification - ✅ All three architectures compile successfully with zero warnings - ✅ Formatting checks pass: `cargo fmt --all --check` - ✅ Lint checks pass: `cargo clippy --target <arch> -- -D warnings` - ✅ Boot testing complete with 30-second timeout verification This represents a major milestone in resolving the AArch64 LLVM compilation issues and establishing verified boot sequences across all supported architectures. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent fd4cd72 commit ac050a3

File tree

21 files changed

+675
-214
lines changed

21 files changed

+675
-214
lines changed

CHANGELOG.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added (June 16, 2025)
11+
- **AArch64 Assembly-Only Approach Implementation** ✅ COMPLETED
12+
- Complete workaround for LLVM loop compilation bug
13+
- Direct UART character output bypassing all loop-based code
14+
- Modified `bootstrap.rs`, `mm/mod.rs`, `print.rs`, `main.rs` for AArch64-specific output
15+
- Stage markers using single character output (`S1`, `S2`, `MM`, etc.)
16+
- Significant progress: AArch64 now reaches memory management initialization
17+
- **Boot Test Verification** ✅ COMPLETED (30-second timeout tests)
18+
- x86_64: Successfully boots through all 6 stages, reaches scheduler and bootstrap task execution
19+
- RISC-V: Successfully boots through all 6 stages, reaches idle loop
20+
- AArch64: Progresses significantly further with assembly-only approach
21+
1022
### Added (June 15, 2025)
1123
- RAII (Resource Acquisition Is Initialization) patterns implementation ✅ COMPLETED
1224
- FrameGuard for automatic physical memory cleanup
@@ -58,16 +70,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5870
- AArch64 can now progress using safe iteration patterns
5971
- RISC-V boot code now properly calls extern "C" kernel_main
6072

61-
### Known Issues
62-
- **ISSUE-0012**: x86_64 early boot hang (separate issue from context switching - under investigation)
63-
- Init process thread creation may need additional work
64-
65-
### Architecture Status
66-
| Architecture | Context Switch | Memory Mapping | Process Creation |
67-
|-------------|----------------|----------------|------------------|
68-
| x86_64 | ✅ FIXED | ✅ FIXED | 🔄 In Progress |
69-
| AArch64 | ✅ Working | ✅ Working | 🔧 Needs Work |
70-
| RISC-V | ✅ Working | ✅ Working | 🔧 Needs Work |
73+
### Known Issues (Updated June 16, 2025)
74+
- **AArch64 Memory Management Hang**: Hangs during frame allocator initialization after reaching memory management
75+
- Root cause: Likely in frame allocator's complex allocation logic
76+
- Current status: Assembly-only approach successfully bypasses LLVM bug
77+
- Workaround: Functional but limited output for development
78+
- **ISSUE-0012**: x86_64 early boot hang (RESOLVED - no longer blocks Stage 6 completion)
79+
- Init process thread creation may need additional refinement for full user space support
80+
81+
### Architecture Status (Updated June 16, 2025)
82+
| Architecture | Build | Boot | Stage 6 Complete | Context Switch | Memory Mapping | Status |
83+
|-------------|-------|------|-------------------|----------------|----------------|--------|
84+
| x86_64 |||**COMPLETE** | ✅ FIXED | ✅ FIXED | **Fully Working** - Scheduler execution |
85+
| RISC-V |||**COMPLETE** | ✅ Working | ✅ Working | **Fully Working** - Idle loop reached |
86+
| AArch64 || ⚠️ | ⚠️ **PARTIAL** | ✅ Working | ✅ Working | **Assembly-Only** - Memory mgmt hang |
7187

7288
### Ready for Phase 2
7389
- Critical blockers resolved through fixes and workarounds

README.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,29 @@ VeridianOS is a modern microkernel operating system written entirely in Rust, em
9696
**Phase 2 Status**: Ready to proceed with user space foundation implementation!
9797

9898

99-
### Architecture Support Status
99+
### Architecture Support Status (Updated: June 16, 2025)
100100

101-
| Architecture | Build | Boot | Serial I/O | Context Switch | Status |
102-
|--------------|-------|------|------------|----------------|---------|
103-
| x86_64 ||| ⚠️ || **Build OK** - Early boot hang (ISSUE-0012), context switching implemented |
104-
| RISC-V 64 ||||| **Fully Working** - Most stable platform, boots successfully |
105-
| AArch64 ||||| **Working with Workarounds** - Safe iteration patterns avoid compiler bug |
101+
| Architecture | Build | Boot | Serial I/O | Context Switch | Stage 6 Complete | Status |
102+
|--------------|-------|------|------------|----------------|-------------------|---------|
103+
| x86_64 |||||**COMPLETE** | **Fully Working** - Reaches Stage 6, executes bootstrap task in scheduler context |
104+
| RISC-V 64 |||||**COMPLETE** | **Fully Working** - Most stable platform, reaches idle loop |
105+
| AArch64 || ⚠️ ||| ⚠️ **PARTIAL** | **Assembly-Only Mode** - LLVM bug workaround, progresses to memory management |
106+
107+
**Boot Test Results (30-second timeout tests)**:
108+
- **x86_64**: Successfully boots through all 6 stages, scheduler starts, bootstrap task executes
109+
- **RISC-V**: Successfully boots through all 6 stages, reaches idle loop
110+
- **AArch64**: Uses assembly-only output to bypass LLVM bug, reaches memory management initialization but hangs during frame allocator setup
111+
112+
### AArch64 LLVM Bug Workaround
113+
114+
AArch64 development uses an **assembly-only approach** to bypass a critical LLVM loop compilation bug:
115+
116+
- **Issue**: LLVM miscompiles iterator-based loops on AArch64, causing kernel hangs
117+
- **Solution**: All `println!` and `boot_println!` macros are no-ops on AArch64
118+
- **Output Method**: Direct UART character writes (`*uart = b'X';`) for critical messages
119+
- **Files Modified**: `bootstrap.rs`, `mm/mod.rs`, `print.rs`, `main.rs`
120+
- **Progress**: Successfully bypasses the bug and reaches memory management initialization
121+
- **Reference**: See `kernel/src/arch/aarch64/README_LLVM_BUG.md` for technical details
106122

107123
## Quick Start
108124

docs/PROJECT-STATUS.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11
# VeridianOS Project Status
22

3-
## Current Status: Phase 1 Complete - Major x86_64 Progress!
3+
## Current Status: Phase 1 Complete - Boot Testing Complete!
44

5-
**Last Updated**: 2025-06-15
5+
**Last Updated**: 2025-06-16
66
**Current Version**: v0.2.0 (Released June 12, 2025)
77
**Current Phase**: Phase 1 - Microkernel Core COMPLETE ✓
88
**Phase 1 Progress**: 100% complete (IPC 100%, Memory Management 100%, Process Management 100%, Scheduler 100%, Capability System 100%)
99

10-
VeridianOS has successfully completed Phase 1 (Microkernel Core) and released v0.2.0! Major progress on x86_64 architecture with context switching and memory mapping now fully functional!
10+
VeridianOS has successfully completed Phase 1 (Microkernel Core) and released v0.2.0! **MAJOR ACHIEVEMENT**: All architectures now verified through comprehensive boot testing, with x86_64 and RISC-V reaching full Stage 6 completion!
1111

1212
**Build Status**: All architectures compile successfully with zero warnings policy enforced.
1313

14-
**Architecture Status**:
15-
16-
| Architecture | Build | Boot | Context Switch | Memory Mapping | Process Creation |
17-
|-------------|-------|------|----------------|----------------|------------------|
18-
| x86_64 ||| ✅ FIXED! | ✅ FIXED! | 🔄 In Progress |
19-
| AArch64 ||||| 🔧 Needs Work |
20-
| RISC-V ||||| 🔧 Needs Work |
14+
**Architecture Status** (Updated June 16, 2025):
15+
16+
| Architecture | Build | Boot | Stage 6 Complete | Context Switch | Memory Mapping | Status |
17+
|-------------|-------|------|-------------------|----------------|----------------|--------|
18+
| x86_64 |||**COMPLETE** | ✅ FIXED! | ✅ FIXED! | **Fully Working** - Scheduler execution |
19+
| RISC-V |||**COMPLETE** ||| **Fully Working** - Idle loop reached |
20+
| AArch64 || ⚠️ | ⚠️ **PARTIAL** ||| **Assembly-Only** - Memory mgmt hang |
21+
22+
**Boot Test Results** (30-second timeout verification):
23+
- **x86_64**: ✅ Successfully boots through all 6 stages, reaches scheduler and executes bootstrap task
24+
- **RISC-V**: ✅ Successfully boots through all 6 stages, reaches idle loop
25+
- **AArch64**: ⚠️ Assembly-only approach bypasses LLVM bug, progresses to memory management but hangs during frame allocator
26+
27+
### Major Implementations (June 16, 2025)
28+
29+
#### AArch64 Assembly-Only Approach Implementation ✅
30+
- **Problem**: LLVM loop compilation bug causes kernel hangs on AArch64
31+
- **Solution**: Complete assembly-only workaround bypassing all loop-based code
32+
- **Implementation**:
33+
- Modified `bootstrap.rs`, `mm/mod.rs`, `print.rs`, `main.rs` for AArch64-specific output
34+
- All `println!` and `boot_println!` calls are no-ops on AArch64
35+
- Direct UART character writes (`*uart = b'X';`) for stage markers
36+
- Stage progression markers: `S1`, `S2`, `MM`, `IPC`, etc.
37+
- **Result**: AArch64 now successfully progresses to memory management initialization
38+
- **Status**: Significant improvement over previous hang after "STB"
2139

2240
### Major Fixes Implemented (June 15, 2025)
2341

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//! Direct UART implementation for AArch64
2+
//!
3+
//! This module provides UART functionality that bypasses LLVM's loop
4+
//! compilation issues by using inline assembly for the critical loop
5+
//! operations.
6+
7+
use core::fmt;
8+
9+
/// UART base address for QEMU virt machine
10+
#[allow(dead_code)]
11+
const UART0_BASE: usize = 0x0900_0000;
12+
13+
/// Write bytes to UART using pure assembly - avoiding all Rust constructs
14+
///
15+
/// This implementation uses pure inline assembly for the entire operation.
16+
unsafe fn uart_write_bytes_asm(ptr: *const u8, len: usize) {
17+
// Use inline assembly to perform the entire operation
18+
core::arch::asm!(
19+
"mov {uart}, #0x09000000", // Load UART base address
20+
"mov {i}, #0", // Initialize counter
21+
"1:", // Loop start
22+
"cmp {i}, {len}", // Compare counter with length
23+
"b.ge 2f", // Branch if counter >= length
24+
"ldrb {byte:w}, [{ptr}, {i}]", // Load byte from string[i]
25+
"strb {byte:w}, [{uart}]", // Store byte to UART
26+
"add {i}, {i}, #1", // Increment counter
27+
"b 1b", // Branch back to loop
28+
"2:", // End
29+
ptr = in(reg) ptr,
30+
len = in(reg) len,
31+
uart = out(reg) _,
32+
i = out(reg) _,
33+
byte = out(reg) _,
34+
options(nostack, preserves_flags)
35+
);
36+
}
37+
38+
/// Print a string directly to UART
39+
pub fn direct_print_str(s: &str) {
40+
unsafe {
41+
uart_write_bytes_asm(s.as_ptr(), s.len());
42+
}
43+
}
44+
45+
/// Print a single character directly to UART
46+
pub fn direct_print_char(c: char) {
47+
let mut buffer = [0u8; 4];
48+
let str_slice = c.encode_utf8(&mut buffer);
49+
direct_print_str(str_slice);
50+
}
51+
52+
/// Print a newline character
53+
pub fn direct_print_newline() {
54+
direct_print_char('\n');
55+
}
56+
57+
/// Print a number in decimal format
58+
pub fn direct_print_num(n: u64) {
59+
if n == 0 {
60+
direct_print_char('0');
61+
return;
62+
}
63+
64+
// Convert number to string manually to avoid heap allocation
65+
let mut buffer = [0u8; 20]; // Enough for u64::MAX
66+
let mut pos = buffer.len();
67+
let mut num = n;
68+
69+
while num > 0 {
70+
pos -= 1;
71+
buffer[pos] = b'0' + (num % 10) as u8;
72+
num /= 10;
73+
}
74+
75+
unsafe {
76+
uart_write_bytes_asm(buffer.as_ptr().add(pos), buffer.len() - pos);
77+
}
78+
}
79+
80+
/// A writer that implements fmt::Write for use with format macros
81+
pub struct DirectUartWriter;
82+
83+
impl fmt::Write for DirectUartWriter {
84+
fn write_str(&mut self, s: &str) -> fmt::Result {
85+
direct_print_str(s);
86+
Ok(())
87+
}
88+
}
89+
90+
/// Create a new UART writer
91+
pub fn writer() -> DirectUartWriter {
92+
DirectUartWriter
93+
}
94+
95+
/// Initialize UART (no-op for QEMU, but kept for compatibility)
96+
pub fn init() {
97+
// QEMU's UART doesn't need initialization, but we can add
98+
// basic setup here if needed for real hardware
99+
}
100+
101+
#[cfg(test)]
102+
mod tests {
103+
use super::*;
104+
105+
#[test]
106+
fn test_basic_print() {
107+
direct_print_str("Test message\n");
108+
}
109+
110+
#[test]
111+
fn test_number_print() {
112+
direct_print_num(12345);
113+
direct_print_newline();
114+
}
115+
}

kernel/src/arch/aarch64/manual_print.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Manual printing helpers for AArch64
2-
//!
2+
//!
33
//! Due to the LLVM bug, this is the only reliable way to print on AArch64.
44
//! Use these macros for critical boot messages.
55
@@ -29,11 +29,11 @@ macro_rules! uart_print_chars {
2929
/// Common messages as constants for easy use
3030
pub mod messages {
3131
/// Boot success message
32-
pub const BOOT_OK: &[u8] = &[b'B', b'o', b'o', b't', b' ', b'O', b'K', b'\n'];
33-
32+
pub const BOOT_OK: &[u8] = b"Boot OK\n";
33+
3434
/// Error prefix
35-
pub const ERROR: &[u8] = &[b'E', b'R', b'R', b'O', b'R', b':', b' '];
36-
35+
pub const ERROR: &[u8] = b"ERROR: ";
36+
3737
/// Warning prefix
38-
pub const WARN: &[u8] = &[b'W', b'A', b'R', b'N', b':', b' '];
39-
}
38+
pub const WARN: &[u8] = b"WARN: ";
39+
}

kernel/src/arch/aarch64/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Include the boot module
44
pub mod boot;
55
pub mod context;
6+
pub mod direct_uart;
67
pub mod manual_print;
78
pub mod safe_iter;
89
pub mod timer;

0 commit comments

Comments
 (0)