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
17 changes: 17 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Fishix Documentation Hub

This directory contains technical documentation for various subsystems of the Fishix kernel.

## Implementation Navigation

### [DMA Subsystem](./dma/README.md)
Detailed information about the Direct Memory Access (DMA) management, coherent memory allocation, and physical contiguous page management.

### [DRM (Direct Rendering Manager)](./drm/README.md)
Documentation regarding the implementation of the DRM/KMS subsystem, GEM (Graphics Execution Manager), and the Fishix-specific DRM driver.

### [Wayland Support](./wayland/README.md)
Overview of how Fishix supports Wayland compositors (like Weston) through DRM/KMS and Linux ABI compatibility.

---
*For general building and running instructions, see the root [README](../README.md).*
22 changes: 22 additions & 0 deletions docs/dma/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# DMA (Direct Memory Access) Subsystem

The DMA subsystem in Fishix provides essential services for hardware devices to access system memory efficiently and safely.

## Key Components

### 1. Coherent Memory Allocation
`mem::dma::alloc_coherent()` allocates physically contiguous memory that is guaranteed to be cache-coherent between the CPU and devices.
- **Implementation**: Uses the PMM (Physical Memory Manager) to find contiguous pages and returns a virtual address from the HHDM (Higher Half Direct Mapping) or kernel heap.
- **Header**: `kernel/src/mem/dma.hpp`
- **Source**: `kernel/src/mem/dma.cpp`

### 2. Physical Page Management
Low-level operations to allocate and free contiguous physical pages:
- `alloc_contiguous_pages(num_pages)`: Returns the base physical address.
- `free_contiguous_pages(base, num_pages)`

### 3. Userspace Mapping (mmap)
`mmap_buffer()` allows the kernel to map a dma-coherent buffer directly into a process's virtual address space, which is critical for zero-copy graphics rendering in Wayland.

## Compatibility
The DMA constants used in Fishix (e.g., `DMA_BIDIRECTIONAL`) are kept compatible with the Linux kernel's `dma-buf.h` to simplify driver porting.
35 changes: 35 additions & 0 deletions docs/drm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# DRM (Direct Rendering Manager) & KMS Engine

The DRM subsystem in Fishix provides a kernel-mode setting (KMS) interface for managing displays and graphics buffers, enabling modern windowing systems like Wayland.

## Components

### 1. DRM Core
The standard framework for managing DRM devices, files, and objects.
- **Header**: `kernel/src/drivers/drm/drm_internal.hpp`
- **Source**: `kernel/src/drivers/drm/drm_core.cpp`

### 2. KMS (Kernel Mode Setting)
Implements modesetting operations like:
- **Device Resources**: CRTCs, Encoders, Connectors, and Planes.
- **Mode Selection**: Detection and setting of screen resolutions.
- **Page Flipping**: Support for `DRM_IOCTL_MODE_PAGE_FLIP` to allow smooth, tear-free rendering with double/triple buffering.
- **Source**: `kernel/src/drivers/drm/drm_modeset.cpp`

### 3. GEM (Graphics Execution Manager)
Handles graphics buffer allocation and sharing.
- **Dumb Buffers**: Simple linear buffers allocated via `DRM_IOCTL_MODE_CREATE_DUMB` that are mapped to userspace for drawing.
- **Flink & Open**: Name-based buffer sharing between processes.
- **Source**: `kernel/src/drivers/drm/drm_gem.cpp`

### 4. Fishix-DRM Virtual Driver
A virtual DRM driver that wraps the standard Fishix hardware framebuffer.
- **Feature**: Allows high-level DRM-aware apps to render to the existing Fishix display through a unified API.
- **Device Node**: `/dev/dri/card0`
- **Source**: `kernel/src/drivers/drm/fishix_drm.cpp`

## VFS Integration
The DRM subsystem integrates into Fishix's VFS through a custom `DRMDevNode` that implements `open`, `ioctl`, `mmap`, and `poll` handlers.

---
*For more info about Wayland specifically, see the [Wayland Documentation](../wayland/README.md).*
37 changes: 37 additions & 0 deletions docs/wayland/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Wayland Support in Fishix

Fishix aims to support native Wayland compositors (such as Weston, Sway, or GNOME/KDE's Wayland backends) through an implemented Linux ABI and a fully functional DRM/KMS subsystem.

## Wayland Rendering Stack

1. **Wayland Compositor**: (e.g. `weston` with the `drm` backend selected)
2. **DRM Subsystem**: (KMS) handles screen modes and framebuffers.
3. **GEM & DMA**: (Dumb Buffers) provide the linear memory for compositors to draw the UI.
4. **Hardware FB**: The actual screen display through the virtual DRM driver.

## Key Requirements for Wayland to Work

### 1. DRM Device Node (`/dev/dri/card0`)
The compositor must be able to open the DRM device to query capabilities and set modes.

### 2. KMS Capability Implementation
Fishix must support:
- `DRM_IOCTL_GET_RESOURCES`
- `DRM_IOCTL_MODE_ADDFB2`
- `DRM_IOCTL_MODE_SETCRTC`
- `DRM_IOCTL_MODE_PAGE_FLIP` (with VBlank events)

### 3. Dumb Buffer mmap
The compositor must be able to allocate linear buffers via `DRM_IOCTL_MODE_CREATE_DUMB` and `mmap` them to its own address space.

## Status in Fishix
As of now, the kernel-side API for Wayland support is **complete**:
- [x] GEM allocation and sharing (Flink/Open)
- [x] KMS Modesetting and Page flipping
- [x] Device node registration for `/dev/dri/card0`
- [x] `mmap` support for graphics buffers
- [x] VBlank event emission for frame timing

Compositors can now be tested by running them in the Fishix userspace.
---
*See the [DRM Document](../drm/README.md) for deeper kernel implementation details.*
69 changes: 49 additions & 20 deletions kernel/meson.build
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
project('fishix', ['cpp', 'c', 'nasm'], default_options: [
'buildtype=debug', 'warning_level=2', 'cpp_std=gnu++23'
])
project('fishix', ['cpp', 'c', 'nasm'],
default_options: [
'buildtype=debug',
'warning_level=2',
'cpp_std=gnu++23',
]
)

fs = import('fs')

add_global_arguments([
'-g3', '-pipe',
'-Wno-unused-parameter', '-Wno-missing-field-initializers',
'-g3',
'-pipe',
'-Wno-unused-parameter',
'-Wno-missing-field-initializers',

'-ffreestanding',
'-fstack-protector',
'-fno-pie',
'-fno-pic',

'-fno-omit-frame-pointer',
'-mno-omit-leaf-frame-pointer',

'-march=x86-64',
'-mabi=sysv',

'-mno-80387',
'-mno-mmx',
'-mno-sse',
'-mno-sse2',

'-mno-red-zone',
'-mgeneral-regs-only',

'-mcmodel=kernel',
'-MMD',
], language: ['cpp', 'c'])
], language: ['c', 'cpp'])

add_global_arguments([
'-fno-exceptions',
Expand All @@ -37,20 +48,17 @@ add_global_link_arguments([
'-static',
'-z', 'noexecstack',
'-T' + meson.current_source_dir() / 'linker.ld',
], language: ['cpp', 'c'])
], language: ['c', 'cpp'])

src_include_dir = include_directories('src')

dependencies = []

source_files = [
'src/kernel.cpp',
'src/ubsan.cpp',

'src/acpi/tables.cpp',

'src/cpu/cpu.cpp',

'src/cpu/gdt/gdt.cpp',
'src/cpu/gdt/gdt_flush.asm',

Expand Down Expand Up @@ -90,6 +98,13 @@ source_files = [
'src/gfx/framebuffer.cpp',
'src/gfx/terminal.cpp',

'src/mem/dma.cpp',
'src/drivers/drm/drm_core.cpp',
'src/drivers/drm/drm_gem.cpp',
'src/drivers/drm/drm_modeset.cpp',
'src/drivers/drm/drm_fops.cpp',
'src/drivers/drm/fishix_drm.cpp',

'src/klib/cppruntime.cpp',
'src/klib/cstdio.cpp',
'src/klib/cstdlib.cpp',
Expand Down Expand Up @@ -135,26 +150,40 @@ fonts = [
'ter-u16b.psf',
]

ld = find_program('ld')

font_copy_targets = []
foreach font : fonts
font_copy_targets += custom_target(
'copy font @0@'.format(font.split('/').get(-1)),
command: [ 'cp', '@INPUT@', '@OUTPUT@' ],
'copy_' + font,
command: ['cp', '@INPUT@', '@OUTPUT@'],
input: font,
output: '@PLAINNAME@'
)
endforeach

ld = find_program('ld')
font_object_targets = []
foreach font_copy_target : font_copy_targets
font = font_copy_target.full_path().split('/').get(-1)

i = 0
foreach font : fonts
font_object_targets += custom_target(
'font object @0@'.format(font),
command: [ ld, '--relocatable', '--format', 'binary', '--output', '@OUTPUT@', '@INPUT@' ],
input: font_copy_target,
output: '@BASENAME@.o'
'obj_' + font,
command: [
ld,
'--relocatable',
'--format', 'binary',
'--output', '@OUTPUT@',
'@INPUT@'
],
input: font_copy_targets[i],
output: font + '.o'
)
i += 1
endforeach

executable('fishix', [source_files, font_object_targets], include_directories: src_include_dir, dependencies: dependencies, install: true)
executable(
'fishix',
[source_files, font_object_targets],
include_directories: src_include_dir,
install: true
)
48 changes: 48 additions & 0 deletions kernel/src/cat.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash

# ===============================
# Recursive Cat Script
# Usage:
# ./cat.sh output.file [folder]
# ===============================

# cek argumen
if [ -z "$1" ]; then
echo "Usage: $0 output.file [folder]"
exit 1
fi

OUTPUT="$1"
TARGET="${2:-.}" # default folder = current dir

# kosongkan file output
> "$OUTPUT"

# fungsi rekursif
process_dir() {
local dir="$1"

for item in "$dir"/*; do
# skip jika tidak ada file
[ -e "$item" ] || continue

if [ -d "$item" ]; then
# rekursif masuk folder
process_dir "$item"

elif [ -f "$item" ]; then
# tulis header
echo "=== ${item#./} ===" >> "$OUTPUT"

# isi file
cat "$item" >> "$OUTPUT"

# newline pemisah
echo -e "\n" >> "$OUTPUT"
fi
done
}

process_dir "$TARGET"

echo "Selesai -> $OUTPUT"
3 changes: 2 additions & 1 deletion kernel/src/dev/input/usbhid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ namespace dev::input::usbhid {
void Device::parse_report_descriptor(u8 *data, u16 length) {
// Global state
u32 usage_page = 0;
i32 logical_minimum = 0, logical_maximum = 0;
[[maybe_unused]] i32 logical_minimum = 0;
[[maybe_unused]] i32 logical_maximum = 0;
u32 report_size = 0;
u32 report_count = 0;

Expand Down
Loading