Initial setup
This commit is contained in:
@@ -0,0 +1,89 @@
|
|||||||
|
SRC_DIR := src
|
||||||
|
BIN_DIR := bin
|
||||||
|
OBJ_DIR := build
|
||||||
|
INCLUDE_DIR := include
|
||||||
|
|
||||||
|
CXX ?= g++
|
||||||
|
CC ?= gcc
|
||||||
|
|
||||||
|
TARGET_DEBUG := $(BIN_DIR)/blade-dbg
|
||||||
|
TARGET_RELEASE := $(BIN_DIR)/blade
|
||||||
|
|
||||||
|
PCH_DIR_DEBUG := $(OBJ_DIR)/debug/pch
|
||||||
|
PCH_DIR_RELEASE := $(OBJ_DIR)/release/pch
|
||||||
|
|
||||||
|
PCH_DEBUG := $(PCH_DIR_DEBUG)/pch.h.gch
|
||||||
|
PCH_RELEASE := $(PCH_DIR_RELEASE)/pch.h.gch
|
||||||
|
|
||||||
|
MRUBY_CFLAGS ?= -I./libs/mruby/build/host/include
|
||||||
|
MRUBY_LIBS ?= -L./libs/mruby/build/host/lib -lmruby
|
||||||
|
|
||||||
|
CFLAGS_DEBUG :=\
|
||||||
|
-std=c++23 -Wall -Wextra -fno-rtti \
|
||||||
|
-Og -fno-inline -gsplit-dwarf -DDEBUG \
|
||||||
|
-g -fno-omit-frame-pointer -ffast-math \
|
||||||
|
-I./include
|
||||||
|
|
||||||
|
CFLAGS_RELEASE :=\
|
||||||
|
-std=c++23 -O3 -mtune=generic -fno-rtti \
|
||||||
|
-fvisibility=hidden -static -ffast-math \
|
||||||
|
-fomit-frame-pointer -DNDEBUG -s \
|
||||||
|
-I./include
|
||||||
|
|
||||||
|
CFLAGS_DEBUG += $(MRUBY_CFLAGS)
|
||||||
|
CFLAGS_RELEASE += $(MRUBY_CFLAGS)
|
||||||
|
|
||||||
|
LIBS := $(MRUBY_LIBS)
|
||||||
|
|
||||||
|
SRC := $(shell find $(SRC_DIR) -type f -name '*.cc')
|
||||||
|
OBJ_DEBUG := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/debug/%.o,$(SRC))
|
||||||
|
OBJ_RELEASE := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/release/%.o,$(SRC))
|
||||||
|
|
||||||
|
DEP_DEBUG := $(OBJ_DEBUG:.o=.d)
|
||||||
|
DEP_RELEASE := $(OBJ_RELEASE:.o=.d)
|
||||||
|
|
||||||
|
.PHONY: all debug release clean
|
||||||
|
|
||||||
|
all: release
|
||||||
|
|
||||||
|
debug: $(TARGET_DEBUG)
|
||||||
|
|
||||||
|
release: $(TARGET_RELEASE)
|
||||||
|
|
||||||
|
$(PCH_DEBUG): $(INCLUDE_DIR)/pch.h
|
||||||
|
@mkdir -p $(PCH_DIR_DEBUG)
|
||||||
|
@$(CXX) $(CFLAGS_DEBUG) -x c++-header -o $@ $(INCLUDE_DIR)/pch.h
|
||||||
|
@echo "Debug Precompiled header generated at $@"
|
||||||
|
|
||||||
|
$(PCH_RELEASE): $(INCLUDE_DIR)/pch.h
|
||||||
|
@mkdir -p $(PCH_DIR_RELEASE)
|
||||||
|
@$(CXX) $(CFLAGS_RELEASE) -x c++-header -o $@ $(INCLUDE_DIR)/pch.h
|
||||||
|
@echo "Release Precompiled header generated at $@"
|
||||||
|
|
||||||
|
$(TARGET_DEBUG): $(PCH_DEBUG) $(OBJ_DEBUG)
|
||||||
|
@mkdir -p $(BIN_DIR)
|
||||||
|
@$(CXX) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(LIBS)
|
||||||
|
@echo "Debug build complete: $@"
|
||||||
|
|
||||||
|
$(TARGET_RELEASE): $(PCH_RELEASE) $(OBJ_RELEASE)
|
||||||
|
@mkdir -p $(BIN_DIR)
|
||||||
|
@$(CXX) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE)$(LIBS)
|
||||||
|
@strip $@
|
||||||
|
@echo "Release build complete: $@"
|
||||||
|
|
||||||
|
$(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc $(PCH_DEBUG) $(GENERATED_HEADER)
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
@$(CXX) $(CFLAGS_DEBUG) -I$(PCH_DIR_DEBUG) -include pch.h -MMD -MP -c $< -o $@
|
||||||
|
@echo "[CXX] Debug object file generated: $@ from $<"
|
||||||
|
|
||||||
|
$(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE) $(GENERATED_HEADER)
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
@$(CXX) $(CFLAGS_RELEASE) -I$(PCH_DIR_RELEASE) -include pch.h -MMD -MP -c $< -o $@
|
||||||
|
@echo "[CXX] release object file generated: $@ from $<"
|
||||||
|
|
||||||
|
-include $(DEP_DEBUG)
|
||||||
|
-include $(DEP_RELEASE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf $(OBJ_DIR) $(BIN_DIR)
|
||||||
|
@echo "Cleaned build artifacts."
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
description = "Blade";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
self.submodules = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ nixpkgs, ... }:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system}.pkgsStatic;
|
||||||
|
hostPkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
|
mruby = pkgs.stdenv.mkDerivation {
|
||||||
|
pname = "mruby";
|
||||||
|
version = "0.0.1";
|
||||||
|
|
||||||
|
src = pkgs.lib.cleanSourceWith {
|
||||||
|
src = ./libs;
|
||||||
|
name = "mruby-src";
|
||||||
|
};
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
./libs/changes.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeBuildInputs = with hostPkgs; [
|
||||||
|
ruby
|
||||||
|
gnumake
|
||||||
|
];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
cd mruby
|
||||||
|
rake
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
cp -r build/host/lib $out/lib
|
||||||
|
cp -r build/host/include $out/include
|
||||||
|
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp build/host/bin/mrbc $out/bin/mrbc
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
blade = pkgs.stdenv.mkDerivation {
|
||||||
|
pname = "blade";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = with hostPkgs; [
|
||||||
|
bash
|
||||||
|
pkg-config
|
||||||
|
gnumake
|
||||||
|
findutils
|
||||||
|
binutils
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
mruby
|
||||||
|
];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
make \
|
||||||
|
MRUBY_CFLAGS="-I${mruby}/include" \
|
||||||
|
MRUBY_LIBS="-L${mruby}/lib -lmruby"
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp bin/blade $out/bin/blade
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
packages.${system} = {
|
||||||
|
default = blade;
|
||||||
|
blade = blade;
|
||||||
|
mruby = mruby;
|
||||||
|
};
|
||||||
|
|
||||||
|
devShells.${system}.default = hostPkgs.mkShell {
|
||||||
|
inputsFrom = [ blade ];
|
||||||
|
|
||||||
|
packages = with hostPkgs; [
|
||||||
|
clang-tools
|
||||||
|
pkg-config
|
||||||
|
ccache
|
||||||
|
gnumake
|
||||||
|
bear
|
||||||
|
ruby
|
||||||
|
gdb
|
||||||
|
binutils
|
||||||
|
findutils
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export CC="ccache $CC"
|
||||||
|
export CXX="ccache $CXX"
|
||||||
|
|
||||||
|
export MRUBY_CFLAGS=-I${mruby}/include
|
||||||
|
export MRUBY_LIBS="-L${mruby}/lib -lmruby"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
# Blade is a PID 1
|
||||||
|
|
||||||
|
## Core
|
||||||
|
|
||||||
|
* [ ] Custom C++ userspace / init system
|
||||||
|
* [ ] Everything runs in one main PID 1 process
|
||||||
|
* [ ] Keep subsystems code-wise separate internally
|
||||||
|
* [ ] Single-user system
|
||||||
|
* [ ] Custom privilege escalation binary (`sudo`-like)
|
||||||
|
|
||||||
|
## Init / Service Manager
|
||||||
|
|
||||||
|
* [ ] PID 1 handles system initialization
|
||||||
|
* [ ] Start/stop/restart services
|
||||||
|
* [ ] Service dependencies
|
||||||
|
* [ ] Service ordering / stages
|
||||||
|
* [ ] Continuous service supervision
|
||||||
|
* [ ] Ruby-defined service configuration
|
||||||
|
* [ ] Ruby hooks for service events
|
||||||
|
* [ ] Runtime service control through Ruby socket
|
||||||
|
|
||||||
|
## Package Manager
|
||||||
|
|
||||||
|
* [ ] Built into the main userspace
|
||||||
|
* [ ] Packages defined as Ruby scripts
|
||||||
|
* [ ] Packages use Git sources
|
||||||
|
* [ ] Build using `make` commands
|
||||||
|
* [ ] Package dependencies
|
||||||
|
* [ ] Install/update packages
|
||||||
|
* [ ] Cleanup/remove unused packages
|
||||||
|
* [ ] Package hooks
|
||||||
|
* [ ] Hooks can add services/configuration/etc.
|
||||||
|
* [ ] Build required packages during startup
|
||||||
|
|
||||||
|
## Ruby
|
||||||
|
|
||||||
|
* [ ] Embedded static mruby
|
||||||
|
* [ ] Ruby is the main configuration language
|
||||||
|
* [ ] Same Ruby system defines packages + services + hooks
|
||||||
|
* [ ] Ruby commands available at runtime over a socket
|
||||||
|
* [ ] Runtime API for controlling the system
|
||||||
|
* [ ] Hooks / shortcuts can react to system events
|
||||||
|
|
||||||
|
## Built-in Components
|
||||||
|
|
||||||
|
* [ ] D-Bus broker
|
||||||
|
* [ ] Wayland compositor
|
||||||
|
- Notifications (also connects to dbus)
|
||||||
|
- Clipboard with history, and api to read/work with history.
|
||||||
|
* [ ] Terminal emulator
|
||||||
|
* [ ] Session manager
|
||||||
|
* [ ] Package manager
|
||||||
|
* [ ] Service manager
|
||||||
|
* [ ] System configuration/runtime API
|
||||||
|
|
||||||
|
## Boot Sequence
|
||||||
|
|
||||||
|
1. Start basic services
|
||||||
|
* Networking
|
||||||
|
* Audio
|
||||||
|
* Other essential infrastructure
|
||||||
|
2. Run package manager
|
||||||
|
* Build/update/install required packages
|
||||||
|
* Cleanup
|
||||||
|
* Run package hooks
|
||||||
|
3. Start TTY2
|
||||||
|
* Launch shell
|
||||||
|
4. Start normal non-desktop services
|
||||||
|
5. Start Wayland on TTY1
|
||||||
|
6. Wayland starts in `locker` state
|
||||||
|
7. Start services that depend on Wayland
|
||||||
|
8. Resolve service dependencies/order
|
||||||
|
9. Enter continuous runtime/event loop
|
||||||
|
|
||||||
|
## Wayland / Desktop
|
||||||
|
|
||||||
|
* [ ] Wayland compositor is built into PID 1
|
||||||
|
* [ ] TTY1 is graphical
|
||||||
|
* [ ] TTY2 is shell/terminal
|
||||||
|
* [ ] Desktop states:
|
||||||
|
* `locker`
|
||||||
|
* `terminal`
|
||||||
|
* `application`
|
||||||
|
* [ ] `application` state gives each application its own workspace
|
||||||
|
* [ ] System owns/controls the login/unlock password
|
||||||
|
* [ ] No traditional display manager
|
||||||
|
* [ ] One built-in terminal emulator
|
||||||
|
* [ ] Consider multiplexing later if actually needed
|
||||||
|
|
||||||
|
## Runtime
|
||||||
|
|
||||||
|
* [ ] Everything remains active after boot
|
||||||
|
* [ ] Event-driven system
|
||||||
|
* [ ] Ruby command socket
|
||||||
|
* [ ] Runtime configuration changes
|
||||||
|
* [ ] Hooks can react to:
|
||||||
|
* service events
|
||||||
|
* package events
|
||||||
|
* Wayland events
|
||||||
|
* shortcuts
|
||||||
|
* system events
|
||||||
|
* [ ] Continuously monitor and manage services
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// PID 1
|
||||||
|
|
||||||
|
int console = open("/dev/console", O_RDWR);
|
||||||
|
|
||||||
|
if (console < 0)
|
||||||
|
{
|
||||||
|
perror("open /dev/console");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dup2(console, STDIN_FILENO);
|
||||||
|
dup2(console, STDOUT_FILENO);
|
||||||
|
dup2(console, STDERR_FILENO);
|
||||||
|
|
||||||
|
close(console);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
execl("/bin/sh", "sh", nullptr);
|
||||||
|
perror("exec");
|
||||||
|
_exit(127);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid > 0)
|
||||||
|
{
|
||||||
|
waitpid(pid, nullptr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user