Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Git LFS for large media files
*.mkv filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text

# Line endings
* text=auto eol=lf
*.bat text eol=crlf

# Binary files
*.elf binary
*.uf2 binary
*.bin binary

# Custom diff drivers
*.c diff=c
*.cpp diff=cpp
*.h diff=c
*.hpp diff=cpp
*.S diff=asm

# Linker scripts
*.x text
*.ld text
43 changes: 43 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
# Build directories
/Build/
/build/
/build-*/

# IDE and editor files
.vscode/*
!.vscode/c_cpp_properties.json
!.vscode/settings.json
!.vscode/launch.json

.idea/
*.swp
*.swo
*~
.DS_Store

# Compiled binaries
*.o
*.elf
*.bin
*.uf2
*.hex
*.dis
*.map

# CMake artifacts
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
compile_commands.json
Makefile

# Python
__pycache__/
*.pyc
.env

# Temporary files
*.tmp
*.log
cache/
*.cache
.cache/
25 changes: 19 additions & 6 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
{
"configurations": [
{
"name": "Linux",
"name": "Pico-OS Kernel",
"includePath": [
"${workspaceFolder}/**"
"${workspaceFolder}",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/common/pico_stdlib_headers/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2_common/hardware_base/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2040/hardware_structs/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2_common/hardware_claim/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2_common/hardware_sync/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2_common/hardware_sync_spin_lock/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2_common/hardware_irq/include",
"${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2_common/pico_platform/include",
"${workspaceFolder}/build/generated/pico_base"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"defines": [
"KERNEL",
"PICO_BOARD=\"pico\"",
"PICO_RP2040=1",
"PICO_32BIT=1"
],
"compilerPath": "/usr/bin/clang++",
"cStandard": "c11",
"cppStandard": "c++20",
"intelliSenseMode": "clang-arm",
"compileCommands": "${workspaceFolder}/Build/compile_commands.json"
"intelliSenseMode": "macos-clang-arm64"
}
],
"version": 4
Expand Down
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug: Attach",
"type": "cortex-debug",
"request": "attach",
"servertype": "openocd",
"executable": "${workspaceFolder}/build/Kernel.elf",
"configFiles": [
"interface/picoprobe.cfg",
"target/rp2040.cfg"
],
"svdFile": "${workspaceFolder}/build/_deps/pico_sdk-src/src/rp2040/hardware_regs/rp2040.svd",
"runToEntryPoint": "main",
"cwd": "${workspaceFolder}"
}
]
}
82 changes: 82 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,85 @@
# Changelog

## [Unreleased] - 2025-12-14

### Added
- **Final Polish Items**:
- `SoftwareSpinLock`: Active locking with deadlock detection and power efficiency (`wfe`/`sev`).
- `SoftwareMutex`: Passive locking using `HardwareSpinLock`.
- `WaitingThreadQueue`: For managing threads waiting on resources.
- **Hardware Integration**:
- `HardwareSpinLock`: Memory-mapped spin lock support for RP2040.
- `sys$read`, `sys$write`: Basic system calls hooked to `ConsoleDevice`.
- **MPU**: Supervisor/User memory separation verified.
- **Core Infrastructure**:
- `init_array`/`fini_array` support in crt0 for C++ static constructors.
- Stack alignment fixes to prevent hardfaults.
- **Exception Handling**: Implemented HardFault handler (Userland kill, Kernel panic).
- **Memory**: Added `allocate_eternal` for silent allocation.
- **QEMU**: Added launch script `Tools/run-qemu.sh`.

### Refactoring & Core Improvements
- **Kernel/StackProtector**: Implemented `init_stack_guard` using RP2040 ROSC for hardware-randomized stack canaries.
- **Kernel/Exceptions**: Enhanced HardFault handlers with clearer register dumps and stack trace headers.
- **Kernel/PageAllocator**: Added detailed comments on RP2040 RAM layout and Buddy System initialization.
- **Kernel/GlobalMemoryAllocator**: Standardized mutex usage with `ScopedMutex` and added comments. Implemented dynamic heap growth.
- **Kernel/StackWrapper**: Improved API docs and parameter naming.
- **Tools**: Removed unstable QEMU/Renode scripts (emulation deferred).

### System
- **Synchronization**: `HardwareSpinLock` is now ISR-safe, storing/restoring interrupt state.
- **MPU**: Setup for supervisor/user mode isolation.
- **Build**: Linker script (`linker.ld`) enforces 8-byte alignment for stack/heap.
- **Documentation**:
- Added `docs/InterruptSafety.md`.
- **Multi-Core Support**: `Scheduler` now supports creating and scheduling threads on both cores of the RP2040. Integrated `HardwareSpinLock` for safe inter-core synchronization.
- **Robust Data Structures**:
- Replaced `Std::SortedSet`'s binary search tree with a **Red-Black Tree** implementation, guaranteeing O(log n) operations.
- Added `m_allocated_pages` to `PageAllocator` using `SortedSet` to explicitly track allocated memory ranges.
- **Userland Allocator**: Implemented a free-list based `malloc`/`free`/`realloc`/`calloc` in `Userland/LibC`, replacing the previous bump allocator. This allows memory reuse and reduces fragmentation.
- `Std::Formatter` specialization for `Kernel::PageRange`.

### Changed
- Refactored `ConsoleFileHandle` to store a reference to the specific `VirtualFile` instance, fixing an issue where `stat /dev/tty` returned incorrect device information.
- Updated `Scheduler::dump()` to correctly iterate over core-specific thread arrays.
- Enhanced `PageAllocator::dump()` to show detailed allocation tracking.

### Fixed
- `stat /dev/tty` listing incorrect file attributes by decoupling `ConsoleFileHandle` from the singleton.
- Compilation errors in `Std/SortedSet.hpp` related to `HashTable` compatibility (relied on strict weak ordering `<` instead of `==`).

## [Unreleased] - 2025-12-12

### Fixed
- **macOS Build Compatibility**: Added `Tools/compat/elf.h` with minimal ELF definitions for macOS.
- **Portable File I/O**: Replaced Linux-specific `memfd_create`/`copy_file_range` with ANSI C alternatives (`tmpfile`, `fread`/`fwrite`).
- **Missing Includes**: Added `MaskedInterruptGuard.hpp` includes to `Process.cpp`, `SystemHandler.cpp`, `Loader.cpp`, `Scheduler.cpp`, and `KernelMutex.hpp`.
- **Stack Alignment**: Fixed potential hardfaults by ensuring 8-byte stack alignment in `Thread::setup_context()` and `hand_over_to_loaded_executable()`.
- **strlcpy Conflict**: Updated `Std/Forward.hpp` to use standard `size_t` return type.
- **Linker Symbol Resolution**: Hardcoded RP2040 RAM boundaries in `PageAllocator.cpp` to bypass missing linker script definitions.
- **Iterator Const Correctness**: Fixed `SortedSet::InorderIterator` comparison operators to accept const references.
- **Test Suite**: Fixed narrowing conversion, undeclared identifiers, and string arithmetic warnings in test files.

### Added
- **C++ Static Constructors**: Implemented `preinit_array`, `init_array`, and `fini_array` calling in `Userland/LibC/sys/crt0.c`.
- **Non-Executable Stack**: Added `.note.GNU-stack` section to `crt0.S` to silence linker warnings.

### Changed
- Refactored `HardwareSpinLock` to correct lock acquisition logic (removed infinite loop on success) and added `wfe`/`sev` instructions for power-efficient SMP synchronization.
- Enhanced `SoftwareSpinLock` with **Deadlock Detection** (checks if core already holds the lock) and `wfe`/`sev` support.
- Updated `.gitignore` to allow useful VSCode configuration files.
- Removed `-lbsd` dependency from `Tools/CMakeLists.txt`.
- Removed unsupported `-fropi`/`-frwpi` compiler flags from `Userland/CMakeLists.txt`.
- Commented out custom `operator new`/`delete` in `GlobalMemoryAllocator.cpp` to avoid conflicts with Pico SDK.

### Added
- **VSCode Configuration**: Added `c_cpp_properties.json` for IntelliSense and `launch.json` for Cortex-Debug support.
- **C++ Static Constructors**: Implemented `preinit_array`, `init_array`, and `fini_array` calling in `Userland/LibC/sys/crt0.c`.

---

## Previous Changes

### Major

- Added `AbstractLock` which is used by the new `LockGuard`.
Expand Down
146 changes: 131 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,46 +1,162 @@
# ==============================================================================
# PicoOS - CMake Build Configuration
# ==============================================================================
#
# Build targets:
# - Kernel.1.elf : Main kernel binary with debug symbols
# - Kernel.1.uf2 : UF2 firmware for direct flashing
# - Kernel.elf : Stripped kernel for production
#
# Usage:
# mkdir build && cd build
# cmake .. -G Ninja
# ninja
#
# ==============================================================================

cmake_minimum_required(VERSION 3.19.5)

# ------------------------------------------------------------------------------
# Build Configuration
# ------------------------------------------------------------------------------

# Export compile_commands.json for IDE support
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
# Default to Debug build
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
endif()

message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

# ------------------------------------------------------------------------------
# Pico SDK Setup
# ------------------------------------------------------------------------------

set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)
find_package(Tools MODULE)

# Import Pico SDK (will download if PICO_SDK_PATH not set)
include(CMake/pico_sdk_import.cmake)

project(Pico C CXX ASM)
# ------------------------------------------------------------------------------
# Project Definition
# ------------------------------------------------------------------------------

project(PicoOS
VERSION 0.4.0
DESCRIPTION "A microkernel-inspired OS for the Raspberry Pi Pico"
LANGUAGES C CXX ASM
)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Initialize Pico SDK
pico_sdk_init()

# FIXME: This is mostly necessary for the SDK
set(DISABLE_WARNINGS -Wno-unused-parameter -Wno-type-limits)
set(DISABLE_CXX_WARNINGS -Wno-reorder -Wno-ignored-qualifiers)
# ------------------------------------------------------------------------------
# Compiler Options
# ------------------------------------------------------------------------------

# Warnings to suppress from Pico SDK headers (not our code)
set(SDK_WARNINGS_OFF
-Wno-unused-parameter
-Wno-type-limits
)

set(SDK_CXX_WARNINGS_OFF
-Wno-reorder
-Wno-ignored-qualifiers
)

# Common compile options interface
add_library(project_options INTERFACE)
target_compile_options(project_options INTERFACE -fdiagnostics-color=always -Wall ${DISABLE_WARNINGS} -Wextra -Werror -O0)
target_compile_options(project_options INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-frtti ${DISABLE_CXX_WARNINGS}>)
target_include_directories(project_options INTERFACE ${CMAKE_SOURCE_DIR})

target_compile_options(project_options INTERFACE
-fdiagnostics-color=always
-Wall
-Wextra
-Werror
-O0
-fstack-protector-strong
${SDK_WARNINGS_OFF}
)

target_compile_options(project_options INTERFACE
$<$<COMPILE_LANGUAGE:CXX>:
-frtti
${SDK_CXX_WARNINGS_OFF}
>
)

target_include_directories(project_options INTERFACE
${CMAKE_SOURCE_DIR}
)

# ------------------------------------------------------------------------------
# Userland Applications
# ------------------------------------------------------------------------------

add_subdirectory(Userland)

file(GLOB_RECURSE Kernel_SOURCES CONFIGURE_DEPENDS Kernel/*.cpp Kernel/*.S Std/*.cpp)
# ------------------------------------------------------------------------------
# Kernel Build
# ------------------------------------------------------------------------------

file(GLOB_RECURSE KERNEL_SOURCES CONFIGURE_DEPENDS
Kernel/*.cpp
Kernel/*.S
Std/*.cpp
)

add_executable(Kernel.1 ${KERNEL_SOURCES})

target_link_libraries(Kernel.1
pico_stdlib
pico_bootrom
hardware_dma
project_options
LibEmbeddedFiles
)

add_executable(Kernel.1 ${Kernel_SOURCES})
target_link_libraries(Kernel.1 pico_stdlib pico_bootrom hardware_dma project_options LibEmbeddedFiles)
target_compile_definitions(Kernel.1 PRIVATE KERNEL)
target_compile_definitions(Kernel.1 PRIVATE
KERNEL
)

# Use custom linker script with alignment fixes
pico_set_linker_script(Kernel.1 ${CMAKE_CURRENT_SOURCE_DIR}/Kernel/linker.ld)

# Generate .uf2, .bin, .hex outputs
pico_add_extra_outputs(Kernel.1)

# ------------------------------------------------------------------------------
# Stripped Kernel for Production
# ------------------------------------------------------------------------------

add_custom_target(Kernel.elf ALL
COMMAND arm-none-eabi-objcopy
--strip-symbol=__flash_data_2
--strip-symbol=__flash_data_3
--strip-symbol=__flash_data_4
--strip-symbol=__flash_data_5
--strip-symbol=__flash_base
Kernel.1.elf Kernel.elf
DEPENDS Kernel.1)
Kernel.1.elf Kernel.elf
DEPENDS Kernel.1
COMMENT "Creating stripped Kernel.elf"
)

# ------------------------------------------------------------------------------
# Summary
# ------------------------------------------------------------------------------

message(STATUS "--------------------------------------------------------------")
message(STATUS "PicoOS v${PROJECT_VERSION}")
message(STATUS " Platform: RP2040 (Raspberry Pi Pico)")
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS " C Standard: ${CMAKE_C_STANDARD}")
message(STATUS " C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "--------------------------------------------------------------")
Loading