mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 10:26:59 +00:00
Compare commits
167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6d512b0f2 | ||
|
|
0b7a134282 | ||
|
|
91b67bd8d5 | ||
|
|
e60f232812 | ||
|
|
3169ec51cb | ||
|
|
beb2c724ff | ||
|
|
bf3c2cb578 | ||
|
|
823e9c0ce7 | ||
|
|
0ddb1e7610 | ||
|
|
32a6bb4d72 | ||
|
|
d8e680604c | ||
|
|
2e28f860cb | ||
|
|
9634ebb086 | ||
|
|
d7d97b5a97 | ||
|
|
4a3752583c | ||
|
|
9de8ee143c | ||
|
|
8d5fa53d3e | ||
|
|
ad8db32305 | ||
|
|
92928e55fb | ||
|
|
31eb7afdc6 | ||
|
|
ad9fac3e28 | ||
|
|
70cd296d19 | ||
|
|
b7020152c1 | ||
|
|
63749b8734 | ||
|
|
4e8ea5acd2 | ||
|
|
5c199e028a | ||
|
|
ec2a9d1883 | ||
|
|
4c46650c64 | ||
|
|
1ee2fcad9e | ||
|
|
5c29ac1473 | ||
|
|
81743261bf | ||
|
|
4eeb907342 | ||
|
|
e527f63af7 | ||
|
|
1e19963a8d | ||
|
|
60ab70a49d | ||
|
|
d9bcc4aff7 | ||
|
|
5604866882 | ||
|
|
e95c82b162 | ||
|
|
9fb307e603 | ||
|
|
a7c3cccce7 | ||
|
|
7eb55f3a59 | ||
|
|
72baf6506d | ||
|
|
2817ad51da | ||
|
|
5b10127e02 | ||
|
|
1404a6ae4f | ||
|
|
7b7f134e27 | ||
|
|
0491c4ad0f | ||
|
|
c6fe9971d8 | ||
|
|
88f178e368 | ||
|
|
d824b4610a | ||
|
|
a4f16b0604 | ||
|
|
83413fdd2b | ||
|
|
2a918bc7ba | ||
|
|
2624b4f8df | ||
|
|
be67c27f58 | ||
|
|
65f362feab | ||
|
|
6b18d44fab | ||
|
|
8b172a69a1 | ||
|
|
0846ed27b2 | ||
|
|
1cb8425653 | ||
|
|
f403816acf | ||
|
|
5af6b8ec5c | ||
|
|
cea0b59c93 | ||
|
|
c5111cdcb5 | ||
|
|
803ebdaefa | ||
|
|
884af3857f | ||
|
|
b427b1d4ac | ||
|
|
d01c309166 | ||
|
|
fc83d7941b | ||
|
|
3da1496e4f | ||
|
|
90e5125913 | ||
|
|
30f1b66b05 | ||
|
|
6c273e0f2f | ||
|
|
4bab8949e7 | ||
|
|
df73f00efd | ||
|
|
b05b221c41 | ||
|
|
95c465ca39 | ||
|
|
569adabf10 | ||
|
|
43a9735f81 | ||
|
|
93b59064c7 | ||
|
|
d19075750b | ||
|
|
8ba03fac72 | ||
|
|
071f8339bf | ||
|
|
dbaff43c6f | ||
|
|
624db9ec9c | ||
|
|
512912c821 | ||
|
|
989ef019d4 | ||
|
|
6a41be2437 | ||
|
|
1639b09cb5 | ||
|
|
1b181772a1 | ||
|
|
6d7f9870f3 | ||
|
|
b40d3c050d | ||
|
|
3fbcf3d4fd | ||
|
|
032b154f41 | ||
|
|
bfac4bf65c | ||
|
|
41d1e3960b | ||
|
|
b708ad7e45 | ||
|
|
4b8fdde06d | ||
|
|
690413045d | ||
|
|
e5cfab37dc | ||
|
|
d49d082712 | ||
|
|
9bb62a5ade | ||
|
|
903d4e0510 | ||
|
|
cc752052dc | ||
|
|
4083b8a563 | ||
|
|
3c7d36a50f | ||
|
|
8b3ca448ed | ||
|
|
36219f5828 | ||
|
|
10ca6ef345 | ||
|
|
80fce3d0e9 | ||
|
|
d38e8b97e2 | ||
|
|
48ad5470ee | ||
|
|
659feee6f7 | ||
|
|
01345ba2b6 | ||
|
|
22dd21c580 | ||
|
|
67640ec8db | ||
|
|
c0eaf4c89b | ||
|
|
35f3a5410a | ||
|
|
42bcc1ad7c | ||
|
|
5cf552fd14 | ||
|
|
8bd70faa89 | ||
|
|
8d3c0486ff | ||
|
|
05c1f37a86 | ||
|
|
c5c77ce734 | ||
|
|
a4e0a42042 | ||
|
|
8afb488539 | ||
|
|
cb4edb6264 | ||
|
|
81d60f144c | ||
|
|
4c0d9886aa | ||
|
|
74bdb89ad3 | ||
|
|
fbd0bf880e | ||
|
|
857b11220c | ||
|
|
981d2cb4f4 | ||
|
|
f299ae6f23 | ||
|
|
ed0535b822 | ||
|
|
9ae0b16b71 | ||
|
|
8a6928b5c9 | ||
|
|
304c2e1383 | ||
|
|
8c6d751254 | ||
|
|
f9d84d434e | ||
|
|
a34aaa1070 | ||
|
|
34ceff4290 | ||
|
|
fcc290f3f9 | ||
|
|
2801dbc21f | ||
|
|
786eac0345 | ||
|
|
c2ead0d6a7 | ||
|
|
23ec181f29 | ||
|
|
616ff8084b | ||
|
|
73a34edd0e | ||
|
|
ca997072ce | ||
|
|
cc950974e8 | ||
|
|
6e2f0d8c1a | ||
|
|
106adf1ac8 | ||
|
|
f694c490a6 | ||
|
|
f6e53fa7c6 | ||
|
|
b4cccb0eb3 | ||
|
|
6f68538b86 | ||
|
|
2ca2809904 | ||
|
|
22b99e051d | ||
|
|
60ea9defc0 | ||
|
|
658c5eb0ed | ||
|
|
e3e4432a3a | ||
|
|
df5c117f65 | ||
|
|
1842ea3b67 | ||
|
|
8dcc3ff40c | ||
|
|
5bdbb59200 | ||
|
|
f06940f21f |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
|||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto
|
|
||||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -18,3 +18,15 @@ limine 2/Makefile
|
|||||||
limine 2/limine
|
limine 2/limine
|
||||||
limine 2/limine.dSYM/Contents/Resources/DWARF/limine
|
limine 2/limine.dSYM/Contents/Resources/DWARF/limine
|
||||||
limine 2/limine.exe
|
limine 2/limine.exe
|
||||||
|
boredos.dump
|
||||||
|
qemu-debug.log
|
||||||
|
iso_root/
|
||||||
|
limine/
|
||||||
|
src/userland/bin/
|
||||||
|
boredos.iso
|
||||||
|
disk.img
|
||||||
|
limine
|
||||||
|
**/.DS_Store
|
||||||
|
.DS_Store
|
||||||
|
/build/
|
||||||
|
*.o
|
||||||
6
LICENSE
6
LICENSE
@@ -647,7 +647,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/\>.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
@@ -666,11 +666,11 @@ might be different; for a GUI interface, you would use an "about box".
|
|||||||
You should also get your employer (if you work as a programmer) or school,
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
<https://www.gnu.org/licenses/>.
|
<https://www.gnu.org/licenses/\>.
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
The GNU General Public License does not permit incorporating your program
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
may consider it more useful to permit linking proprietary applications with
|
may consider it more useful to permit linking proprietary applications with
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
Public License instead of this License. But first, please read
|
Public License instead of this License. But first, please read
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
<https://www.gnu.org/licenses/why-not-lgpl.html\>.
|
||||||
|
|||||||
178
Makefile
178
Makefile
@@ -1,122 +1,212 @@
|
|||||||
# BrewOS Makefile
|
# BoredOS Makefile
|
||||||
# Target Architecture: x86_64
|
# Target Architecture: x86_64
|
||||||
# Host: macOS
|
# Host: macOS
|
||||||
|
# Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
# This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
# This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
|
||||||
CC = x86_64-elf-gcc
|
CC = x86_64-elf-gcc
|
||||||
LD = x86_64-elf-ld
|
LD = x86_64-elf-ld
|
||||||
NASM = nasm
|
NASM = nasm
|
||||||
XORRISO = xorriso
|
XORRISO = xorriso
|
||||||
|
|
||||||
SRC_DIR = src/kernel
|
SRC_DIR = src
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
ISO_DIR = iso_root
|
ISO_DIR = iso_root
|
||||||
|
|
||||||
KERNEL_ELF = $(BUILD_DIR)/brewos.elf
|
KERNEL_ELF = $(BUILD_DIR)/boredos.elf
|
||||||
ISO_IMAGE = brewos.iso
|
ISO_IMAGE = boredos.iso
|
||||||
|
|
||||||
C_SOURCES = $(wildcard $(SRC_DIR)/*.c)
|
C_SOURCES = $(wildcard $(SRC_DIR)/core/*.c) \
|
||||||
CLI_APP_SOURCES = $(wildcard $(SRC_DIR)/cli_apps/*.c)
|
$(wildcard $(SRC_DIR)/sys/*.c) \
|
||||||
ASM_SOURCES = $(wildcard $(SRC_DIR)/*.asm)
|
$(wildcard $(SRC_DIR)/mem/*.c) \
|
||||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(C_SOURCES)) \
|
$(wildcard $(SRC_DIR)/dev/*.c) \
|
||||||
$(patsubst $(SRC_DIR)/cli_apps/%.c, $(BUILD_DIR)/cli_apps/%.o, $(CLI_APP_SOURCES)) \
|
$(wildcard $(SRC_DIR)/net/*.c) \
|
||||||
$(patsubst $(SRC_DIR)/%.asm, $(BUILD_DIR)/%.o, $(ASM_SOURCES))
|
$(wildcard $(SRC_DIR)/net/nic/*.c) \
|
||||||
|
$(wildcard $(SRC_DIR)/fs/*.c) \
|
||||||
|
$(wildcard $(SRC_DIR)/wm/*.c) \
|
||||||
|
$(wildcard $(SRC_DIR)/net/lwip/core/*.c) \
|
||||||
|
$(wildcard $(SRC_DIR)/net/lwip/core/ipv4/*.c) \
|
||||||
|
$(SRC_DIR)/net/lwip/netif/ethernet.c \
|
||||||
|
$(SRC_DIR)/net/lwip/netif/bridgeif.c
|
||||||
|
|
||||||
|
ASM_SOURCES = $(wildcard $(SRC_DIR)/arch/*.asm)
|
||||||
|
OBJ_FILES = $(patsubst $(SRC_DIR)/core/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/core/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/sys/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/sys/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/mem/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/mem/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/dev/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/dev/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/net/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/net/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/net/nic/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/net/nic/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/fs/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/fs/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/wm/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/wm/*.c)) \
|
||||||
|
$(patsubst $(SRC_DIR)/net/lwip/%.c, $(BUILD_DIR)/lwip/%.o, $(filter $(SRC_DIR)/net/lwip/%.c, $(C_SOURCES))) \
|
||||||
|
$(patsubst $(SRC_DIR)/arch/%.asm, $(BUILD_DIR)/%.o, $(ASM_SOURCES))
|
||||||
|
|
||||||
CFLAGS = -g -O2 -pipe -Wall -Wextra -std=gnu11 -ffreestanding \
|
CFLAGS = -g -O2 -pipe -Wall -Wextra -std=gnu11 -ffreestanding \
|
||||||
-fno-stack-protector -fno-stack-check -fno-lto -fPIE \
|
-fno-stack-protector -fno-stack-check -fno-lto -fPIE \
|
||||||
-m64 -march=x86-64 -mno-80387 -mno-mmx -mno-sse -mno-sse2 -mno-red-zone \
|
-m64 -march=x86-64 -msse -msse2 -mstackrealign -mno-red-zone \
|
||||||
-I$(SRC_DIR) -I$(SRC_DIR)/cli_apps
|
-I$(SRC_DIR) -I$(SRC_DIR)/net/lwip -I$(SRC_DIR)/core -I$(SRC_DIR)/sys -I$(SRC_DIR)/mem -I$(SRC_DIR)/dev -I$(SRC_DIR)/net -I$(SRC_DIR)/net/nic -I$(SRC_DIR)/fs -I$(SRC_DIR)/wm
|
||||||
|
|
||||||
LDFLAGS = -m elf_x86_64 -nostdlib -static -pie --no-dynamic-linker \
|
LDFLAGS = -m elf_x86_64 -nostdlib -static -pie --no-dynamic-linker \
|
||||||
-z text -z max-page-size=0x1000 -T linker.ld
|
-z text -z max-page-size=0x1000 -T linker.ld
|
||||||
|
|
||||||
NASMFLAGS = -f elf64
|
NASMFLAGS = -f elf64
|
||||||
|
|
||||||
# Limine Version
|
LIMINE_VERSION = 10.8.2
|
||||||
LIMINE_VERSION = 7.0.0
|
|
||||||
LIMINE_URL_BASE = https://github.com/limine-bootloader/limine/raw/v$(LIMINE_VERSION)
|
LIMINE_URL_BASE = https://github.com/limine-bootloader/limine/raw/v$(LIMINE_VERSION)
|
||||||
|
|
||||||
.PHONY: all clean run limine-setup
|
.PHONY: all clean run limine-setup
|
||||||
|
|
||||||
all: $(ISO_IMAGE)
|
all: $(ISO_IMAGE)
|
||||||
|
|
||||||
# Ensure build directories exist
|
|
||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
mkdir -p $(BUILD_DIR)/cli_apps
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
# Download Limine Binaries via Git
|
|
||||||
limine-setup:
|
limine-setup:
|
||||||
@if [ ! -f limine/limine-bios.sys ]; then \
|
@if [ ! -f limine/limine-bios.sys ]; then \
|
||||||
echo "Limine binaries missing or invalid. Cloning v$(LIMINE_VERSION)-binary..."; \
|
echo "Limine binaries missing or invalid. Cloning v$(LIMINE_VERSION)-binary..."; \
|
||||||
rm -rf limine; \
|
rm -rf limine; \
|
||||||
git clone https://github.com/limine-bootloader/limine.git --branch=v$(LIMINE_VERSION)-binary --depth=1 limine; \
|
git clone https://github.com/limine-bootloader/limine.git --branch=v$(LIMINE_VERSION)-binary --depth=1 limine; \
|
||||||
fi
|
fi
|
||||||
@if [ ! -f $(SRC_DIR)/limine.h ]; then \
|
@if [ ! -f $(SRC_DIR)/core/limine.h ]; then \
|
||||||
echo "Copying limine.h..."; \
|
echo "Copying limine.h..."; \
|
||||||
cp limine/limine.h $(SRC_DIR)/limine.h; \
|
cp limine/limine.h $(SRC_DIR)/core/limine.h; \
|
||||||
fi
|
fi
|
||||||
@echo "Building Limine host utility..."; \
|
@echo "Building Limine host utility..."; \
|
||||||
$(MAKE) -C limine
|
$(MAKE) -C limine
|
||||||
|
|
||||||
# Compile C Sources
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
# Compile CLI Apps C Sources
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/core/%.c | $(BUILD_DIR) limine-setup
|
||||||
$(BUILD_DIR)/cli_apps/%.o: $(SRC_DIR)/cli_apps/%.c | $(BUILD_DIR) limine-setup
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
# Assemble ASM Sources
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/sys/%.c | $(BUILD_DIR) limine-setup
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm | $(BUILD_DIR)
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/mem/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/dev/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/net/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/net/nic/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/fs/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/wm/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/lwip/%.o: $(SRC_DIR)/net/lwip/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/arch/%.asm | $(BUILD_DIR)
|
||||||
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/test_syscall.o: $(SRC_DIR)/arch/test_syscall.asm | $(BUILD_DIR)
|
||||||
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/user_test.o: $(SRC_DIR)/arch/user_test.asm | $(BUILD_DIR)
|
||||||
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/process_asm.o: $(SRC_DIR)/arch/process_asm.asm | $(BUILD_DIR)
|
||||||
$(NASM) $(NASMFLAGS) $< -o $@
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
# Link Kernel
|
|
||||||
$(KERNEL_ELF): $(OBJ_FILES)
|
$(KERNEL_ELF): $(OBJ_FILES)
|
||||||
$(LD) $(LDFLAGS) -o $@ $(OBJ_FILES)
|
$(LD) $(LDFLAGS) -o $@ $(OBJ_FILES)
|
||||||
|
$(MAKE) -C $(SRC_DIR)/userland
|
||||||
|
|
||||||
# Create ISO
|
$(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
|
||||||
$(ISO_IMAGE): $(KERNEL_ELF) limine.cfg limine-setup
|
rm -rf $(BUILD_DIR)/initrd
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/bin
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/Library/images/Wallpapers
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/Library/images/gif
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/Library/Fonts/Emoji
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/Library/DOOM
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/docs
|
||||||
|
|
||||||
|
@for f in $(SRC_DIR)/userland/bin/*.elf; do \
|
||||||
|
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/bin/; fi \
|
||||||
|
done
|
||||||
|
@for f in $(SRC_DIR)/images/wallpapers/*; do \
|
||||||
|
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/images/Wallpapers/; fi \
|
||||||
|
done
|
||||||
|
@for f in $(SRC_DIR)/images/gif/*.gif; do \
|
||||||
|
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/images/gif/; fi \
|
||||||
|
done
|
||||||
|
@for f in $(SRC_DIR)/fonts/*.ttf; do \
|
||||||
|
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/Fonts/; fi \
|
||||||
|
done
|
||||||
|
@for f in $(SRC_DIR)/fonts/Emoji/*.ttf; do \
|
||||||
|
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/Fonts/Emoji/; fi \
|
||||||
|
done
|
||||||
|
@if [ -f $(SRC_DIR)/userland/games/doom/doom1.wad ]; then cp $(SRC_DIR)/userland/games/doom/doom1.wad $(BUILD_DIR)/initrd/Library/DOOM/; fi
|
||||||
|
@for f in $$(find docs -name '*.md' 2>/dev/null); do \
|
||||||
|
if [ -f "$$f" ]; then \
|
||||||
|
dir=$$(dirname "$$f"); \
|
||||||
|
mkdir -p $(BUILD_DIR)/initrd/"$$dir"; \
|
||||||
|
cp "$$f" $(BUILD_DIR)/initrd/"$$dir"/; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
@if [ -f README.md ]; then cp README.md $(BUILD_DIR)/initrd/; fi
|
||||||
|
@if [ -f LICENSE ]; then cp LICENSE $(BUILD_DIR)/initrd/; fi
|
||||||
|
|
||||||
|
cd $(BUILD_DIR)/initrd && COPYFILE_DISABLE=1 tar --exclude="._*" -cf ../initrd.tar *
|
||||||
|
|
||||||
|
$(ISO_IMAGE): $(KERNEL_ELF) $(BUILD_DIR)/initrd.tar limine.conf limine-setup
|
||||||
rm -rf $(ISO_DIR)
|
rm -rf $(ISO_DIR)
|
||||||
mkdir -p $(ISO_DIR)
|
mkdir -p $(ISO_DIR)
|
||||||
mkdir -p $(ISO_DIR)/EFI/BOOT
|
mkdir -p $(ISO_DIR)/EFI/BOOT
|
||||||
|
|
||||||
# Copy Kernel and Config
|
|
||||||
cp $(KERNEL_ELF) $(ISO_DIR)/
|
cp $(KERNEL_ELF) $(ISO_DIR)/
|
||||||
cp limine.cfg $(ISO_DIR)/
|
cp limine.conf $(ISO_DIR)/
|
||||||
|
|
||||||
# Copy README
|
cp $(BUILD_DIR)/initrd.tar $(ISO_DIR)/
|
||||||
cp README.md $(ISO_DIR)/
|
echo " module_path: boot():/initrd.tar" >> $(ISO_DIR)/limine.conf
|
||||||
|
|
||||||
# Copy user file.c if it exists
|
@if [ -f splash.jpg ]; then cp splash.jpg $(ISO_DIR)/; fi
|
||||||
@if [ -f file.c ]; then cp file.c $(ISO_DIR)/; fi
|
|
||||||
|
|
||||||
# Copy Wallpaper (if it exists)
|
|
||||||
@if [ -f src/kernel/wallpaper.ppm ]; then cp src/kernel/wallpaper.ppm $(ISO_DIR)/; fi
|
|
||||||
|
|
||||||
# Copy Limine Bootloader Files (flat structure in binary branch)
|
|
||||||
cp limine/limine-bios.sys $(ISO_DIR)/
|
cp limine/limine-bios.sys $(ISO_DIR)/
|
||||||
cp limine/limine-bios-cd.bin $(ISO_DIR)/
|
cp limine/limine-bios-cd.bin $(ISO_DIR)/
|
||||||
cp limine/limine-uefi-cd.bin $(ISO_DIR)/
|
cp limine/limine-uefi-cd.bin $(ISO_DIR)/
|
||||||
|
|
||||||
# Create EFI Boot Files
|
|
||||||
cp limine/BOOTX64.EFI $(ISO_DIR)/EFI/BOOT/
|
cp limine/BOOTX64.EFI $(ISO_DIR)/EFI/BOOT/
|
||||||
cp limine/BOOTIA32.EFI $(ISO_DIR)/EFI/BOOT/
|
cp limine/BOOTIA32.EFI $(ISO_DIR)/EFI/BOOT/
|
||||||
|
|
||||||
# Generate ISO
|
$(XORRISO) -as mkisofs -R -J -b limine-bios-cd.bin \
|
||||||
$(XORRISO) -as mkisofs -b limine-bios-cd.bin \
|
|
||||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||||
--efi-boot limine-uefi-cd.bin \
|
--efi-boot limine-uefi-cd.bin \
|
||||||
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
||||||
$(ISO_DIR) -o $(ISO_IMAGE)
|
$(ISO_DIR) -o $(ISO_IMAGE)
|
||||||
|
|
||||||
# Install Limine to ISO (for BIOS boot)
|
|
||||||
./limine/limine bios-install $(ISO_IMAGE)
|
./limine/limine bios-install $(ISO_IMAGE)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR) $(ISO_DIR) $(ISO_IMAGE)
|
rm -rf $(BUILD_DIR) $(ISO_DIR) $(ISO_IMAGE)
|
||||||
|
$(MAKE) -C $(SRC_DIR)/userland clean
|
||||||
|
|
||||||
run: $(ISO_IMAGE)
|
run: $(ISO_IMAGE)
|
||||||
qemu-system-x86_64 -m 2G -serial stdio -cdrom $(ISO_IMAGE) -boot d \
|
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||||
|
-smp 4 \
|
||||||
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \
|
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||||
-netdev user,id=net0,hostfwd=udp::12345-:12345 -device e1000,netdev=net0 \
|
-netdev user,id=net0,hostfwd=udp::12346-:12345 -device virtio-net-pci,netdev=net0 \
|
||||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080
|
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
||||||
|
-display cocoa,show-cursor=off \
|
||||||
|
-drive file=disk.img,format=raw,file.locking=off \
|
||||||
|
-cpu max
|
||||||
22
NOTICE
Normal file
22
NOTICE
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
NOTICE
|
||||||
|
------
|
||||||
|
|
||||||
|
This product includes software developed by Chris ("boreddevnl") as part of the BoredOS (Previously Brewkernel/BrewOS) project.
|
||||||
|
|
||||||
|
Copyright (C) 2024–2026 Chris / boreddevnl (previously boreddevhq)
|
||||||
|
|
||||||
|
All source files in this repository contain copyright and license
|
||||||
|
headers that must be preserved in redistributions and derivative works.
|
||||||
|
|
||||||
|
If you distribute or modify this project (in whole or in part),
|
||||||
|
you MUST:
|
||||||
|
|
||||||
|
- Retain all copyright and license headers at the top of each file.
|
||||||
|
- Include this NOTICE file along with any redistributions or
|
||||||
|
derivative works.
|
||||||
|
- Provide clear attribution to the original author in documentation
|
||||||
|
or credits where appropriate.
|
||||||
|
|
||||||
|
The above attribution requirements are informational and intended to
|
||||||
|
ensure proper credit is given. They do not alter or supersede the
|
||||||
|
terms of the GNU General Public License (GPL), which governs this work.
|
||||||
183
README.md
183
README.md
@@ -1,156 +1,87 @@
|
|||||||
# Brew OS 1.45 Beta
|
# BoredOS
|
||||||
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
|
|
||||||
|
|
||||||
## Brewkernel is now BrewOS!
|
<div align="center">
|
||||||
Brewkernel will from now on be deprecated as it's core became too messy. I have built a less bloated kernel and wrote a DE above it, which is why it is now an OS instead of a kernel (in my opinion).
|
<img src="boredos.svg" alt="BoredOS Logo" width="450" />
|
||||||
|
<p><em>A modern x86_64 hobbyist operating system built from the ground up.</em></p>
|
||||||
|
|
||||||
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||||
|

|
||||||
|

|
||||||
|
</div>
|
||||||
|
|
||||||
<img src="asciiart.png" width="200" /> </br>
|
---
|
||||||
Brew Kernel is a simple x86_64 hobbyist operating system.
|
|
||||||
It features a DE (and WM), a FAT32 filesystem, customizable UI and much much more!
|
|
||||||
|
|
||||||
## Features
|
BoredOS is a x86_64 operating system featuring a custom Desktop Environment (DE), a dedicated Window Manager (BoredWM), and a FAT32 filesystem. It balances low-level kernel exploration with a surprisingly capable userspace.
|
||||||
- Drag and drop mouse centered UI
|
|
||||||
- Customizable UI
|
|
||||||
- Basic Networking Stack
|
|
||||||
- Brew WM
|
|
||||||
- Fat 32 FS
|
|
||||||
- 64-bit long mode support
|
|
||||||
- Multiboot2 compliant
|
|
||||||
- Text editor
|
|
||||||
- Markdown Viewer
|
|
||||||
- Minesweeper
|
|
||||||
- IDT
|
|
||||||
- Ability to run on actual x86_64 hardware
|
|
||||||
- CLI
|
|
||||||
|
|
||||||
## Prerequisites
|

|
||||||
|
> [!NOTE]
|
||||||
|
> *The screenshot above may represent a previous build and is subject to change as the UI evolves.*
|
||||||
|
|
||||||
To build BrewOS, you'll need the following tools installed:
|
---
|
||||||
|
|
||||||
- **x86_64 ELF Toolchain**: `x86_64-elf-gcc`, `x86_64-elf-ld`
|
## 🚀 Features
|
||||||
- **NASM**: Netwide Assembler for compiling assembly code
|
|
||||||
- **xorriso**: For creating bootable ISO images
|
|
||||||
- **QEMU** (optional): For testing the kernel in an emulator
|
|
||||||
|
|
||||||
On macOS, you can install these using Homebrew:
|
### ⚙️ System Architecture
|
||||||
```sh
|
* **64-bit Long Mode:** Fully utilizing the x86_64 architecture.
|
||||||
brew install x86_64-elf-binutils x86_64-elf-gcc nasm xorriso qemu
|
* **Symmetric Multi-Processing (SMP):** Full support for multi-core CPUs via Limine SMP.
|
||||||
```
|
* **LAPIC & IPI Scheduling:** Advanced interrupt handling and inter-processor communication for task distribution.
|
||||||
|
* **SMP-Safe Spinlocks:** Robust kernel-wide synchronization for VFS, process management, and the GUI.
|
||||||
|
* **Multiboot2 Compliant:** Bootable on real hardware and modern emulators.
|
||||||
|
* **Kernel Core:** Interrupt Descriptor Table (IDT) management and a robust syscall interface.
|
||||||
|
* **Filesystem:** Full **FAT32** support for persistent and in-memory storage.
|
||||||
|
* **Networking:** Includes the lwIP networking stack.
|
||||||
|
|
||||||
## Building
|
### 📺 Graphical User Interface
|
||||||
|
* **BoredWM:** A custom Window Manager with drag-and-drop, mouse-centered interaction.
|
||||||
|
* **Customization:** Adjustable UI to suit your aesthetic.
|
||||||
|
* **Media Support:** Built-in image decoding.
|
||||||
|
|
||||||
Simply run `make` from the project root:
|
### 🛠️ Included Applications
|
||||||
|
* **Productivity:** GUI Text Editor calculator, Markdown Viewer, a simple browser and BoredWord.
|
||||||
|
* **Creativity:** A Paint application.
|
||||||
|
* **Utilities:** Terminal, Task Manager, File Explorer, Clock and a (limited) C Compiler.
|
||||||
|
* **Games:** Minesweeper and DOOM.
|
||||||
|
|
||||||
```sh
|
---
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
This will:
|
## 📚 Documentation
|
||||||
1. Compile all kernel C sources and assembly files
|
|
||||||
2. Link the kernel ELF binary
|
|
||||||
3. Generate a bootable ISO image (`brewos.iso`)
|
|
||||||
|
|
||||||
The build output is organized as follows:
|
Explore the internal workings of BoredOS via our comprehensive guides in the [`docs/`](docs/) directory.
|
||||||
- Compiled object files: `build/`
|
|
||||||
- ISO root filesystem: `iso_root/`
|
|
||||||
- Final ISO image: `brewos.iso`
|
|
||||||
|
|
||||||
## Running
|
* 📖 **[Documentation Index](docs/README.md)** – Start here.
|
||||||
|
* 🏗️ **[Architecture Overview](docs/architecture/core.md)** – Deep dive into the kernel.
|
||||||
|
* 🔨 **[Building and Running](docs/build/usage.md)** – Setup your build environment.
|
||||||
|
* 🚀 **[AppDev SDK](docs/appdev/custom_apps.md)** – Build your own apps for BoredOS.
|
||||||
|
|
||||||
### QEMU Emulation
|
---
|
||||||
|
|
||||||
Run the kernel in QEMU:
|
## ☕ Support the Journey
|
||||||
|
|
||||||
```sh
|
If you find this project interesting or helpful, consider fueling the development with a coffee!
|
||||||
make run
|
|
||||||
```
|
|
||||||
|
|
||||||
Or manually:
|
<a href="https://buymeacoffee.com/boreddevnl" target="_blank">
|
||||||
```sh
|
|
||||||
qemu-system-x86_64 -m 2G -serial stdio -cdrom brewos.iso -boot d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running on Real Hardware
|
|
||||||
|
|
||||||
*Warning: This is at YOUR OWN RISK. This software comes with ZERO warranty and may break your system.*
|
|
||||||
|
|
||||||
1. **Create bootable USB**: Use [Balena Etcher](https://www.balena.io/etcher/) to flash `brewos.iso` to a USB drive
|
|
||||||
|
|
||||||
2. **Prepare the system**:
|
|
||||||
- Enable legacy (BIOS) boot in your system BIOS/UEFI settings
|
|
||||||
- Disable Secure Boot if needed
|
|
||||||
|
|
||||||
3. **Boot**: Insert the USB drive and select it in the boot menu during startup
|
|
||||||
|
|
||||||
**Networking requires an Intel E1000 network card or similar while using Ethernet.**
|
|
||||||
|
|
||||||
4. **Tested Hardware**:
|
|
||||||
- HP EliteDesk 705 G4 DM (AMD Ryzen 5 PRO 2400G, Radeon Vega) **Tested, no networking.**
|
|
||||||
- Lenovo ThinkPad A475 20KL002VMH (AMD Pro A12-8830B, Radeon R7) **Tested, no networking.**
|
|
||||||
- Acer Aspire E5-573-311M (Intel Core i3-5005U, Intel HD Graphics) **Tested, no networking.**
|
|
||||||
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
- `src/kernel/` - Main kernel implementation
|
|
||||||
- `boot.asm` - Boot assembly code
|
|
||||||
- `main.c` - Kernel entry point
|
|
||||||
- `*.c / *.h` - Core kernel modules (graphics, interrupts, filesystem, etc.)
|
|
||||||
- `cli_apps/` - Command-line applications
|
|
||||||
- `build/` - Compiled object files (generated during build)
|
|
||||||
- `iso_root/` - ISO filesystem layout (generated during build)
|
|
||||||
- `limine/` - Limine bootloader files (downloaded automatically)
|
|
||||||
- `linker.ld` - Linker script for x86_64 ELF
|
|
||||||
- `limine.cfg` - Limine bootloader configuration
|
|
||||||
- `Makefile` - Build configuration and targets
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
###
|
|
||||||
|
|
||||||
<h2 align="left">Help me brew some coffee! ☕️</h2>
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
<p align="left">
|
|
||||||
If you enjoy this project, and like what i'm doing here, consider buying me a coffee!
|
|
||||||
<br><br>
|
|
||||||
<a href="https://buymeacoffee.com/boreddevnl" target="_blank">
|
|
||||||
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50" style="border-radius: 8px;" />
|
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50" style="border-radius: 8px;" />
|
||||||
</a>
|
</a>
|
||||||
</p>
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
---
|
||||||
|
|
||||||
Copyright (C) 2024-2026 boreddevnl
|
## ⚠️ Project Disclaimer & Heritage
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
**BoredOS** is the successor to **BrewKernel**, a text-only project initiated in 2023.
|
||||||
|
|
||||||
NOTICE
|
While BrewKernel served as the foundational learning ground for this OS, it has been officially **deprecated and archived**. It no longer receives updates, bug fixes, or pull request reviews. BoredOS represents a complete architectural reboot, applying years of lessons learned to create a cleaner, more modular, and more capable 64-bit system.
|
||||||
------
|
|
||||||
|
|
||||||
This product includes software developed by Chris ("boreddevnl") as part of the BrewKernel project.
|
> [!IMPORTANT]
|
||||||
|
> Please ensure all issues, discussions, and contributions are directed to this repository. Legacy BrewKernel code is preserved for historical purposes only and is not compatible with BoredOS.
|
||||||
|
|
||||||
Copyright (C) 2024–2026 Chris / boreddevnl (previously boreddevhq)
|
---
|
||||||
|
|
||||||
All source files in this repository contain copyright and license
|
## ⚖️ License
|
||||||
headers that must be preserved in redistributions and derivative works.
|
|
||||||
|
|
||||||
If you distribute or modify this project (in whole or in part),
|
**Copyright (C) 2024-2026 boreddevnl**
|
||||||
you MUST:
|
|
||||||
|
|
||||||
- Retain all copyright and license headers at the top of each file.
|
Distributed under the **GNU General Public License v3**. See the `LICENSE` file for details.
|
||||||
- Include this NOTICE file along with any redistributions or
|
|
||||||
derivative works.
|
|
||||||
- Provide clear attribution to the original author in documentation
|
|
||||||
or credits where appropriate.
|
|
||||||
|
|
||||||
The above attribution requirements are informational and intended to
|
> [!IMPORTANT]
|
||||||
ensure proper credit is given. They do not alter or supersede the
|
> This product includes software developed by Chris ("boreddevnl"). You must retain all copyright headers and include the original attribution in any redistributions or derivative works. See the `NOTICE` file for more details.
|
||||||
terms of the GNU General Public License (GPL), which governs this work.
|
|
||||||
BIN
asciiart.png
BIN
asciiart.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB |
21
boredos.svg
Normal file
21
boredos.svg
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 415 130" width="100%">
|
||||||
|
<style>
|
||||||
|
text {
|
||||||
|
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||||
|
font-size: 16px;
|
||||||
|
white-space: pre;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.magenta { fill: #B589D6; }
|
||||||
|
.blue { fill: #569CD6; }
|
||||||
|
.cyan { fill: #4EC9B0; }
|
||||||
|
.text-color { fill: #FFFFFF; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<text x="0" y="20" xml:space="preserve"><tspan class="magenta">====================== </tspan><tspan class="text-color">__ ____ ____ </tspan></text>
|
||||||
|
<text x="0" y="40" xml:space="preserve"><tspan class="magenta">===================== </tspan><tspan class="text-color">/ /_ / __ \/ ___\</tspan></text>
|
||||||
|
<text x="0" y="60" xml:space="preserve"><tspan class="blue">==================== </tspan><tspan class="text-color">/ __ \/ / / /\___ \</tspan></text>
|
||||||
|
<text x="0" y="80" xml:space="preserve"><tspan class="blue">=================== </tspan><tspan class="text-color">/ /_/ / /_/ /____/ /</tspan></text>
|
||||||
|
<text x="0" y="100" xml:space="preserve"><tspan class="cyan">================== </tspan><tspan class="text-color">/_.___/\____//_____/ </tspan></text>
|
||||||
|
<text x="0" y="120" xml:space="preserve"><tspan class="cyan">================= </tspan></text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
build/about.o
BIN
build/about.o
Binary file not shown.
BIN
build/boot.o
BIN
build/boot.o
Binary file not shown.
BIN
build/brewos.elf
BIN
build/brewos.elf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/cmd.o
BIN
build/cmd.o
Binary file not shown.
Binary file not shown.
BIN
build/dns.o
BIN
build/dns.o
Binary file not shown.
BIN
build/e1000.o
BIN
build/e1000.o
Binary file not shown.
BIN
build/editor.o
BIN
build/editor.o
Binary file not shown.
BIN
build/explorer.o
BIN
build/explorer.o
Binary file not shown.
BIN
build/fat32.o
BIN
build/fat32.o
Binary file not shown.
BIN
build/graphics.o
BIN
build/graphics.o
Binary file not shown.
BIN
build/http.o
BIN
build/http.o
Binary file not shown.
BIN
build/icmp.o
BIN
build/icmp.o
Binary file not shown.
BIN
build/idt.o
BIN
build/idt.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
BIN
build/markdown.o
BIN
build/markdown.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/network.o
BIN
build/network.o
Binary file not shown.
BIN
build/notepad.o
BIN
build/notepad.o
Binary file not shown.
BIN
build/paint.o
BIN
build/paint.o
Binary file not shown.
BIN
build/pci.o
BIN
build/pci.o
Binary file not shown.
BIN
build/platform.o
BIN
build/platform.o
Binary file not shown.
BIN
build/ps2.o
BIN
build/ps2.o
Binary file not shown.
BIN
build/rtc.o
BIN
build/rtc.o
Binary file not shown.
BIN
build/tcp.o
BIN
build/tcp.o
Binary file not shown.
BIN
build/vm.o
BIN
build/vm.o
Binary file not shown.
BIN
build/wm.o
BIN
build/wm.o
Binary file not shown.
Binary file not shown.
33
docs/README.md
Normal file
33
docs/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>BoredOS Documentation</h1>
|
||||||
|
<p><em>Internal guides, architecture, and application development.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Welcome to the internal documentation for BoredOS! This directory contains detailed guides on how the OS functions, how to build it, and how to develop applications for it.
|
||||||
|
|
||||||
|
## 📚 Table of Contents
|
||||||
|
|
||||||
|
The documentation is organized into three main categories:
|
||||||
|
|
||||||
|
### 1. 🏗️ [Architecture](architecture/)
|
||||||
|
Explains the logical layout of the kernel and internal components.
|
||||||
|
- [`Core`](architecture/core.md): Kernel source layout and the boot process (Limine, Multiboot2).
|
||||||
|
- [`Memory`](architecture/memory.md): Physical Memory Management (PMM) and Virtual Memory Management (VMM).
|
||||||
|
- [`Filesystem`](architecture/filesystem.md): Virtual File System (VFS) and the RAM-based FAT32 simulation.
|
||||||
|
- [`Window Manager`](architecture/window_manager.md): How the built-in Window Manager natively handles graphics, events, and compositing.
|
||||||
|
|
||||||
|
### 2. 🔨 [Building and Deployment](build/)
|
||||||
|
Instructions for compiling the OS from source.
|
||||||
|
- [`Toolchain`](build/toolchain.md): Prerequisites and cross-compiler setup (`x86_64-elf-gcc`, `nasm`, `xorriso`).
|
||||||
|
- [`Usage`](build/usage.md): Understanding the Makefile targets, QEMU emulation, and flashing to bare metal hardware.
|
||||||
|
|
||||||
|
### 3. 🚀 [Application Development](appdev/)
|
||||||
|
The SDK and toolchain guides for creating your own `.elf` userland binaries.
|
||||||
|
- [`SDK Reference`](appdev/sdk_reference.md): Explanation of the custom `libc` wrappers (`stdlib.h`, `string.h`) and system calls.
|
||||||
|
- [`UI API`](appdev/ui_api.md): Drawing on the screen, creating windows, and polling the event loop using `libui.h`.
|
||||||
|
- [`Custom Apps`](appdev/custom_apps.md): A step-by-step tutorial on writing a new graphical C application, editing the Makefile, and bundling it into the ISO.
|
||||||
|
- [`Example Apps`](appdev/examples/README.md): A collection of sample C applications ranging from basic terminal output to advanced TCP networking.
|
||||||
|
|
||||||
|
---
|
||||||
90
docs/appdev/custom_apps.md
Normal file
90
docs/appdev/custom_apps.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Creating a Custom App</h1>
|
||||||
|
<p><em>A step-by-step tutorial on writing a new graphical C application.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This guide explains how to write a new "Hello World" application locally, compile it as an `.elf` binary into the `bin/` folder, and launch it inside BoredOS.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> **Looking for working code?** Check out the [Examples Directory](examples/README.md) for full source code demonstrating basic CLI, Windows, Animations, and TCP Networking.
|
||||||
|
|
||||||
|
## 📝 Step 1: Write the C Source
|
||||||
|
|
||||||
|
Applications reside entirely in the `src/userland/` directory. Create a new file, for example, `src/userland/gui/hello.c`.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Group CLI apps into `src/userland/cli/` and windowed apps into `src/userland/gui/` for organization.
|
||||||
|
|
||||||
|
```c
|
||||||
|
// src/userland/gui/hello.c
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <libui.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// Attempt to open a 300x200 window
|
||||||
|
ui_window_t wid = ui_window_create("My Custom App", 100, 100, 300, 200);
|
||||||
|
if (wid < 0) {
|
||||||
|
printf("Error creating window!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write text in center
|
||||||
|
ui_draw_string(wid, 50, 90, "Hello, BoredOS!!", 0xFFFFFFFF);
|
||||||
|
|
||||||
|
// Commit drawing to screen
|
||||||
|
ui_mark_dirty(wid, 0, 0, 300, 200);
|
||||||
|
|
||||||
|
gui_event_t event;
|
||||||
|
while (1) {
|
||||||
|
if (ui_get_event(wid, &event)) {
|
||||||
|
if (event.type == GUI_EVENT_CLOSE) {
|
||||||
|
break; // Exit loop if 'X' is clicked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Returning 0 smoothly exits the process via crt0.asm
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚙️ Step 2: Edit the Makefile
|
||||||
|
|
||||||
|
Now you need to tell the build system to compile `hello.c`. Fortunately, the `src/userland/Makefile` is designed to detect new C files largely automatically!
|
||||||
|
|
||||||
|
1. Open `src/userland/Makefile`.
|
||||||
|
2. Find the line specifying `APP_SOURCES_FULL`:
|
||||||
|
```make
|
||||||
|
APP_SOURCES_FULL = $(wildcard cli/*.c gui/*.c sys/*.c games/*.c *.c)
|
||||||
|
```
|
||||||
|
Since you placed the file in `gui/hello.c`, the wildcard logic will pick it up automatically.
|
||||||
|
3. The Makefile will generate `bin/hello.elf` during the build phase.
|
||||||
|
|
||||||
|
## 📦 Step 3: Bundle it into the OS
|
||||||
|
|
||||||
|
The main overarching `Makefile` (in the project root) takes binaries from `src/userland/bin/*.elf` and places them into the `iso_root/bin/` directory, while also adding them to `limine.conf` as loadable boot modules.
|
||||||
|
|
||||||
|
1. Go back to the root of the OS:
|
||||||
|
```sh
|
||||||
|
cd ../..
|
||||||
|
```
|
||||||
|
2. Compile the entire project to build the ISO and test in QEMU:
|
||||||
|
```sh
|
||||||
|
make clean && make run
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Step 4: Run it inside BoredOS
|
||||||
|
|
||||||
|
1. When BoredOS boots, launch the **Terminal** application.
|
||||||
|
2. The OS automatically maps built applications to standard shell commands. Simply type your application's filename (without the `.elf` extension).
|
||||||
|
3. Type `hello` in the terminal and press Enter.
|
||||||
|
4. Your custom window will appear!
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> You can also open your app by opening the file explorer, navigating to the `bin` directory, and double-clicking the executable.
|
||||||
|
|
||||||
|
---
|
||||||
52
docs/appdev/examples/01_hello_cli.md
Normal file
52
docs/appdev/examples/01_hello_cli.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Example 01: Hello CLI</h1>
|
||||||
|
<p><em>The absolute basics. Writing a terminal program.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This example demonstrates the bare minimum structure of a BoredOS application that outputs text to the standard output (usually the Terminal executing the binary).
|
||||||
|
|
||||||
|
## 📝 Concepts Introduced
|
||||||
|
* Including `stdlib.h` for basic IO.
|
||||||
|
* The `main()` entry point.
|
||||||
|
* Using `printf()` for formatted output.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 The Code (`src/userland/cli/hello_world.c`)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
// Standard library initialization is handled automatically by crt0.asm
|
||||||
|
|
||||||
|
// Print a simple string to the terminal
|
||||||
|
printf("Hello, World from BoredOS Userland!\n");
|
||||||
|
|
||||||
|
// Print some formatted data
|
||||||
|
int favorite_number = 67;
|
||||||
|
printf("Did you know my favorite number is %d?\n", favorite_number);
|
||||||
|
|
||||||
|
// Returning from main automatically terminates the process cleanly
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ How it Works
|
||||||
|
|
||||||
|
1. **`#include <stdlib.h>`**: We include the SDK's standard library header which gives us access to `printf`.
|
||||||
|
2. **`int main(...)`**: Every process begins execution here (managed transparently by `crt0.asm`).
|
||||||
|
3. **`printf(...)`**: The SDK routes this call internally directly to the `SYS_WRITE` system call, making it available on the terminal.
|
||||||
|
4. **`return 0`**: A successful exit code.
|
||||||
|
|
||||||
|
## 🚀 Running It
|
||||||
|
|
||||||
|
If you build the project, you can open the Terminal and type:
|
||||||
|
```sh
|
||||||
|
/ # hello_world
|
||||||
|
Hello, World from BoredOS Userland!
|
||||||
|
Did you know my favorite number is 67?
|
||||||
|
/ #
|
||||||
|
```
|
||||||
71
docs/appdev/examples/02_basic_window.md
Normal file
71
docs/appdev/examples/02_basic_window.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Example 02: Basic Window</h1>
|
||||||
|
<p><em>An introduction to libui and creating graphical apps.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This example demonstrates how to create an empty window that stays active on the screen until the user explicitly closes it by clicking the 'X' button.
|
||||||
|
|
||||||
|
## 📝 Concepts Introduced
|
||||||
|
* Including `libui.h` and the event structure.
|
||||||
|
* Creating a `ui_window_t` handle.
|
||||||
|
* Creating an infinite event loop using `ui_get_event()`.
|
||||||
|
* Yielding CPU time to the kernel via `sys_yield()`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 The Code (`src/userland/gui/basic_window.c`)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <libui.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// 1. Ask the Window Manager to create a new window
|
||||||
|
// Arguments are: Title, X Position, Y Position, Width, Height
|
||||||
|
ui_window_t wid = ui_window_create("My First GUI", 100, 100, 400, 300);
|
||||||
|
|
||||||
|
if (wid < 0) {
|
||||||
|
printf("Failed to create the window!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Define our event object
|
||||||
|
gui_event_t event;
|
||||||
|
|
||||||
|
// 3. Enter the main event loop
|
||||||
|
while (1) {
|
||||||
|
// ui_get_event is non-blocking. It returns true if an event was waiting.
|
||||||
|
if (ui_get_event(wid, &event)) {
|
||||||
|
|
||||||
|
// Check what type of event occurred
|
||||||
|
if (event.type == GUI_EVENT_CLOSE) {
|
||||||
|
// The user clicked the 'X' button in the titlebar!
|
||||||
|
printf("Window closed cleanly by user.\n");
|
||||||
|
break; // Break the infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. CRITICAL: Yield the remainder of our timeslice
|
||||||
|
// If we don't do this, the while(1) loop will consume 100% of the CPU
|
||||||
|
// and starve the rest of the OS!
|
||||||
|
sys_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returning from main will automatically destroy the window and exit the process.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ How it Works
|
||||||
|
|
||||||
|
1. **Window Handle (`wid`)**: `ui_window_create` sends a request to the kernel. The kernel allocates the memory for the window and returns a numerical ID (the handle) that we use for all future interactions with that specific window.
|
||||||
|
2. **The Event Loop**: Graphical programs run forever until closed. The `while (1)` loop serves this purpose.
|
||||||
|
3. **Polling**: `ui_get_event` asks the kernel, "Hey, did the user click my window or press a key since the last time I asked?". It is non-blocking, so it immediately returns `false` if nothing happened.
|
||||||
|
4. **CPU Yielding**: Since we are constantly polling in a tight loop, we call `sys_yield()` at the end of the loop frame. This politely tells the OS scheduler, "I'm done checking for events, go ahead and let another program run for a bit."
|
||||||
|
|
||||||
|
## 🚀 Running It
|
||||||
|
|
||||||
|
Launch the Terminal and type `basic_window`. You'll see an empty window appear that you can move around the screen!
|
||||||
92
docs/appdev/examples/03_bouncing_ball.md
Normal file
92
docs/appdev/examples/03_bouncing_ball.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Example 03: Bouncing Ball</h1>
|
||||||
|
<p><em>Animating graphics and managing application state.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This example builds upon the `02_basic_window` guide. It demonstrates how to constantly update the screen to simulate a bouncing square moving freely inside the window bounds.
|
||||||
|
|
||||||
|
## 📝 Concepts Introduced
|
||||||
|
* Maintaining application state across frames (Velocity/Position).
|
||||||
|
* Drawing primitives (`ui_fill_rect`, `ui_draw_string`).
|
||||||
|
* The importance of clearing the screen on a new frame.
|
||||||
|
* Explicitly forcing standard visual updates via `ui_mark_dirty()`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 The Code (`src/userland/gui/bounce.c`)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <libui.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
// Window Dimensions
|
||||||
|
#define W_WIDTH 400
|
||||||
|
#define W_HEIGHT 300
|
||||||
|
// Square Dimensions
|
||||||
|
#define SQ_SIZE 30
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
ui_window_t wid = ui_window_create("Bouncing Box Animation", 50, 50, W_WIDTH, W_HEIGHT);
|
||||||
|
if (wid < 0) return 1;
|
||||||
|
|
||||||
|
// Define object state variables
|
||||||
|
int pos_x = 50;
|
||||||
|
int pos_y = 50;
|
||||||
|
int vel_x = 2; // Move 2 pixels per frame horizontally
|
||||||
|
int vel_y = 2; // Move 2 pixels per frame vertically
|
||||||
|
|
||||||
|
gui_event_t event;
|
||||||
|
while (1) {
|
||||||
|
// 1. Process Events
|
||||||
|
while (ui_get_event(wid, &event)) {
|
||||||
|
if (event.type == GUI_EVENT_CLOSE) {
|
||||||
|
return 0; // Exit cleanly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Physics & Logic Update
|
||||||
|
pos_x += vel_x;
|
||||||
|
pos_y += vel_y;
|
||||||
|
|
||||||
|
// Collision logic (Bounce off edges)
|
||||||
|
// The window has a 20px title bar, so the usable client height is W_HEIGHT - 20.
|
||||||
|
if (pos_x <= 0 || pos_x + SQ_SIZE >= W_WIDTH) {
|
||||||
|
vel_x = -vel_x; // Reverse horizontal direction
|
||||||
|
}
|
||||||
|
if (pos_y <= 0 || pos_y + SQ_SIZE >= W_HEIGHT - 20) {
|
||||||
|
vel_y = -vel_y; // Reverse vertical direction
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Rendering Update
|
||||||
|
// Step A: Clear the entire background to Black (0xFF000000)
|
||||||
|
ui_draw_rect(wid, 0, 0, W_WIDTH, W_HEIGHT, 0xFF000000);
|
||||||
|
|
||||||
|
// Step B: Draw our shape in Red (0xFFFF0000) at the new position
|
||||||
|
ui_draw_rect(wid, pos_x, pos_y, SQ_SIZE, SQ_SIZE, 0xFFFF0000);
|
||||||
|
|
||||||
|
// Step C: Draw some UI text over the animation in White
|
||||||
|
ui_draw_string(wid, 10, 10, "BoredOS Animation Demo!", 0xFFFFFFFF);
|
||||||
|
|
||||||
|
// Step D: Instruct the compositor to flush our drawing buffer to the physical screen
|
||||||
|
ui_mark_dirty(wid, 0, 0, W_WIDTH, W_HEIGHT);
|
||||||
|
|
||||||
|
// 4. Yield and throttle
|
||||||
|
sys_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ How it Works
|
||||||
|
|
||||||
|
1. **State Management**: We store `pos_x`, `pos_y`, `vel_x`, and `vel_y`. These variables represent the "physics" of our system. Notice that they update *outside* the event-checking logic so that the animation runs even if the user isn't clicking the mouse.
|
||||||
|
2. **Screen Clearing**: We *must* fill the screen with black (`ui_draw_rect(wid, 0, 0, W_WIDTH, W_HEIGHT, ...)`). If we don't clear the screen, the red square will leave a permanent trailing smear everywhere it goes!
|
||||||
|
3. **The Double Buffer**: `ui_draw_rect` and `ui_draw_string` do not immediately appear on your monitor. They just color a hidden buffer within the kernel.
|
||||||
|
4. **`ui_mark_dirty`**: This is the crucial command that tells the kernel Window Manager, "I'm done drawing my frame. Can you quickly copy my hidden buffer over to the real screen now?"
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Because `sys_yield()`'s pause duration depends heavily on CPU load and how many other processes are running (or QEMU emulation speed), tying physics/movement strictly to loops can make the game run faster on faster computers. Advanced developers will want to calculate delta time (time elapsed since the last frame) for smooth motion.
|
||||||
92
docs/appdev/examples/04_tcp_client.md
Normal file
92
docs/appdev/examples/04_tcp_client.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Example 04: TCP HTTP Client</h1>
|
||||||
|
<p><em>Utilizing lwIP to establish an outbound TCP connection.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This advanced example demonstrates the steps required to use the raw network system calls to establish a connection with an external HTTP server and dump the response over the terminal.
|
||||||
|
|
||||||
|
## 📝 Concepts Introduced
|
||||||
|
* Verifying the network state (`sys_network_is_initialized`, `sys_network_has_ip`).
|
||||||
|
* Performing DNS lookups manually via `sys_dns_lookup`.
|
||||||
|
* Managing strict TCP flow logic (`sys_tcp_connect`, send, block for receive).
|
||||||
|
* Using the terminal `SYS_WRITE` output for debugging.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 The Code (`src/userland/cli/http_get.c`)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
if (!sys_network_is_initialized() || !sys_network_has_ip()) {
|
||||||
|
printf("Network is unreachable! Make sure you inited the network first!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Resolve host name to IP
|
||||||
|
const char *target_host = "boreddev.nl";
|
||||||
|
net_ipv4_address_t server_ip;
|
||||||
|
|
||||||
|
printf("Resolving %s...\n", target_host);
|
||||||
|
if (sys_dns_lookup(target_host, &server_ip) < 0) {
|
||||||
|
printf("DNS Lookup failed.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Resolved to: %d.%d.%d.%d\n", server_ip.bytes[0], server_ip.bytes[1],
|
||||||
|
server_ip.bytes[2], server_ip.bytes[3]);
|
||||||
|
|
||||||
|
// 2. Establish a TCP connection on port 80 (HTTP)
|
||||||
|
printf("Connecting...\n");
|
||||||
|
if (sys_tcp_connect(&server_ip, 80) < 0) {
|
||||||
|
printf("Connection failed.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Connected! Sending GET request...\n");
|
||||||
|
|
||||||
|
// 3. Format and send the raw HTTP Request
|
||||||
|
char request[256];
|
||||||
|
strcpy(request, "GET / HTTP/1.1\r\nHost: ");
|
||||||
|
strcat(request, target_host);
|
||||||
|
strcat(request, "\r\nConnection: close\r\n\r\n");
|
||||||
|
|
||||||
|
if (sys_tcp_send(request, strlen(request)) < 0) {
|
||||||
|
printf("Failed to send data.\n");
|
||||||
|
sys_tcp_close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Block and wait for response data
|
||||||
|
char recv_buf[512];
|
||||||
|
int bytes_received;
|
||||||
|
|
||||||
|
printf("\n--- RESPONSE ---\n");
|
||||||
|
while ((bytes_received = sys_tcp_recv(recv_buf, sizeof(recv_buf) - 1)) > 0) {
|
||||||
|
recv_buf[bytes_received] = '\0'; // Null-terminate the chunk
|
||||||
|
printf("%s", recv_buf); // Print the chunk to stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Cleanup
|
||||||
|
printf("\n--- END RESPONSE ---\n");
|
||||||
|
sys_tcp_close();
|
||||||
|
printf("Connection closed.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ How it Works
|
||||||
|
|
||||||
|
1. **Network Setup**: First, we must ensure the host machine or QEMU environment gave BoredOS a valid IP address via DHCP. The `sys_network_has_ip()` check prevents our app from hanging trying to route data to nowhere.
|
||||||
|
2. **DNS (`sys_dns_lookup`)**: Since we want to connect to a domain name, not a raw IP, we query the DNS server configured by the OS (which it received via DHCP).
|
||||||
|
3. **Connection (`sys_tcp_connect`)**: We block the application thread while the OS performs the 3-way TCP handshake over port 80.
|
||||||
|
4. **Payload (`sys_tcp_send`)**: We format a compliant HTTP/1.1 payload representing a simple GET request for the root directory `/`.
|
||||||
|
5. **Chunked Receiving (`sys_tcp_recv`)**: The server's response might be larger than our `recv_buf` (512 bytes). Therefore, we loop. `sys_tcp_recv` blocks execution until data arrives. If it returns `0`, the remote server cleanly closed the connection (which happens automatically because we specified `Connection: close` in our request payload!).
|
||||||
|
|
||||||
|
## 🚀 Running It
|
||||||
|
|
||||||
|
Make sure QEMU is running with networking enabled. Launch the terminal and type `http_get`. You will see the raw headers and HTML source of the target webpage scroll down the CLI interface!
|
||||||
28
docs/appdev/examples/README.md
Normal file
28
docs/appdev/examples/README.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Example Applications</h1>
|
||||||
|
<p><em>From basic output to complex Graphical and Network applications.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Welcome to the examples directory! These guides are designed to help you understand how to write C applications for the BoredOS userland, utilizing the custom `libc` SDK.
|
||||||
|
|
||||||
|
The examples are listed in order of increasing complexity. Click on a tutorial to view the complete source code and an explanation of the concepts it introduces.
|
||||||
|
|
||||||
|
## 🟢 Beginner
|
||||||
|
|
||||||
|
* **[`01_hello_cli.md`](01_hello_cli.md)**: The absolute basics. Learn how to write a simple Terminal program that outputs text and processes standard system calls.
|
||||||
|
* **[`02_basic_window.md`](02_basic_window.md)**: An introduction to `libui.h`. Learn how to create an empty window, set up a basic event loop, and handle the "Close" button cleanly.
|
||||||
|
|
||||||
|
## 🟡 Intermediate
|
||||||
|
|
||||||
|
* **[`03_bouncing_ball.md`](03_bouncing_ball.md)**: Dive deeper into graphical rendering. This example introduces the `ui_mark_dirty` command, framerate independence via `sys_yield()`, and state management to animate a shape moving around the screen and bouncing off the window edges.
|
||||||
|
|
||||||
|
## 🔴 Advanced
|
||||||
|
|
||||||
|
* **[`04_tcp_client.md`](04_tcp_client.md)**: Using the lwIP networking stack. This example demonstrates how to perform a DNS lookup, connect to an external server over TCP (like an HTTP server), send a raw request, and print the response to the terminal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> If you want to test these out, simply create a new `.c` file in `src/userland/cli/` (for terminal apps) or `src/userland/gui/` (for windowed apps), paste the example code, then run `make clean && make run` from the project root!
|
||||||
157
docs/appdev/sdk_reference.md
Normal file
157
docs/appdev/sdk_reference.md
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Userland SDK Reference</h1>
|
||||||
|
<p><em>Comprehensive manual for custom libc and system calls in BoredOS.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
BoredOS provides a custom `libc` implementation necessary for writing userland applications (`.elf` binaries). By avoiding a full-blown standard library like `glibc`, the OS ensures a minimal executable footprint tailored strictly to the existing kernel features.
|
||||||
|
|
||||||
|
All headers are located in `src/userland/libc/`.
|
||||||
|
|
||||||
|
## 📚 Standard Library (`stdlib.h` & `string.h`)
|
||||||
|
|
||||||
|
The standard library wrappers provide memory management, string manipulation, and basic IO formatting without needing direct syscalls.
|
||||||
|
|
||||||
|
### Memory Allocation
|
||||||
|
* `void* malloc(size_t size);` - Allocate a block of memory on the heap.
|
||||||
|
* `void free(void* ptr);` - Free a previously allocated memory block.
|
||||||
|
* `void* calloc(size_t nmemb, size_t size);` - Allocate and zero-out a block of memory for an array.
|
||||||
|
* `void* realloc(void* ptr, size_t size);` - Resize an existing memory block.
|
||||||
|
|
||||||
|
### Memory Manipulation (`string.h`)
|
||||||
|
* `void* memset(void *s, int c, size_t n);` - Fill a block of memory with a specific byte.
|
||||||
|
* `void* memcpy(void *dest, const void *src, size_t n);` - Copy memory from source to destination.
|
||||||
|
* `void* memmove(void *dest, const void *src, size_t n);` - Safely copy overlapping memory blocks.
|
||||||
|
* `int memcmp(const void *s1, const void *s2, size_t n);` - Compare two memory blocks.
|
||||||
|
|
||||||
|
### String Utilities
|
||||||
|
* `size_t strlen(const char *s);` - Get the length of a string.
|
||||||
|
* `int strcmp(const char *s1, const char *s2);` - Compare two strings lexicographically.
|
||||||
|
* `char* strcpy(char *dest, const char *src);` - Copy a string to a destination buffer.
|
||||||
|
* `char* strcat(char *dest, const char *src);` - Concatenate two strings.
|
||||||
|
|
||||||
|
### Conversion and Formatting
|
||||||
|
* `int atoi(const char *nptr);` - String to integer conversion.
|
||||||
|
* `void itoa(int n, char *buf);` - Integer to string conversion.
|
||||||
|
|
||||||
|
### Input / Output
|
||||||
|
* `void puts(const char *s);` - Print a string followed by a newline to the standard output.
|
||||||
|
* `void printf(const char *fmt, ...);` - Formatted print to standard output (supports `%d`, `%s`, `%x`, etc.).
|
||||||
|
|
||||||
|
### Process Control
|
||||||
|
* `void exit(int status);` - Terminate the current process.
|
||||||
|
* `void sleep(int ms);` - Pause execution for a specified number of milliseconds.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ System Calls (`syscall.h`)
|
||||||
|
|
||||||
|
For advanced operations, `syscall.h` provides direct wrappers into the kernel.
|
||||||
|
|
||||||
|
### Process & System Info
|
||||||
|
* `void sys_exit(int status);` - Raw exit syscall.
|
||||||
|
* `int sys_write(int fd, const char *buf, int len);` - Write to a file descriptor (usually fd 1 for stdout).
|
||||||
|
* `void* sys_sbrk(int incr);` - Expand or shrink the process data segment (used internally by `malloc`).
|
||||||
|
* `void sys_kill(int pid);` - Send a kill signal to a process.
|
||||||
|
* `void sys_yield(void);` - Yield the remainder of the process's timeslice to the scheduler.
|
||||||
|
* `int sys_system(int cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);` - Execute a privileged system command (e.g., reboot, shutdown, beep).
|
||||||
|
* `int sys_get_os_info(os_info_t *info);` - Populate an `os_info_t` struct with version and environment details.
|
||||||
|
* `uint64_t sys_get_shell_config(const char *key);` - Retrieve internal shell configuration values.
|
||||||
|
* `void sys_set_text_color(uint32_t color);` - Set the raw CLI text output color.
|
||||||
|
|
||||||
|
### File System API (VFS)
|
||||||
|
Interacting with files and directories using the Virtual File System.
|
||||||
|
* `int sys_open(const char *path, const char *mode);` - Open a file, returning a file descriptor.
|
||||||
|
* `int sys_read(int fd, void *buf, uint32_t len);` - Read from an open file.
|
||||||
|
* `int sys_write_fs(int fd, const void *buf, uint32_t len);` - Write to an open file.
|
||||||
|
* `void sys_close(int fd);` - Close an open file descriptor.
|
||||||
|
* `int sys_seek(int fd, int offset, int whence);` - Reposition the file offset.
|
||||||
|
* `uint32_t sys_tell(int fd);` - Get the current file offset.
|
||||||
|
* `uint32_t sys_size(int fd);` - Get the total file size.
|
||||||
|
* `int sys_delete(const char *path);` - Delete a file.
|
||||||
|
* `int sys_mkdir(const char *path);` - Create a new directory.
|
||||||
|
* `int sys_exists(const char *path);` - Check if a path exists on the filesystem.
|
||||||
|
* `int sys_getcwd(char *buf, int size);` - Get the current working directory string.
|
||||||
|
* `int sys_chdir(const char *path);` - Change the current working directory.
|
||||||
|
* `int sys_list(const char *path, FAT32_FileInfo *entries, int max_entries);` - List directory contents into an array of `FAT32_FileInfo` structs.
|
||||||
|
* `int sys_get_file_info(const char *path, FAT32_FileInfo *info);` - Retrieve metadata for a specific file.
|
||||||
|
|
||||||
|
### Networking Stack API
|
||||||
|
BoredOS includes lwIP for hardware TCP/UDP networking.
|
||||||
|
|
||||||
|
#### Configuration and Status
|
||||||
|
* `int sys_network_init(void);` - Initialize the network stack.
|
||||||
|
* `int sys_network_is_initialized(void);` - Check stack status.
|
||||||
|
* `int sys_network_dhcp_acquire(void);` - Request an IP configuration from a DHCP server.
|
||||||
|
* `int sys_network_has_ip(void);` - Check if the system has a valid IP address.
|
||||||
|
* `int sys_network_get_mac(net_mac_address_t *mac);` - Get the physical MAC address of the NIC.
|
||||||
|
* `int sys_network_get_nic_name(char *name_out);` - Get the name of the active network interface card.
|
||||||
|
* `int sys_network_get_ip(net_ipv4_address_t *ip);` - Get current local IPv4 address.
|
||||||
|
* `int sys_network_set_ip(const net_ipv4_address_t *ip);` - Manually assign a static IP.
|
||||||
|
* `int sys_network_get_gateway(net_ipv4_address_t *ip);` - Get the default gateway IP.
|
||||||
|
* `int sys_network_get_dns(net_ipv4_address_t *ip);` - Get the primary DNS server IP.
|
||||||
|
* `int sys_set_dns_server(const net_ipv4_address_t *ip);` - Set the primary DNS server.
|
||||||
|
* `int sys_get_dns_server(net_ipv4_address_t *ip);` - Retrieve configured DNS server.
|
||||||
|
* `int sys_network_get_stat(int stat_type);` - Get network statistics (packets in/out, drops, etc.).
|
||||||
|
* `void sys_network_force_unlock(void);` - Force release of network stack locks (use with caution).
|
||||||
|
|
||||||
|
#### Communication
|
||||||
|
* `int sys_icmp_ping(const net_ipv4_address_t *dest_ip);` - Send an ICMP echo request.
|
||||||
|
* `int sys_udp_send(const net_ipv4_address_t *dest_ip, uint16_t dest_port, uint16_t src_port, const void *data, size_t data_len);` - Send a raw UDP datagram.
|
||||||
|
* `int sys_dns_lookup(const char *name, net_ipv4_address_t *out_ip);` - Resolve a hostname to an IPv4 address.
|
||||||
|
* `int sys_tcp_connect(const net_ipv4_address_t *ip, uint16_t port);` - Establish a TCP connection to a remote host.
|
||||||
|
* `int sys_tcp_send(const void *data, size_t len);` - Send data over an active TCP socket.
|
||||||
|
* `int sys_tcp_recv(void *buf, size_t max_len);` - Receive data from a TCP socket (blocking).
|
||||||
|
* `int sys_tcp_recv_nb(void *buf, size_t max_len);` - Receive data from a TCP socket (non-blocking).
|
||||||
|
* `int sys_tcp_close(void);` - Close the active TCP socket.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📑 Core Data Structures
|
||||||
|
|
||||||
|
### `os_info_t`
|
||||||
|
Contains detailed build and version information about the OS.
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
char os_name[64];
|
||||||
|
char os_version[64];
|
||||||
|
char os_codename[64];
|
||||||
|
char kernel_name[64];
|
||||||
|
char kernel_version[64];
|
||||||
|
char build_date[64];
|
||||||
|
char build_time[64];
|
||||||
|
char build_arch[64];
|
||||||
|
} os_info_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
### `FAT32_FileInfo`
|
||||||
|
Represents a filesystem entry.
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
char name[256];
|
||||||
|
uint32_t size;
|
||||||
|
uint8_t is_directory;
|
||||||
|
uint32_t start_cluster;
|
||||||
|
uint16_t write_date;
|
||||||
|
uint16_t write_time;
|
||||||
|
} FAT32_FileInfo;
|
||||||
|
```
|
||||||
|
|
||||||
|
### `ProcessInfo`
|
||||||
|
Provides status information for an active process.
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
uint32_t pid;
|
||||||
|
char name[64];
|
||||||
|
uint64_t ticks;
|
||||||
|
size_t used_memory;
|
||||||
|
} ProcessInfo;
|
||||||
|
```
|
||||||
|
|
||||||
|
### IP / MAC Addresses
|
||||||
|
Wrappers for raw byte arrays.
|
||||||
|
```c
|
||||||
|
typedef struct { uint8_t bytes[6]; } net_mac_address_t;
|
||||||
|
typedef struct { uint8_t bytes[4]; } net_ipv4_address_t;
|
||||||
|
```
|
||||||
105
docs/appdev/ui_api.md
Normal file
105
docs/appdev/ui_api.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>UI API (<code>libui.h</code>)</h1>
|
||||||
|
<p><em>Comprehensive manual for interacting with the Window Manager.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The UI library (`libui.h`) is the sole mechanism for Graphical Userland Applications to draw to the screen and receive input events in BoredOS. It wraps `SYS_GUI` kernel calls.
|
||||||
|
|
||||||
|
## 🪟 Window Management
|
||||||
|
|
||||||
|
A "Window" is a reserved drawing canvas managed by the compositor.
|
||||||
|
|
||||||
|
* `ui_window_t ui_window_create(const char *title, int x, int y, int w, int h);`
|
||||||
|
Creates a new window at `(x, y)` with dimensions `w`x`h`. Returns a window handle.
|
||||||
|
**Flags** are currently embedded in the syscall; standard windows include decorations (titlebar, borders).
|
||||||
|
* `void ui_window_set_title(ui_window_t win, const char *title);`
|
||||||
|
Dynamically update the text displayed in the window's titlebar.
|
||||||
|
* `void ui_window_set_resizable(ui_window_t win, bool resizable);`
|
||||||
|
Enable or disable the user's ability to resize the window by dragging its edges.
|
||||||
|
* `void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h);`
|
||||||
|
Query the global screen resolution of the display.
|
||||||
|
|
||||||
|
## 🎨 Drawing Primitives
|
||||||
|
|
||||||
|
All drawing functions write to an off-screen buffer associated with the window. **You must call `ui_mark_dirty()` to instruct the compositor to push your changes to the physical screen.**
|
||||||
|
|
||||||
|
* `void ui_draw_rect(ui_window_t win, int x, int y, int w, int h, uint32_t color);`
|
||||||
|
Draw a solid filled rectangle.
|
||||||
|
* `void ui_draw_rounded_rect_filled(ui_window_t win, int x, int y, int w, int h, int radius, uint32_t color);`
|
||||||
|
Fill a rectangle with rounded corners of a specified `radius`.
|
||||||
|
* `void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data);`
|
||||||
|
Blit a raw ARGB pixel buffer (`image_data`) directly into the window canvas.
|
||||||
|
* `void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h);`
|
||||||
|
Mark a specific rectangular region of the window as "dirty". The Window Manager will redraw this area on the next compositing pass.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Colors are defined as 32-bit unsigned integers in **ARGB** format: `0xAARRGGBB`.
|
||||||
|
> E.g., `0xFF000000` is opaque black, `0xFFFF0000` is opaque red.
|
||||||
|
|
||||||
|
## 🔤 Text Rendering
|
||||||
|
|
||||||
|
BoredOS provides multiple text rendering methodologies, including a default system font and scaled/bitmap alternatives.
|
||||||
|
|
||||||
|
* `void ui_draw_string(ui_window_t win, int x, int y, const char *str, uint32_t color);`
|
||||||
|
Draw text using the default system typeface.
|
||||||
|
* `void ui_draw_string_bitmap(ui_window_t win, int x, int y, const char *str, uint32_t color);`
|
||||||
|
Draw text using a secondary fast bitmap font renderer.
|
||||||
|
* `void ui_draw_string_scaled(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale);`
|
||||||
|
Draw text scaled up or down by a floating-point multiplier.
|
||||||
|
* `void ui_draw_string_scaled_sloped(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale, float slope);`
|
||||||
|
Draw scaled text with an italic-like slope/shear applied.
|
||||||
|
* `void ui_set_font(ui_window_t win, const char *path);`
|
||||||
|
Load and set a custom `.ttf` or bitmap font from the filesystem for this window.
|
||||||
|
|
||||||
|
### Font Metrics
|
||||||
|
Used for calculating layout bounds before drawing:
|
||||||
|
* `uint32_t ui_get_string_width(const char *str);`
|
||||||
|
* `uint32_t ui_get_font_height(void);`
|
||||||
|
* `uint32_t ui_get_string_width_scaled(const char *str, float scale);`
|
||||||
|
* `uint32_t ui_get_font_height_scaled(float scale);`
|
||||||
|
|
||||||
|
## 🔄 Event Handling
|
||||||
|
|
||||||
|
Applications must continuously poll for events inside an infinite `$while(1)` loop.
|
||||||
|
|
||||||
|
* `bool ui_get_event(ui_window_t win, gui_event_t *ev);`
|
||||||
|
Returns `true` if an event was waiting in the queue, populating the `ev` structure. Returns `false` if the queue is empty.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Because `ui_get_event` is non-blocking, you must call `sys_yield();` inside your event loop if no event was received. In BoredOS's **Multi-Core (SMP)** architecture, failing to yield will pin a CPU core to 100% usage, potentially starving other processes.
|
||||||
|
>
|
||||||
|
> All UI syscalls are **Thread-Safe** at the kernel level via the global GUI spinlock.
|
||||||
|
|
||||||
|
### Graphical Event Structure
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
int type; // Specifies the event class (see below)
|
||||||
|
int arg1; // Generic argument 1
|
||||||
|
int arg2; // Generic argument 2
|
||||||
|
int arg3; // Generic argument 3
|
||||||
|
} gui_event_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Event Types & Arguments
|
||||||
|
|
||||||
|
| Event Constant | `type` ID | Trigger | `arg1` | `arg2` | `arg3` |
|
||||||
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
|
| `GUI_EVENT_NONE` | `0` | Empty event | - | - | - |
|
||||||
|
| `GUI_EVENT_PAINT` | `1` | Window needs redrawing | - | - | - |
|
||||||
|
| `GUI_EVENT_CLICK` | `2` | Mouse click down | X Coord | Y Coord | Button State |
|
||||||
|
| `GUI_EVENT_RIGHT_CLICK` | `3` | Mouse right-click down | X Coord | Y Coord | Button State |
|
||||||
|
| `GUI_EVENT_CLOSE` | `4` | User clicked 'X' button | - | - | - |
|
||||||
|
| `GUI_EVENT_KEY` | `5` | Keyboard key pressed | Keycode | Modifiers | - |
|
||||||
|
| `GUI_EVENT_KEYUP` | `10` | Keyboard key released | Keycode | Modifiers | - |
|
||||||
|
| `GUI_EVENT_MOUSE_DOWN` | `6` | Generic mouse button down | X Coord | Y Coord | Button State |
|
||||||
|
| `GUI_EVENT_MOUSE_UP` | `7` | Generic mouse button release | X Coord | Y Coord | Button State |
|
||||||
|
| `GUI_EVENT_MOUSE_MOVE` | `8` | Mouse cursor moved | X Coord | Y Coord | - |
|
||||||
|
| `GUI_EVENT_MOUSE_WHEEL` | `9` | Scroll wheel rotated | Scroll Delta | - | - |
|
||||||
|
| `GUI_EVENT_RESIZE` | `11` | Window dimensions changed| New Width | New Height | - |
|
||||||
|
|
||||||
|
*(Note: Coordinate arguments (`arg1`, `arg2`) for mouse events are typically relative to the top-left corner of the window's client area).*
|
||||||
|
|
||||||
|
---
|
||||||
58
docs/architecture/core.md
Normal file
58
docs/architecture/core.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Core Architecture</h1>
|
||||||
|
<p><em>Overview of BoredOS kernel layout, boot process, and userspace transition.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
BoredOS is a 64-bit hobbyist operating system designed for the x86_64 architecture. While it features kernel-space drivers and a built-in window manager, it supports fully-isolated userspace applications and includes a networking stack.
|
||||||
|
|
||||||
|
This document serves as an overview of the core architecture and the layout of the kernel source code.
|
||||||
|
|
||||||
|
## 📂 Source Code Layout (`src/`)
|
||||||
|
|
||||||
|
The OS heavily relies on module separation. The `src/` directory is logically split into several domains:
|
||||||
|
|
||||||
|
- **`arch/`**: Contains the assembly routines needed for bootstrapping the system (`boot.asm`) and setting up the CPU state for userland execution (`process_asm.asm`). It also handles architecture-specific mechanisms like the Global Descriptor Table (GDT) and Interrupt Descriptor Table (IDT).
|
||||||
|
- **`core/`**: The initialization sequence of the OS lives here. `main.c` is the entry point from the bootloader. This directory also contains essential kernel utilities (`kutils.c`), panic handlers (`panic.c`), and built-in command parsing logic (`cmd.c`).
|
||||||
|
- **`dev/`**: Device drivers. This includes the PCI scanner, disk management infrastructure, input drivers (keyboard and mouse), and the Real Time Clock (RTC).
|
||||||
|
- **`fs/`**: Filesystem implementations. The system uses a Virtual File System (VFS) abstraction alongside an in-memory FAT32 filesystem with support for drives over ATA that are formatted as FAT32 (plain/MBR).
|
||||||
|
- **`mem/`**: Physical and virtual memory management. It controls page frame allocation, paging, and kernel heap operations.
|
||||||
|
- **`net/`**: The networking stack. BoredOS relies on `lwIP` for processing IPv4 and TCP/UDP traffic, interacting with a range of NICs via `net/nic/`.
|
||||||
|
- **`sys/`**: System calls and process management. The ELF loader resides here, alongside the Symmetric Multi-Processing (**smp.c**) bringup and Local APIC (**lapic.c**) management logic.
|
||||||
|
- **`wm/`**: The graphical subsystem. It handles drawing primitives, window structures, font rendering, and double-buffering.
|
||||||
|
- **`userland/`**: Out-of-kernel components. This includes the custom SDK/compiler environment (`libc/`) and user applications (`cli/`, `gui/`, `games/`).
|
||||||
|
|
||||||
|
## 🚀 Boot Process
|
||||||
|
|
||||||
|
BoredOS uses **Limine** as its primary bootloader.
|
||||||
|
|
||||||
|
1. **Limine Initialization**: The machine firmware (BIOS or UEFI) loads Limine. Limine parses `limine.conf`, sets up an early graphical framebuffer, and reads the kernel ELF file into memory.
|
||||||
|
2. **Multiboot2 & SMP Protocol**: The kernel expects the Limine boot protocol. It makes a specific **SMP Request** to Limine to locate and bring up all available CPU cores.
|
||||||
|
3. **Kernel Entry (`main.c`)**: The entry point `_start` is called on the Bootstrap Processor (BSP). It initializes the serial port, GDT/IDT, memory management, and paging.
|
||||||
|
4. **AP Bringup**: The BSP calls `smp_init()`, which sends the Startup Inter-Processor Interrupt (SIPI) sequence to all Application Processors (APs). Each AP initializes its own local GDT, TSS, and Page Tables before entering an idle loop.
|
||||||
|
5. **Driver Initialization**: PCI buses are scanned, finding the network card or disk controllers. The filesystem is mounted.
|
||||||
|
6. **Window Manager**: The UI is drawn on top of the Limine-provided framebuffer.
|
||||||
|
|
||||||
|
## 🧵 Multi-Core & Scheduling
|
||||||
|
|
||||||
|
BoredOS utilizes Symmetric Multi-Processing (SMP) to distribute workloads across all available CPU cores.
|
||||||
|
|
||||||
|
- **LAPIC & IPIs**: Each CPU has its own Local APIC. The kernel uses Inter-Processor Interrupts (IPIs) for inter-core communication, specifically for triggering the scheduler on other cores (`vector 0x41`).
|
||||||
|
- **Scheduler**: A round-robin scheduler runs on each core. Processes are pinned to specific CPUs (CPU Affinity) to maintain cache locality. The BSP timer interrupt (`60Hz`) broadcasts a scheduling IPI to all core to ensure balanced execution.
|
||||||
|
- **Spinlocks**: Since multiple cores can access kernel structures (VFS, Process List) simultaneously, the kernel uses **interrupt-safe spinlocks** to prevent race conditions.
|
||||||
|
|
||||||
|
## 🛡️ Userland Transition
|
||||||
|
|
||||||
|
The OS supports privilege separation (Ring 0 vs. Ring 3). When an application is launched, the kernel:
|
||||||
|
|
||||||
|
1. Loads the ELF file from the filesystem.
|
||||||
|
2. Assigns the process to a CPU core via a round-robin distribution strategy.
|
||||||
|
3. Allocates a new virtual address space (Page Directory) for the process.
|
||||||
|
4. Maps the executable segments according to the ELF headers.
|
||||||
|
5. Switches to User Mode (Ring 3) via the `iretq` instruction.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Programs interact with the core kernel using system calls (`syscall.c`). Multitasking is achieved by pre-empting user processes on their respective cores.
|
||||||
|
|
||||||
|
---
|
||||||
37
docs/architecture/filesystem.md
Normal file
37
docs/architecture/filesystem.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Filesystem Architecture</h1>
|
||||||
|
<p><em>Virtual File System layer and FAT32 abstraction in BoredOS.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
BoredOS implements a rudimentary but functional filesystem layer designed to support reading system assets and user applications during runtime.
|
||||||
|
|
||||||
|
## 🗂️ Virtual File System (VFS)
|
||||||
|
|
||||||
|
The Virtual File System acts as an abstraction layer across different underlying storage mechanisms (even if, currently, only one type is fully utilized). System calls targeting files (`SYS_FS`) route through the VFS rather than interacting with the disk directly.
|
||||||
|
|
||||||
|
Key VFS functionalities include:
|
||||||
|
- **File Descriptors**: Mapping integer IDs to internal file structures for userland processes.
|
||||||
|
- **Standard Operations**: Standardizing `open()`, `read()`, `write()`, `close()`, `seek()`, and directory listings.
|
||||||
|
- **Path Parsing**: Resolving absolute and relative paths.
|
||||||
|
- **SMP Safety**: All VFS and underlying FAT32 operations are protected by a global **Spinlock**. This ensures that multiple cores can safely read from the filesystem simultaneously without corrupting internal file seek pointers or directory cache states.
|
||||||
|
|
||||||
|
## 💾 FAT32 Implementation
|
||||||
|
|
||||||
|
The primary filesystem logic in `fat32.c` handles both in-memory RAM-based filesystem simulation and physical ATA block devices.
|
||||||
|
|
||||||
|
### 💿 Storage Support
|
||||||
|
|
||||||
|
BoredOS supports two main types of storage for its FAT32 implementation:
|
||||||
|
|
||||||
|
1. **RAMFS (Boot Modules)**: During boot, Limine loads necessary files (such as userland `.elf` binaries, fonts, and wallpapers) into memory as standard boot modules. The FAT32 code parses these loaded memory modules and automatically constructs a synthetic FAT32 directory tree inside RAM (mounted as `A:`).
|
||||||
|
2. **ATA Drives**: The kernel includes a basic PIO-based ATA driver that can detect and read/write to physical IDE/PATA hard disks.
|
||||||
|
- **GPT is NOT supported**: Currently, only **MBR (Master Boot Record)** partition tables or **raw (partitionless)** disks are supported.
|
||||||
|
- **Filesystem**: The partition must be formatted as **FAT32**.
|
||||||
|
|
||||||
|
### 🔍 Auto-detection
|
||||||
|
The `Disk Manager` automatically probes primary and secondary IDE channels during initialization. If a valid FAT32 partition is found (either directly at sector 0 or via an MBR partition table), the disk is assigned a drive letter (starting from `B:`) and becomes accessible to the VFS.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
40
docs/architecture/memory.md
Normal file
40
docs/architecture/memory.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Memory Management</h1>
|
||||||
|
<p><em>Physical and Virtual Memory coordination in x86_64 Long Mode.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Memory management in BoredOS is split into physical and virtual layers, designed to support both kernel operations and userland isolation on the x86_64 architecture.
|
||||||
|
|
||||||
|
## 🧠 Physical Memory Management (PMM)
|
||||||
|
|
||||||
|
The PMM is responsible for tracking which physical RAM frames (usually 4KB each) are free and which are in use.
|
||||||
|
|
||||||
|
1. **Memory Map**: During boot, Limine provides a memory map detailing the available, reserved, and unusable physical memory regions.
|
||||||
|
2. **Bitmap Allocator**: The core PMM uses a bitmap-based allocation strategy. Each bit in the bitmap represents a single physical page (frame). If a bit is `1`, the page is in use; if `0`, it is free.
|
||||||
|
3. **Allocation**: When a new page is requested (e.g., for userland space or kernel heap), the PMM scans the bitmap for the first available zero bit, marks it as used, and returns the physical address.
|
||||||
|
4. **SMP Safety**: In a multi-core environment, the PMM and VMM are protected by **Spinlocks** to prevent two CPUs from allocating the same frame or modifying page tables simultaneously.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 4KB frame sizes strike a balance between allocation speed and minimal memory fragmentation, fitting directly with the page tables.
|
||||||
|
|
||||||
|
## 🗺️ Virtual Memory Management (VMM) and Paging
|
||||||
|
|
||||||
|
BoredOS uses 4-level paging (PML4), a requirement for x86_64 long mode, dividing the virtual address space between the kernel and userland.
|
||||||
|
|
||||||
|
- **Kernel Space**: The kernel relies on a higher-half design where its code, data, and heap are mapped to high addresses (typically above `0xFFFF800000000000`).
|
||||||
|
- **Per-CPU Structures**: Each CPU core maintains its own architectural state in memory:
|
||||||
|
* **Per-CPU GDT**: Each core is initialized with its own Global Descriptor Table.
|
||||||
|
* **Per-CPU TSS**: Each core has a dedicated Task State Segment containing the `RSP0` pointer for its own kernel stack, ensuring safe interrupt handling across cores.
|
||||||
|
- **User Space**: Userland applications are loaded into lower virtual addresses.
|
||||||
|
- **Page Faults**: The `mem/` subsystem registers an Interrupt Service Routine (ISR) for page faults (Interrupt 14). If a process accesses unmapped memory, the handler determines whether to allocate a new frame or terminate the process.
|
||||||
|
|
||||||
|
## 🏗️ Kernel Heap
|
||||||
|
|
||||||
|
Dynamic allocation within the kernel (`kmalloc` and `kfree`) is layered on top of the physical allocator. The kernel maintains its own heap area in virtual memory. When the heap requires more space, it requests physical frames from the PMM and maps them into the kernel's virtual address space.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> The kernel heap is a shared resource; therefore, all `kmalloc` and `kfree` operations are guarded by a global spinlock to ensure thread safety during multi-core execution.
|
||||||
|
|
||||||
|
---
|
||||||
48
docs/architecture/window_manager.md
Normal file
48
docs/architecture/window_manager.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h1>Window Manager (WM)</h1>
|
||||||
|
<p><em>The native graphical subsystem compositing and event routing.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
BoredOS features a fully custom, graphical Window Manager built directly into the kernel, residing in the `src/wm/` directory. It is responsible for compositing the screen, handling window logic, rendering text, and dispatching UI events.
|
||||||
|
|
||||||
|
## 🖼️ Framebuffer and Rendering
|
||||||
|
|
||||||
|
1. **Limine Framebuffer**: During boot, the Limine bootloader requests a graphical framebuffer from the hardware (e.g., GOP in UEFI environments) and passes a pointer to this linear memory buffer to the kernel.
|
||||||
|
2. **Double Buffering**: To prevent screen tearing, the WM does not draw directly to the screen. It allocates a "back buffer" in kernel memory equal to the size of the screen. All drawing operations (lines, rectangles, windows) happen on this back buffer.
|
||||||
|
3. **Compositing**: Once per frame or upon request, the entire back buffer (or dirty regions) is copied to the actual Limine physical framebuffer memory, making the changes visible instantly.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> The performance of the window manager heavily depends on minimizing the "dirty regions" drawn in the compositing loop rather than sweeping the whole screen.
|
||||||
|
|
||||||
|
## 🪟 Window System (`wm.c`)
|
||||||
|
|
||||||
|
The windowing system is built around a linked list of `Window` structures.
|
||||||
|
|
||||||
|
- **Z-Ordering**: The list determines the draw order. Windows at the back of the list are drawn first, and the active window is drawn last (on top).
|
||||||
|
- **Window Structures**: Each window object tracks its dimensions (`x`, `y`, `width`, `height`), title, background color, and an internal buffer if it's acting as a canvas for userland apps.
|
||||||
|
- **Decorations**: The kernel handles drawing window borders, title bars, and close buttons automatically unless a borderless style is specified.
|
||||||
|
|
||||||
|
## 🖱️ Input Handling and Events
|
||||||
|
|
||||||
|
The WM acts as the central hub for input routing.
|
||||||
|
|
||||||
|
1. **Mouse Driver**: The PS/2 mouse driver (`dev/mouse.c`) detects movement and button clicks. It raises interrupts that update global cursor coordinates.
|
||||||
|
2. **Hit Testing**: The WM checks these coordinates against the bounding boxes of existing windows. It handles dragging logic (if the user clicks a title bar) or focus changes.
|
||||||
|
3. **Event Queue**: If a userland application owns the window that was clicked, the WM packages the input (coordinates, button state) into an event message and drops it into the owning process's event queue. The application can retrieve these via the custom libc UI functions.
|
||||||
|
|
||||||
|
- **Event Polling**: The UI loop inside an app continuously calls `ui_poll_event()` to respond to mouse clicks and window movement dispatched by the kernel WM.
|
||||||
|
|
||||||
|
## 🧵 Multi-Core Safety & Performance
|
||||||
|
|
||||||
|
With the introduction of Symmetric Multi-Processing (SMP), the Window Manager (WM) was redesigned to ensure stability and high performance across multiple cores.
|
||||||
|
|
||||||
|
1. **Granular Window Locks**: Each `Window` object possesses its own `spinlock_t lock;`. User applications concurrently draw directly into their own window buffers without stalling the rest of the system. The global `wm_lock` is reserved strictly for altering global structures like window z-order or syncing buffers to the screen compositing layer.
|
||||||
|
2. **Per-CPU Rendering State**: To facilitate simultaneous GUI system calls across all CPU cores, the low-level rendering context (`g_render_target` array) is isolated per-CPU using the core ID. This allows completely lockless multi-core pixel rasterization, drastically reducing rendering bottlenecks.
|
||||||
|
3. **Deferred Compositing**: Final screen composition (`wm_paint`) is scheduled to the main kernel idle loop on the Bootstrap Processor (BSP). This enables application cores to continue processing logic seamlessly while the GUI asynchronously handles flipping the physical framebuffer.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Because application rendering (rasterizing geometry into a window's backbuffer) is SMP-safe and lock-free across cores, GUI performance scales linearly with the number of CPUs active.
|
||||||
|
|
||||||
|
---
|
||||||
52
docs/build/toolchain.md
vendored
Normal file
52
docs/build/toolchain.md
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Build Toolchain
|
||||||
|
|
||||||
|
BoredOS is built cross-compiled from a host system (such as macOS or Linux) to target the generic `x86_64-elf` platform.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
To build BoredOS, you need the following tools:
|
||||||
|
|
||||||
|
1. **x86_64 ELF GCC Cross-Compiler**:
|
||||||
|
- `x86_64-elf-gcc`: The C compiler targeting the freestanding overarching ELF environment.
|
||||||
|
- `x86_64-elf-ld`: The linker to combine object files into the final `boredos.elf` kernel binary and userland variables.
|
||||||
|
|
||||||
|
2. **NASM**:
|
||||||
|
- Required to compile the `.asm` files in `src/arch/` and `src/userland/crt0.asm`. It formats the output as `elf64` objects to be linked alongside the C code.
|
||||||
|
|
||||||
|
3. **xorriso**:
|
||||||
|
- A specialized tool to create ISO 9660 filesystem images.
|
||||||
|
- *Why?* `xorriso` packages the compiled kernel, Limine bootloader, and asset files (fonts, images, userland binaries) into the final bootable `boredos.iso` CD-ROM image.
|
||||||
|
|
||||||
|
4. **QEMU** (Optional but highly recommended for testing):
|
||||||
|
- `qemu-system-x86_64` is used for rapid emulation and testing.
|
||||||
|
|
||||||
|
## Installation (macOS)
|
||||||
|
|
||||||
|
You can easily install the complete toolchain using Homebrew:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install x86_64-elf-binutils x86_64-elf-gcc nasm xorriso qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation (Linux)
|
||||||
|
|
||||||
|
Depending on your distribution, the installation commands vary. Note that some distributions may require you to build the `x86_64-elf` cross-compiler from source if it isn't available in their default repositories.
|
||||||
|
|
||||||
|
### Debian / Ubuntu
|
||||||
|
```sh
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo nasm xorriso qemu-system-x86
|
||||||
|
```
|
||||||
|
*(Note: You will need to build the `x86_64-elf` cross-compiler from source or find a compatible PPA, as it is not in the default Debian/Ubuntu repositories.)*
|
||||||
|
|
||||||
|
### Arch Linux
|
||||||
|
Arch Linux provides the regular tools in its standard repositories and the cross-compiler via the AUR:
|
||||||
|
```sh
|
||||||
|
sudo pacman -S nasm xorriso qemu-full
|
||||||
|
yay -S x86_64-elf-gcc x86_64-elf-binutils
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fedora
|
||||||
|
```sh
|
||||||
|
sudo dnf install make gcc gcc-c++ bison flex gmp-devel mpfr-devel libmpc-devel texinfo nasm xorriso qemu
|
||||||
|
```
|
||||||
58
docs/build/usage.md
vendored
Normal file
58
docs/build/usage.md
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Building, Running, and Deployment
|
||||||
|
|
||||||
|
BoredOS uses a single top-level `Makefile` to orchestrate the build process.
|
||||||
|
|
||||||
|
## The Build Process
|
||||||
|
|
||||||
|
When you run `make` in the root directory, the following stages occur automatically:
|
||||||
|
|
||||||
|
1. **Limine Setup (`limine-setup`)**:
|
||||||
|
If the Limine bootloader binaries are missing, the Makefile automatically clones the appropriate Limine binary release from GitHub and compiles its host utility.
|
||||||
|
2. **Kernel Compilation**:
|
||||||
|
All `.c` files in `src/core`, `src/mem`, `src/dev`, `src/sys`, `src/fs`, `src/wm`, and `src/net` are compiled into object files (`.o`) inside the `build/` directory using `x86_64-elf-gcc`.
|
||||||
|
3. **Kernel Assembly**:
|
||||||
|
All `.asm` files in `src/arch/` are assembled into object files using `nasm`.
|
||||||
|
4. **Kernel Linking**:
|
||||||
|
`x86_64-elf-ld` links the kernel object files together, instructed by the `linker.ld` script, outputting the `boredos.elf` kernel binary.
|
||||||
|
5. **Userland Compilation**:
|
||||||
|
The Makefile shifts into the `src/userland` directory, compiling the custom `libc` and generating `bin/*.elf` executable user applications.
|
||||||
|
6. **ISO Generation**:
|
||||||
|
The `iso_root` directory is staged. The kernel, Limine configuration, fonts, images, and userland applications are copied in. Finally, `xorriso` generates the `boredos.iso` bootable image.
|
||||||
|
|
||||||
|
## Minimum System Requirements
|
||||||
|
|
||||||
|
To run BoredOS successfully (either in emulation or on bare metal), your target machine should meet the following minimum requirements:
|
||||||
|
|
||||||
|
- **CPU**: An `x86_64` (64-bit) compatible processor.
|
||||||
|
- **Memory**: Approximately `~256 MB` of RAM.
|
||||||
|
- **Display**: A VGA-compatible display (required for the GUI Window Manager).
|
||||||
|
- **Networking (Optional)**: A compatible Network Interface Card (NIC) is required if you want to use the networking stack (e.g., an Intel E1000 or similar supported by the [`net/nic/`](../../src/net/nic/) drivers). Networking is not strictly required for the OS to boot or run offline applications.
|
||||||
|
|
||||||
|
|
||||||
|
## Running in Emulation
|
||||||
|
|
||||||
|
To test the generated ISO quickly without real hardware, use the QEMU emulator:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make run
|
||||||
|
```
|
||||||
|
|
||||||
|
This command invokes QEMU with specific arguments:
|
||||||
|
- `-m 4G`: Allocates 4 Gigabytes of RAM.
|
||||||
|
- `-cdrom boredos.iso`: Mounts the built OS image as a CD-ROM.
|
||||||
|
- `-netdev user...`: Sets up a basic NAT network interface for the OS's networking stack.
|
||||||
|
- `-smp 4`: Enables 4 CPU cores.
|
||||||
|
- `-drive file=disk.img...`: Attaches a raw disk image included in this release of BoredOS.
|
||||||
|
|
||||||
|
## Running on Bare Metal
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> Running hobby operating systems on real hardware is at your own risk and may cause undefined behavior.
|
||||||
|
|
||||||
|
To boot BoredOS on a physical PC:
|
||||||
|
|
||||||
|
1. Build the OS to get `boredos.iso`.
|
||||||
|
2. Use a flashing tool like **Balena Etcher** or `dd` to write the ISO to a USB flash drive.
|
||||||
|
3. Reboot your target computer, enter the BIOS/UEFI setup.
|
||||||
|
4. **Boot Configuration**: BoredOS supports booting on both modern **UEFI** systems and legacy **BIOS** systems natively via Limine. Ensure **Secure Boot** is disabled in your firmware settings.
|
||||||
|
5. Select the USB drive from the boot menu.
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,156 +0,0 @@
|
|||||||
# Brew OS 1.45 Beta
|
|
||||||
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
|
|
||||||
|
|
||||||
## Brewkernel is now BrewOS!
|
|
||||||
Brewkernel will from now on be deprecated as it's core became too messy. I have built a less bloated kernel and wrote a DE above it, which is why it is now an OS instead of a kernel (in my opinion).
|
|
||||||
|
|
||||||
|
|
||||||
<img src="asciiart.png" width="200" /> </br>
|
|
||||||
Brew Kernel is a simple x86_64 hobbyist operating system.
|
|
||||||
It features a DE (and WM), a FAT32 filesystem, customizable UI and much much more!
|
|
||||||
|
|
||||||
## Features
|
|
||||||
- Drag and drop mouse centered UI
|
|
||||||
- Customizable UI
|
|
||||||
- Basic Networking Stack
|
|
||||||
- Brew WM
|
|
||||||
- Fat 32 FS
|
|
||||||
- 64-bit long mode support
|
|
||||||
- Multiboot2 compliant
|
|
||||||
- Text editor
|
|
||||||
- Markdown Viewer
|
|
||||||
- Minesweeper
|
|
||||||
- IDT
|
|
||||||
- Ability to run on actual x86_64 hardware
|
|
||||||
- CLI
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
To build BrewOS, you'll need the following tools installed:
|
|
||||||
|
|
||||||
- **x86_64 ELF Toolchain**: `x86_64-elf-gcc`, `x86_64-elf-ld`
|
|
||||||
- **NASM**: Netwide Assembler for compiling assembly code
|
|
||||||
- **xorriso**: For creating bootable ISO images
|
|
||||||
- **QEMU** (optional): For testing the kernel in an emulator
|
|
||||||
|
|
||||||
On macOS, you can install these using Homebrew:
|
|
||||||
```sh
|
|
||||||
brew install x86_64-elf-binutils x86_64-elf-gcc nasm xorriso qemu
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
Simply run `make` from the project root:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
This will:
|
|
||||||
1. Compile all kernel C sources and assembly files
|
|
||||||
2. Link the kernel ELF binary
|
|
||||||
3. Generate a bootable ISO image (`brewos.iso`)
|
|
||||||
|
|
||||||
The build output is organized as follows:
|
|
||||||
- Compiled object files: `build/`
|
|
||||||
- ISO root filesystem: `iso_root/`
|
|
||||||
- Final ISO image: `brewos.iso`
|
|
||||||
|
|
||||||
## Running
|
|
||||||
|
|
||||||
### QEMU Emulation
|
|
||||||
|
|
||||||
Run the kernel in QEMU:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make run
|
|
||||||
```
|
|
||||||
|
|
||||||
Or manually:
|
|
||||||
```sh
|
|
||||||
qemu-system-x86_64 -m 2G -serial stdio -cdrom brewos.iso -boot d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running on Real Hardware
|
|
||||||
|
|
||||||
*Warning: This is at YOUR OWN RISK. This software comes with ZERO warranty and may break your system.*
|
|
||||||
|
|
||||||
1. **Create bootable USB**: Use [Balena Etcher](https://www.balena.io/etcher/) to flash `brewos.iso` to a USB drive
|
|
||||||
|
|
||||||
2. **Prepare the system**:
|
|
||||||
- Enable legacy (BIOS) boot in your system BIOS/UEFI settings
|
|
||||||
- Disable Secure Boot if needed
|
|
||||||
|
|
||||||
3. **Boot**: Insert the USB drive and select it in the boot menu during startup
|
|
||||||
|
|
||||||
**Networking requires an Intel E1000 network card or similar while using Ethernet.**
|
|
||||||
|
|
||||||
4. **Tested Hardware**:
|
|
||||||
- HP EliteDesk 705 G4 DM (AMD Ryzen 5 PRO 2400G, Radeon Vega) **Tested, no networking.**
|
|
||||||
- Lenovo ThinkPad A475 20KL002VMH (AMD Pro A12-8830B, Radeon R7) **Tested, no networking.**
|
|
||||||
- Acer Aspire E5-573-311M (Intel Core i3-5005U, Intel HD Graphics) **Tested, no networking.**
|
|
||||||
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
- `src/kernel/` - Main kernel implementation
|
|
||||||
- `boot.asm` - Boot assembly code
|
|
||||||
- `main.c` - Kernel entry point
|
|
||||||
- `*.c / *.h` - Core kernel modules (graphics, interrupts, filesystem, etc.)
|
|
||||||
- `cli_apps/` - Command-line applications
|
|
||||||
- `build/` - Compiled object files (generated during build)
|
|
||||||
- `iso_root/` - ISO filesystem layout (generated during build)
|
|
||||||
- `limine/` - Limine bootloader files (downloaded automatically)
|
|
||||||
- `linker.ld` - Linker script for x86_64 ELF
|
|
||||||
- `limine.cfg` - Limine bootloader configuration
|
|
||||||
- `Makefile` - Build configuration and targets
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
###
|
|
||||||
|
|
||||||
<h2 align="left">Help me brew some coffee! ☕️</h2>
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
<p align="left">
|
|
||||||
If you enjoy this project, and like what i'm doing here, consider buying me a coffee!
|
|
||||||
<br><br>
|
|
||||||
<a href="https://buymeacoffee.com/boreddevnl" target="_blank">
|
|
||||||
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50" style="border-radius: 8px;" />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Copyright (C) 2024-2026 boreddevnl
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
NOTICE
|
|
||||||
------
|
|
||||||
|
|
||||||
This product includes software developed by Chris ("boreddevnl") as part of the BrewKernel project.
|
|
||||||
|
|
||||||
Copyright (C) 2024–2026 Chris / boreddevnl (previously boreddevhq)
|
|
||||||
|
|
||||||
All source files in this repository contain copyright and license
|
|
||||||
headers that must be preserved in redistributions and derivative works.
|
|
||||||
|
|
||||||
If you distribute or modify this project (in whole or in part),
|
|
||||||
you MUST:
|
|
||||||
|
|
||||||
- Retain all copyright and license headers at the top of each file.
|
|
||||||
- Include this NOTICE file along with any redistributions or
|
|
||||||
derivative works.
|
|
||||||
- Provide clear attribution to the original author in documentation
|
|
||||||
or credits where appropriate.
|
|
||||||
|
|
||||||
The above attribution requirements are informational and intended to
|
|
||||||
ensure proper credit is given. They do not alter or supersede the
|
|
||||||
terms of the GNU General Public License (GPL), which governs this work.
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,9 +0,0 @@
|
|||||||
TIMEOUT=3
|
|
||||||
|
|
||||||
:BrewOS
|
|
||||||
PROTOCOL=limine
|
|
||||||
|
|
||||||
KERNEL_PATH=boot:///brewos.elf
|
|
||||||
|
|
||||||
#FRAMEBUFFER_WIDTH=1280
|
|
||||||
#FRAMEBUFFER_HEIGHT=720
|
|
||||||
1
limine
1
limine
Submodule limine deleted from efd130dbb6
@@ -1,9 +0,0 @@
|
|||||||
TIMEOUT=3
|
|
||||||
|
|
||||||
:BrewOS
|
|
||||||
PROTOCOL=limine
|
|
||||||
|
|
||||||
KERNEL_PATH=boot:///brewos.elf
|
|
||||||
|
|
||||||
#FRAMEBUFFER_WIDTH=1280
|
|
||||||
#FRAMEBUFFER_HEIGHT=720
|
|
||||||
15
limine.conf
Normal file
15
limine.conf
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
# This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
# This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
|
||||||
|
timeout: 3
|
||||||
|
verbose: yes
|
||||||
|
|
||||||
|
${WALLPAPER_PATH}=boot():/splash.jpg
|
||||||
|
wallpaper: ${WALLPAPER_PATH}
|
||||||
|
wallpaper_style: centered
|
||||||
|
backdrop: 000000
|
||||||
|
|
||||||
|
/BoredOS
|
||||||
|
protocol: limine
|
||||||
|
path: boot():/boredos.elf
|
||||||
14
linker.ld
14
linker.ld
@@ -15,6 +15,12 @@ SECTIONS
|
|||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.requests : {
|
||||||
|
KEEP(*(.requests_start))
|
||||||
|
KEEP(*(.requests))
|
||||||
|
KEEP(*(.requests_end))
|
||||||
|
}
|
||||||
|
|
||||||
.data : {
|
.data : {
|
||||||
*(.data*)
|
*(.data*)
|
||||||
}
|
}
|
||||||
@@ -24,14 +30,6 @@ SECTIONS
|
|||||||
*(.bss*)
|
*(.bss*)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limine requests section */
|
|
||||||
.requests : {
|
|
||||||
KEEP(*(.requests_start))
|
|
||||||
KEEP(*(.requests))
|
|
||||||
KEEP(*(.requests_end))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Discard unnecessary sections */
|
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
*(.note .note.*)
|
*(.note .note.*)
|
||||||
|
|||||||
BIN
screenshot.jpg
Normal file
BIN
screenshot.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 342 KiB |
BIN
splash.jpg
Normal file
BIN
splash.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
19
src/arch/boot.asm
Normal file
19
src/arch/boot.asm
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
; 64-bit Entry Point for BoredOS
|
||||||
|
; Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
; This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
; This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
section .text
|
||||||
|
global _start
|
||||||
|
extern kmain
|
||||||
|
|
||||||
|
bits 64
|
||||||
|
|
||||||
|
_start:
|
||||||
|
cli
|
||||||
|
|
||||||
|
|
||||||
|
call kmain
|
||||||
|
|
||||||
|
hlt
|
||||||
|
.loop:
|
||||||
|
jmp .loop
|
||||||
31
src/arch/gdt_asm.asm
Normal file
31
src/arch/gdt_asm.asm
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
; Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
; This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
; This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
global gdt_flush
|
||||||
|
global tss_flush
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
gdt_flush:
|
||||||
|
lgdt [rdi] ; Load GDT from the pointer passed in RDI
|
||||||
|
|
||||||
|
mov ax, 0x10 ; 0x10 is the offset in the GDT to data segment
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
|
; Far jump to update CS
|
||||||
|
push 0x08 ; 0x08 is the offset to the code segment
|
||||||
|
lea rax, [rel .flush]
|
||||||
|
push rax
|
||||||
|
retfq
|
||||||
|
|
||||||
|
.flush:
|
||||||
|
ret
|
||||||
|
|
||||||
|
tss_flush:
|
||||||
|
mov ax, 0x28 ; 0x28 is the offset in the GDT to the TSS
|
||||||
|
ltr ax
|
||||||
|
ret
|
||||||
201
src/arch/interrupts.asm
Normal file
201
src/arch/interrupts.asm
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
; Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
; This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
; This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
section .text
|
||||||
|
global isr0_wrapper
|
||||||
|
global isr1_wrapper
|
||||||
|
global isr8_wrapper
|
||||||
|
global isr12_wrapper
|
||||||
|
global isr14_wrapper
|
||||||
|
global isr128_wrapper
|
||||||
|
global isr_sched_ipi_wrapper
|
||||||
|
extern timer_handler
|
||||||
|
extern keyboard_handler
|
||||||
|
extern mouse_handler
|
||||||
|
extern sched_ipi_handler
|
||||||
|
extern syscall_handler_c
|
||||||
|
extern exception_handler_c
|
||||||
|
|
||||||
|
; Helper to send EOI (End of Interrupt) to PIC
|
||||||
|
send_eoi:
|
||||||
|
push rax
|
||||||
|
mov al, 0x20
|
||||||
|
out 0x20, al ; Master PIC
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
%macro ISR_NOERRCODE 2
|
||||||
|
isr%2_wrapper:
|
||||||
|
push 0 ; Dummy error code
|
||||||
|
push %2 ; Vector
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
; Save SSE/FPU state (fxsave requires 16-byte alignment)
|
||||||
|
sub rsp, 512
|
||||||
|
fxsave [rsp]
|
||||||
|
|
||||||
|
; Pass current RSP as 1st argument (registers_t*)
|
||||||
|
mov rdi, rsp
|
||||||
|
|
||||||
|
call %1
|
||||||
|
|
||||||
|
; Update RSP with return value (task switch)
|
||||||
|
mov rsp, rax
|
||||||
|
|
||||||
|
; Restore SSE/FPU state
|
||||||
|
fxrstor [rsp]
|
||||||
|
add rsp, 512
|
||||||
|
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
add rsp, 16 ; drop dummy vector and error code
|
||||||
|
iretq
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
isr0_wrapper:
|
||||||
|
ISR_NOERRCODE timer_handler, 32
|
||||||
|
|
||||||
|
isr1_wrapper:
|
||||||
|
ISR_NOERRCODE keyboard_handler, 33
|
||||||
|
|
||||||
|
isr12_wrapper:
|
||||||
|
ISR_NOERRCODE mouse_handler, 44
|
||||||
|
|
||||||
|
isr_sched_ipi_wrapper:
|
||||||
|
ISR_NOERRCODE sched_ipi_handler, 65
|
||||||
|
|
||||||
|
isr128_wrapper:
|
||||||
|
ISR_NOERRCODE syscall_handler_c, 128
|
||||||
|
|
||||||
|
; Common exception macro for exceptions WITHOUT error code
|
||||||
|
%macro EXCEPTION_NOERRCODE 1
|
||||||
|
global exc%1_wrapper
|
||||||
|
exc%1_wrapper:
|
||||||
|
push 0 ; Dummy error code
|
||||||
|
push %1 ; Vector
|
||||||
|
jmp exception_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Common exception macro for exceptions WITH error code
|
||||||
|
%macro EXCEPTION_ERRCODE 1
|
||||||
|
global exc%1_wrapper
|
||||||
|
exc%1_wrapper:
|
||||||
|
push %1 ; Vector
|
||||||
|
jmp exception_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Define all 32 standard exceptions
|
||||||
|
EXCEPTION_NOERRCODE 0 ; Divide Error
|
||||||
|
EXCEPTION_NOERRCODE 1 ; Debug
|
||||||
|
EXCEPTION_NOERRCODE 2 ; NMI
|
||||||
|
EXCEPTION_NOERRCODE 3 ; Breakpoint
|
||||||
|
EXCEPTION_NOERRCODE 4 ; Overflow
|
||||||
|
EXCEPTION_NOERRCODE 5 ; Bound Range Exceeded
|
||||||
|
EXCEPTION_NOERRCODE 6 ; Invalid Opcode
|
||||||
|
EXCEPTION_NOERRCODE 7 ; Device Not Available
|
||||||
|
EXCEPTION_ERRCODE 8 ; Double Fault
|
||||||
|
EXCEPTION_NOERRCODE 9 ; Coprocessor Segment Overrun
|
||||||
|
EXCEPTION_ERRCODE 10 ; Invalid TSS
|
||||||
|
EXCEPTION_ERRCODE 11 ; Segment Not Present
|
||||||
|
EXCEPTION_ERRCODE 12 ; Stack-Segment Fault
|
||||||
|
EXCEPTION_ERRCODE 13 ; General Protection Fault
|
||||||
|
EXCEPTION_ERRCODE 14 ; Page Fault
|
||||||
|
EXCEPTION_NOERRCODE 15 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 16 ; x87 Floating-Point Exception
|
||||||
|
EXCEPTION_ERRCODE 17 ; Alignment Check
|
||||||
|
EXCEPTION_NOERRCODE 18 ; Machine Check
|
||||||
|
EXCEPTION_NOERRCODE 19 ; SIMD Floating-Point Exception
|
||||||
|
EXCEPTION_NOERRCODE 20 ; Virtualization Exception
|
||||||
|
EXCEPTION_ERRCODE 21 ; Control Protection Exception
|
||||||
|
EXCEPTION_NOERRCODE 22 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 23 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 24 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 25 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 26 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 27 ; Reserved
|
||||||
|
EXCEPTION_NOERRCODE 28 ; Hypervisor Injection Exception
|
||||||
|
EXCEPTION_ERRCODE 29 ; VMM Communication Exception
|
||||||
|
EXCEPTION_ERRCODE 30 ; Security Exception
|
||||||
|
EXCEPTION_NOERRCODE 31 ; Reserved
|
||||||
|
|
||||||
|
exception_common:
|
||||||
|
; Save registers (registers_t structure)
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
; Save SSE/FPU state (fxsave requires 16-byte alignment)
|
||||||
|
sub rsp, 512
|
||||||
|
fxsave [rsp]
|
||||||
|
|
||||||
|
; Pass current RSP as 1st argument (registers_t*)
|
||||||
|
mov rdi, rsp
|
||||||
|
|
||||||
|
call exception_handler_c
|
||||||
|
|
||||||
|
; Switch stack if needed (for process termination)
|
||||||
|
mov rsp, rax
|
||||||
|
|
||||||
|
; Restore SSE/FPU state
|
||||||
|
fxrstor [rsp]
|
||||||
|
add rsp, 512
|
||||||
|
|
||||||
|
; Restore registers
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
add rsp, 16 ; drop vector and error code
|
||||||
|
iretq
|
||||||
|
|
||||||
61
src/arch/process_asm.asm
Normal file
61
src/arch/process_asm.asm
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
; Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
; This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
; This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
global process_jump_usermode
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
|
||||||
|
process_jump_usermode:
|
||||||
|
cli
|
||||||
|
|
||||||
|
; Load user data segment (0x23)
|
||||||
|
mov ax, 0x23
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
; Build the IRETQ stack frame
|
||||||
|
; 1. SS (User Data Segment)
|
||||||
|
push 0x23
|
||||||
|
|
||||||
|
; 2. RSP (User Stack)
|
||||||
|
push rsi
|
||||||
|
|
||||||
|
; 3. RFLAGS (Enable Interrupts: IF = 0x200 | Reserved bit 1 = 0x2 -> 0x202)
|
||||||
|
push 0x202
|
||||||
|
|
||||||
|
; 4. CS (User Code Segment)
|
||||||
|
push 0x1B
|
||||||
|
|
||||||
|
; 5. RIP (Entry Point)
|
||||||
|
push rdi
|
||||||
|
|
||||||
|
; Jump to Ring 3!
|
||||||
|
iretq
|
||||||
|
|
||||||
|
; void context_switch_to(uint64_t rsp)
|
||||||
|
; Restores context from isr frame and jumps
|
||||||
|
global context_switch_to
|
||||||
|
context_switch_to:
|
||||||
|
mov rsp, rdi
|
||||||
|
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
|
||||||
|
add rsp, 16 ; drop int_no and err_code
|
||||||
|
iretq
|
||||||
94
src/arch/syscalls.asm
Normal file
94
src/arch/syscalls.asm
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
; Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||||
|
; This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||||
|
; This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||||
|
global syscall_entry
|
||||||
|
extern syscall_handler_c
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
; Syscall ABI:
|
||||||
|
; RDI = syscall_num
|
||||||
|
; RSI = arg1
|
||||||
|
; RDX = arg2
|
||||||
|
; R10 = arg3
|
||||||
|
; R8 = arg4
|
||||||
|
; R9 = arg5
|
||||||
|
|
||||||
|
syscall_entry:
|
||||||
|
; 1. Switch to Kernel Stack safely
|
||||||
|
; Note: For true SMP safety, we need per-CPU storage (via swapgs).
|
||||||
|
; For now, we use a global scratch which is only safe because we mask interrupts on entry.
|
||||||
|
mov [rel user_rsp_scratch], rsp
|
||||||
|
mov rsp, [rel kernel_syscall_stack]
|
||||||
|
|
||||||
|
; 2. Build iretq frame (compatible with registers_t)
|
||||||
|
push 0x1B ; SS (User Data)
|
||||||
|
push qword [rel user_rsp_scratch] ; RSP
|
||||||
|
push r11 ; RFLAGS (captured by syscall)
|
||||||
|
push 0x23 ; CS (User Code)
|
||||||
|
push rcx ; RIP (return address from syscall)
|
||||||
|
|
||||||
|
push 0 ; err_code
|
||||||
|
push 0 ; int_no (can be used for syscall vector)
|
||||||
|
|
||||||
|
; 3. Save all registers in registers_t order
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
; Save SSE/FPU state
|
||||||
|
sub rsp, 512
|
||||||
|
fxsave [rsp]
|
||||||
|
|
||||||
|
; 4. Call C handler with registers_t*
|
||||||
|
mov rdi, rsp
|
||||||
|
call syscall_handler_c
|
||||||
|
|
||||||
|
; 5. Switch to the resulting RSP (might be different if task switched)
|
||||||
|
mov rsp, rax
|
||||||
|
|
||||||
|
; Restore SSE/FPU state
|
||||||
|
fxrstor [rsp]
|
||||||
|
add rsp, 512
|
||||||
|
|
||||||
|
; 6. Restore and return via iretq
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
add rsp, 16 ; drop int_no/err_code
|
||||||
|
|
||||||
|
; Debug: check RIP before iretq
|
||||||
|
; We can't easily print from here without destroying registers,
|
||||||
|
; but we can at least check if it's canonical.
|
||||||
|
|
||||||
|
iretq
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
global kernel_syscall_stack
|
||||||
|
global user_rsp_scratch
|
||||||
|
kernel_syscall_stack: resq 1
|
||||||
|
user_rsp_scratch: resq 1
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user