mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 10:26:59 +00:00
Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
12
.gitignore
vendored
12
.gitignore
vendored
@@ -18,3 +18,15 @@ limine 2/Makefile
|
||||
limine 2/limine
|
||||
limine 2/limine.dSYM/Contents/Resources/DWARF/limine
|
||||
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
|
||||
8
LICENSE
8
LICENSE
@@ -3,7 +3,7 @@
|
||||
|
||||
Copyright(C) Chris (boreddevnl) 2024-2026
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/\>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -647,7 +647,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
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.
|
||||
|
||||
@@ -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,
|
||||
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
|
||||
<https://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/\>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
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
|
||||
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\>.
|
||||
|
||||
197
Makefile
197
Makefile
@@ -1,122 +1,233 @@
|
||||
# BrewOS Makefile
|
||||
# BoredOS Makefile
|
||||
# Target Architecture: x86_64
|
||||
# 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
|
||||
LD = x86_64-elf-ld
|
||||
NASM = nasm
|
||||
XORRISO = xorriso
|
||||
|
||||
SRC_DIR = src/kernel
|
||||
SRC_DIR = src
|
||||
BUILD_DIR = build
|
||||
ISO_DIR = iso_root
|
||||
|
||||
KERNEL_ELF = $(BUILD_DIR)/brewos.elf
|
||||
ISO_IMAGE = brewos.iso
|
||||
KERNEL_ELF = $(BUILD_DIR)/boredos.elf
|
||||
ISO_IMAGE = boredos.iso
|
||||
|
||||
C_SOURCES = $(wildcard $(SRC_DIR)/*.c)
|
||||
CLI_APP_SOURCES = $(wildcard $(SRC_DIR)/cli_apps/*.c)
|
||||
ASM_SOURCES = $(wildcard $(SRC_DIR)/*.asm)
|
||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(C_SOURCES)) \
|
||||
$(patsubst $(SRC_DIR)/cli_apps/%.c, $(BUILD_DIR)/cli_apps/%.o, $(CLI_APP_SOURCES)) \
|
||||
$(patsubst $(SRC_DIR)/%.asm, $(BUILD_DIR)/%.o, $(ASM_SOURCES))
|
||||
C_SOURCES = $(wildcard $(SRC_DIR)/core/*.c) \
|
||||
$(wildcard $(SRC_DIR)/sys/*.c) \
|
||||
$(wildcard $(SRC_DIR)/mem/*.c) \
|
||||
$(wildcard $(SRC_DIR)/dev/*.c) \
|
||||
$(wildcard $(SRC_DIR)/net/*.c) \
|
||||
$(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 \
|
||||
-fno-stack-protector -fno-stack-check -fno-lto -fPIE \
|
||||
-m64 -march=x86-64 -mno-80387 -mno-mmx -mno-sse -mno-sse2 -mno-red-zone \
|
||||
-I$(SRC_DIR) -I$(SRC_DIR)/cli_apps
|
||||
-m64 -march=x86-64 -msse -msse2 -mstackrealign -mno-red-zone \
|
||||
-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 \
|
||||
-z text -z max-page-size=0x1000 -T linker.ld
|
||||
|
||||
NASMFLAGS = -f elf64
|
||||
|
||||
# Limine Version
|
||||
LIMINE_VERSION = 7.0.0
|
||||
LIMINE_VERSION = 10.8.2
|
||||
LIMINE_URL_BASE = https://github.com/limine-bootloader/limine/raw/v$(LIMINE_VERSION)
|
||||
|
||||
.PHONY: all clean run limine-setup
|
||||
|
||||
all: $(ISO_IMAGE)
|
||||
|
||||
# Ensure build directories exist
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
mkdir -p $(BUILD_DIR)/cli_apps
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
# Download Limine Binaries via Git
|
||||
limine-setup:
|
||||
@if [ ! -f limine/limine-bios.sys ]; then \
|
||||
echo "Limine binaries missing or invalid. Cloning v$(LIMINE_VERSION)-binary..."; \
|
||||
rm -rf limine; \
|
||||
git clone https://github.com/limine-bootloader/limine.git --branch=v$(LIMINE_VERSION)-binary --depth=1 limine; \
|
||||
fi
|
||||
@if [ ! -f $(SRC_DIR)/limine.h ]; then \
|
||||
@if [ ! -f $(SRC_DIR)/core/limine.h ]; then \
|
||||
echo "Copying limine.h..."; \
|
||||
cp limine/limine.h $(SRC_DIR)/limine.h; \
|
||||
cp limine/limine.h $(SRC_DIR)/core/limine.h; \
|
||||
fi
|
||||
@echo "Building Limine host utility..."; \
|
||||
$(MAKE) -C limine
|
||||
|
||||
# Compile C Sources
|
||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) limine-setup
|
||||
mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# Compile CLI Apps C Sources
|
||||
$(BUILD_DIR)/cli_apps/%.o: $(SRC_DIR)/cli_apps/%.c | $(BUILD_DIR) limine-setup
|
||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/core/%.c | $(BUILD_DIR) limine-setup
|
||||
mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# Assemble ASM Sources
|
||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm | $(BUILD_DIR)
|
||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/sys/%.c | $(BUILD_DIR) limine-setup
|
||||
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 $@
|
||||
|
||||
# Link Kernel
|
||||
$(KERNEL_ELF): $(OBJ_FILES)
|
||||
$(LD) $(LDFLAGS) -o $@ $(OBJ_FILES)
|
||||
$(MAKE) -C $(SRC_DIR)/userland
|
||||
|
||||
# Create ISO
|
||||
$(ISO_IMAGE): $(KERNEL_ELF) limine.cfg limine-setup
|
||||
$(ISO_IMAGE): $(KERNEL_ELF) limine.conf limine-setup
|
||||
rm -rf $(ISO_DIR)
|
||||
mkdir -p $(ISO_DIR)
|
||||
mkdir -p $(ISO_DIR)/EFI/BOOT
|
||||
|
||||
# Copy Kernel and Config
|
||||
cp $(KERNEL_ELF) $(ISO_DIR)/
|
||||
cp limine.cfg $(ISO_DIR)/
|
||||
cp limine.conf $(ISO_DIR)/
|
||||
mkdir -p $(ISO_DIR)/bin
|
||||
@for f in $(SRC_DIR)/userland/bin/*.elf; do \
|
||||
if [ -f "$$f" ]; then \
|
||||
basename=$$(basename "$$f"); \
|
||||
cp "$$f" $(ISO_DIR)/bin/; \
|
||||
echo " module_path: boot():/bin/$$basename" >> $(ISO_DIR)/limine.conf; \
|
||||
fi \
|
||||
done
|
||||
|
||||
# Copy README
|
||||
cp README.md $(ISO_DIR)/
|
||||
@if [ -f README.md ]; then cp README.md $(ISO_DIR)/; fi
|
||||
@if [ -f $(SRC_DIR)/userland/games/doom/doom1.wad ]; then \
|
||||
mkdir -p $(ISO_DIR)/Library/DOOM; \
|
||||
cp $(SRC_DIR)/userland/games/doom/doom1.wad $(ISO_DIR)/Library/DOOM/; \
|
||||
echo " module_path: boot():/Library/DOOM/doom1.wad" >> $(ISO_DIR)/limine.conf; \
|
||||
fi
|
||||
|
||||
# Copy user file.c if it exists
|
||||
@if [ -f file.c ]; then cp file.c $(ISO_DIR)/; fi
|
||||
mkdir -p $(ISO_DIR)/Library/images/Wallpapers
|
||||
@for f in $(SRC_DIR)/images/wallpapers/*; do \
|
||||
if [ -f "$$f" ]; then \
|
||||
basename=$$(basename "$$f"); \
|
||||
cp "$$f" $(ISO_DIR)/Library/images/Wallpapers/; \
|
||||
echo " module_path: boot():/Library/images/Wallpapers/$$basename" >> $(ISO_DIR)/limine.conf; \
|
||||
fi \
|
||||
done
|
||||
@if [ -f splash.jpg ]; then cp splash.jpg $(ISO_DIR)/; fi
|
||||
|
||||
# Copy Wallpaper (if it exists)
|
||||
@if [ -f src/kernel/wallpaper.ppm ]; then cp src/kernel/wallpaper.ppm $(ISO_DIR)/; fi
|
||||
mkdir -p $(ISO_DIR)/Library/images/gif
|
||||
@for f in $(SRC_DIR)/images/gif/*.gif; do \
|
||||
if [ -f "$$f" ]; then \
|
||||
basename=$$(basename "$$f"); \
|
||||
cp "$$f" $(ISO_DIR)/Library/images/gif/; \
|
||||
echo " module_path: boot():/Library/images/gif/$$basename" >> $(ISO_DIR)/limine.conf; \
|
||||
fi \
|
||||
done
|
||||
|
||||
mkdir -p $(ISO_DIR)/docs
|
||||
@for f in $$(find docs -name '*.md'); do \
|
||||
if [ -f "$$f" ]; then \
|
||||
dir=$$(dirname "$$f"); \
|
||||
mkdir -p $(ISO_DIR)/"$$dir"; \
|
||||
cp "$$f" $(ISO_DIR)/"$$dir"/; \
|
||||
echo " module_path: boot():/$$f" >> $(ISO_DIR)/limine.conf; \
|
||||
fi \
|
||||
done
|
||||
|
||||
# Copy Limine Bootloader Files (flat structure in binary branch)
|
||||
cp limine/limine-bios.sys $(ISO_DIR)/
|
||||
cp limine/limine-bios-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/BOOTIA32.EFI $(ISO_DIR)/EFI/BOOT/
|
||||
|
||||
# Generate ISO
|
||||
$(XORRISO) -as mkisofs -b limine-bios-cd.bin \
|
||||
mkdir -p $(ISO_DIR)/Library/Fonts
|
||||
@for f in $(SRC_DIR)/fonts/*.ttf; do \
|
||||
if [ -f "$$f" ]; then \
|
||||
basename=$$(basename "$$f"); \
|
||||
cp "$$f" $(ISO_DIR)/Library/Fonts/; \
|
||||
echo " module_path: boot():/Library/Fonts/$$basename" >> $(ISO_DIR)/limine.conf; \
|
||||
fi \
|
||||
done
|
||||
|
||||
@if [ -f README.md ]; then \
|
||||
cp README.md $(ISO_DIR)/; \
|
||||
echo " module_path: boot():/README.md" >> $(ISO_DIR)/limine.conf; \
|
||||
fi
|
||||
|
||||
@if [ -f LICENSE ]; then \
|
||||
cp LICENSE $(ISO_DIR)/; \
|
||||
echo " module_path: boot():/LICENSE" >> $(ISO_DIR)/limine.conf; \
|
||||
fi
|
||||
|
||||
$(XORRISO) -as mkisofs -R -J -b limine-bios-cd.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
--efi-boot limine-uefi-cd.bin \
|
||||
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
||||
$(ISO_DIR) -o $(ISO_IMAGE)
|
||||
|
||||
# Install Limine to ISO (for BIOS boot)
|
||||
./limine/limine bios-install $(ISO_IMAGE)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(ISO_DIR) $(ISO_IMAGE)
|
||||
$(MAKE) -C $(SRC_DIR)/userland clean
|
||||
|
||||
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 \
|
||||
-netdev user,id=net0,hostfwd=udp::12345-:12345 -device e1000,netdev=net0 \
|
||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080
|
||||
-netdev user,id=net0,hostfwd=udp::12346-:12345 -device virtio-net-pci,netdev=net0 \
|
||||
-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.
|
||||
117
README.md
117
README.md
@@ -1,109 +1,45 @@
|
||||
# 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.
|
||||
# BoredOS
|
||||
|
||||
## 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.
|
||||
<div align="center">
|
||||
<img src="boredos.svg" alt="BoredOS Logo" width="450" />
|
||||
</div>
|
||||
BoredOS is a simple x86_64 hobbyist operating system.
|
||||
It features a DE (and WM), a FAT32 filesystem, customizable UI and much much more!
|
||||
|
||||

|
||||
*this screenshot might be outdated*
|
||||
|
||||
## Features
|
||||
- userspace
|
||||
- JPG image support
|
||||
- Disk manager
|
||||
- Drag and drop mouse centered UI
|
||||
- Customizable UI
|
||||
- Basic Networking Stack
|
||||
- Brew WM
|
||||
- Fat 32 FS
|
||||
- Bored WM
|
||||
- FAT32 filesystem
|
||||
- 64-bit long mode support
|
||||
- Multiboot2 compliant
|
||||
- Text editor
|
||||
- Markdown Viewer
|
||||
- Minesweeper
|
||||
- Markdown Viewer
|
||||
- GUI Text editor
|
||||
- Paint application
|
||||
- IDT
|
||||
- Ability to run on actual x86_64 hardware
|
||||
- CLI
|
||||
- (Limited) C Compiler
|
||||
|
||||
## Prerequisites
|
||||
## Documentation
|
||||
|
||||
To build BrewOS, you'll need the following tools installed:
|
||||
BoredOS has comprehensive documentation available in the [`docs/`](docs/) directory covering architecture, the build system, and application development SDKs.
|
||||
|
||||
- **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
|
||||
- **[Index / Table of Contents](docs/README.md)**
|
||||
- **[Architecture Overview](docs/architecture/core.md)**
|
||||
- **[Building and Running](docs/build/usage.md)**
|
||||
- **[Application Development Guide](docs/appdev/custom_apps.md)**
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -126,6 +62,11 @@ qemu-system-x86_64 -m 2G -serial stdio -cdrom brewos.iso -boot d
|
||||
###
|
||||
|
||||
|
||||
## This project was previously labeled as "BrewKernel"
|
||||
Brewkernel was a text only very simple (and messy) project i started 3 years ago. It was my first work in OSDev and i absolutely loved it. It sadly just got too messy and i myself couldn't understand my own code anymore. About a year ago i started work on BoredOS, and pushed a *"working"* version of it a few days ago as of writing this *(Feb. 10 2026)*
|
||||
Brewkernel has already been deprecated and will not be accepting any pull requests or fix any issues as it is now a public archive.
|
||||
Thanks to everyone who helped me with Brewkernel, even if it were just ideas, and intend to keep working on this for the forseeable future!
|
||||
|
||||
## License
|
||||
|
||||
Copyright (C) 2024-2026 boreddevnl
|
||||
@@ -135,7 +76,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
NOTICE
|
||||
------
|
||||
|
||||
This product includes software developed by Chris ("boreddevnl") as part of the BrewKernel project.
|
||||
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)
|
||||
|
||||
|
||||
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 500 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.
25
docs/README.md
Normal file
25
docs/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# BoredOS Documentation
|
||||
|
||||
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.
|
||||
78
docs/appdev/custom_apps.md
Normal file
78
docs/appdev/custom_apps.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Creating a Custom App (Step-by-Step)
|
||||
|
||||
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.
|
||||
|
||||
## 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>
|
||||
|
||||
int main(void) {
|
||||
// Attempt to open a 300x200 window
|
||||
int wid = ui_create_window("My Custom App", 300, 200, 0);
|
||||
if (wid < 0) {
|
||||
printf("Error creating window!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Write text in center
|
||||
ui_draw_string(wid, "Hello, BoredOS!!", 50, 90, 0xFFFFFFFF);
|
||||
|
||||
// Commit drawing to screen
|
||||
ui_swap_buffers(wid);
|
||||
|
||||
ui_event_t event;
|
||||
while (1) {
|
||||
if (ui_poll_event(&event)) {
|
||||
if (event.window_id == wid && event.type == UI_EVENT_WINDOW_CLOSE) {
|
||||
break; // Exit loop if 'X' is clicked
|
||||
}
|
||||
}
|
||||
|
||||
syscall1(SYSTEM_CMD_YIELD, 0);
|
||||
}
|
||||
|
||||
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!
|
||||
|
||||
*you can also open your app by opening the file explorer and navigating to the bin directory and double clicking the executable.*
|
||||
36
docs/appdev/sdk_reference.md
Normal file
36
docs/appdev/sdk_reference.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Userland SDK Reference
|
||||
|
||||
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.
|
||||
|
||||
## The Custom libc Structure (`src/userland/libc/`)
|
||||
|
||||
The SDK comprises a few key files containing wrappers around kernel system calls:
|
||||
|
||||
- `stdlib.h` / `stdlib.c`: Memory allocation (`malloc`, `free`), integer conversion (`itoa`, `atoi`), printing (`printf`, `sprintf`), and random numbers (`rand`, `srand`).
|
||||
- `string.h` / `string.c`: String manipulation utilities (`strlen`, `strcpy`, `strcmp`, `memset`, `memcpy`).
|
||||
- `syscall.h` / `syscall.c`: The raw interface to issue `syscall` assembly instructions, routing requests to the kernel.
|
||||
- `libui.h` / `libui.c`: Graphical interface commands (creating windows, drawing pixels, events).
|
||||
|
||||
## System Calls Overview
|
||||
|
||||
When a userland application wants to interact with the hardware (print to screen, read a file, create a window), it must ask the kernel via a **System Call**.
|
||||
|
||||
In BoredOS (`x86_64`), system calls are issued using the `syscall` instruction. The kernel intercepts this instruction and inspects the processor's RAX register to figure out *what* the application wants to do.
|
||||
|
||||
The custom `libc` provides `syscallX` wrapper functions that abstract the assembly details:
|
||||
```c
|
||||
// Example: Performing a minimal system call from userland
|
||||
int sys_write(int fd, const char *buf, int len) {
|
||||
return syscall3(SYS_WRITE, fd, (uint64_t)buf, len);
|
||||
}
|
||||
```
|
||||
|
||||
### Notable System Calls
|
||||
|
||||
- **`SYS_WRITE` (1)**: Currently acts as a generic output mechanism for `printf`, typically routing text to the kernel's serial output for debugging, or to an active text-mode console.
|
||||
- **`SYS_GUI` (3)**: The primary multiplexer for all window manager operations. The arguments define subcommands (like `UI_CREATE_WINDOW`, `UI_FILL_RECT`).
|
||||
- **`SYS_FS` (4)**: Interacts with the virtual filesystem (e.g., `FS_CMD_OPEN`, `FS_CMD_READ`). Under the hood, this reads from the loaded RAMFS or an attached physical ATA disk via the native FAT32 driver.
|
||||
- **`SYS_EXIT` (60)**: Terminates the current process and returns control to the kernel.
|
||||
- **`SYSTEM_CMD_YIELD` (43)**: Instructs the process scheduler to pause the current process and let another process run.
|
||||
|
||||
If you are developing a new application, **do not invoke syscalls manually**. Instead, include `stdlib.h` and use the C functions provided.
|
||||
85
docs/appdev/ui_api.md
Normal file
85
docs/appdev/ui_api.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# UI API (`libui.h`)
|
||||
|
||||
For an application to be visible on the screen, it must interact with the BoredOS Window Manager (WM). The tools required for this are located in `src/userland/libc/libui.h` and `libui.c`.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
The UI library sends requests (via `SYS_GUI`) to the kernel to reserve an area on the screen (a `Window`) and then issues commands to color specific pixels within that area. The kernel is responsible for compositing this area over other windows.
|
||||
|
||||
## Example: Creating a Window
|
||||
|
||||
First, include the library and define an event structure:
|
||||
|
||||
```c
|
||||
#include <libui.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void) {
|
||||
// 1. Create the window
|
||||
// Arguments: Title, Width, Height, Flags (e.g. 0 for bordered window)
|
||||
int window_id = ui_create_window("Hello World App", 400, 300, 0);
|
||||
|
||||
if (window_id < 0) {
|
||||
printf("Failed to create window!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ... Event loop will go here ...
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Drawing Primitives
|
||||
|
||||
The library offers functions to mutate the window's internal buffer. After issuing drawing commands, you **must** instruct the kernel to push the changes onto the screen.
|
||||
|
||||
```c
|
||||
// Fill the entire window with a solid blue background
|
||||
// Arguments: Window ID, X, Y, Width, Height, ARGB Color value
|
||||
ui_fill_rect(window_id, 0, 0, 400, 300, 0xFF0000FF);
|
||||
|
||||
// Tell the kernel to commit the drawing commands to the screen
|
||||
ui_swap_buffers(window_id);
|
||||
```
|
||||
|
||||
Available rendering methods:
|
||||
- `ui_fill_rect(id, x, y, w, h, color)`: Draw a solid rectangle.
|
||||
- `ui_draw_rect(id, x, y, w, h, color)`: Draw an outline of a rectangle.
|
||||
- `ui_draw_line(id, x0, y0, x1, y1, color)`: Bresenham line algorithm.
|
||||
- `ui_draw_string(id, string, x, y, color)`: Render text using the kernel's built-in font.
|
||||
- `ui_update_region(id, x, y, w, h)`: A targeted version of `ui_swap_buffers` that only updates a specific area, saving performance.
|
||||
|
||||
## Handling the Event Loop
|
||||
|
||||
Graphical applications are event-driven. They stay alive inside a `while (1)` loop, periodically asking the kernel if the user clicked the mouse or pressed a key inside their window.
|
||||
|
||||
```c
|
||||
ui_event_t event;
|
||||
|
||||
// Main UI Loop
|
||||
while (1) {
|
||||
// ui_poll_event is non-blocking. It returns 1 if an event occurred, 0 otherwise.
|
||||
if (ui_poll_event(&event)) {
|
||||
|
||||
// The WM dispatch sets event.window_id
|
||||
// We only care about events meant for our specific window
|
||||
if (event.window_id == window_id) {
|
||||
|
||||
if (event.type == UI_EVENT_MOUSE_DOWN) {
|
||||
printf("User clicked at X:%d Y:%d\n", event.mouse_x, event.mouse_y);
|
||||
|
||||
// Respond visually to the click
|
||||
ui_fill_rect(window_id, event.mouse_x, event.mouse_y, 10, 10, 0xFFFF0000); // Red dot
|
||||
ui_swap_buffers(window_id);
|
||||
}
|
||||
else if (event.type == UI_EVENT_WINDOW_CLOSE) {
|
||||
// Start tearing down the application safely
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent 100% CPU usage by yielding execution time back to the OS scheduler
|
||||
syscall1(SYSTEM_CMD_YIELD, 0);
|
||||
}
|
||||
```
|
||||
39
docs/architecture/core.md
Normal file
39
docs/architecture/core.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Core Architecture
|
||||
|
||||
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, parsing userland binaries and setting them up for execution.
|
||||
- **`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 Protocol**: The kernel expects the Limine boot protocol (which is compatible with modern Multiboot specifications). Passing a framebuffer and memory map is handled natively by Limine's request structures (defined locally via `limine.h`).
|
||||
3. **Kernel Entry (`main.c`)**: The entry point `_start` is called. It immediately initializes the serial port for debugging, sets up core structures (GDT/IDT), initializes the physical memory manager based on the Limine memory map, and starts the virtual memory manager.
|
||||
4. **Driver Initialization**: PCI buses are scanned, finding the network card or disk controllers. The filesystem is mounted.
|
||||
5. **Window Manager**: The UI is drawn on top of the Limine-provided framebuffer.
|
||||
|
||||
## Userland Transition
|
||||
|
||||
The OS supports privilege separation (Ring 0 vs. Ring 3). When an application (like `browser.elf` or `viewer.elf`) is launched, the kernel:
|
||||
1. Loads the ELF file from the filesystem using the ELF parser in `sys/elf.c`.
|
||||
2. Allocates a new virtual address space (Page Directory) for the process.
|
||||
3. Maps the executable segments according to the ELF headers.
|
||||
4. Switches to User Mode (Ring 3) via the `iretq` instruction, jumping into the application's entry point (`crt0.asm`).
|
||||
|
||||
Programs then interact with the core kernel using system calls (`syscall.c`).
|
||||
28
docs/architecture/filesystem.md
Normal file
28
docs/architecture/filesystem.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Filesystem Architecture
|
||||
|
||||
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.
|
||||
|
||||
## FAT32 Implementation
|
||||
|
||||
The primary filesystem logic in `fat32.c` has a dual nature, supporting both an in-memory RAM filesystem for booting and standard block devices for external storage.
|
||||
|
||||
### Booting and the RAMFS
|
||||
Since BoredOS boots from a CD-ROM ISO image generated by `xorriso`, it does not read directly off the CD to execute applications.
|
||||
1. **ISO Booting**: During boot, Limine loads necessary files (such as userland `.elf` binaries, fonts, and wallpapers) into memory as standard boot modules.
|
||||
2. **RAM Simulation**: The FAT32 filesystem code parses these loaded memory modules and automatically constructs a synthetic FAT32 directory tree inside RAM.
|
||||
3. **Root Filesystem**: All active execution of built-in GUI and CLI apps occurs off this read-only, in-memory FAT32 simulation.
|
||||
|
||||
### ATA Disk Support
|
||||
Beyond the core RAMFS used for booting, the FAT32 implementation natively supports interacting with permanent storage:
|
||||
1. **ATA Block Driver**: The kernel features an ATA block device driver capable of communicating with physical hard disks (or raw disk images attached via QEMU).
|
||||
2. **Partition Compatibility**: The driver can recognize and natively mount external ATA disks formatted as single FAT32 filesystems or structured with a Master Boot Record (MBR) partition table.
|
||||
3. **VFS Integration**: When external storage is mounted, the VFS delegates operations down directly to the FAT32 driver, which will read native sectors across the ATA interface.
|
||||
23
docs/architecture/memory.md
Normal file
23
docs/architecture/memory.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Memory Management
|
||||
|
||||
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.
|
||||
|
||||
## 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`). This ensures the kernel remains mapped and accessible regardless of which user process is currently active.
|
||||
- **User Space**: Userland applications are loaded into lower virtual addresses (starting frequently around `0x40000000`).
|
||||
- **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 (e.g., for stack growth or lazy loading) or terminate the process for a segmentation fault.
|
||||
|
||||
## 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 using the VMM.
|
||||
33
docs/architecture/window_manager.md
Normal file
33
docs/architecture/window_manager.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Window Manager (WM)
|
||||
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
## Userland API (`libui.c`)
|
||||
|
||||
Applications do not talk to the hardware directly. Instead, they use a library (`libui.c`) which makes specialized system calls (`SYS_GUI`).
|
||||
|
||||
- **Window Creation**: `ui_create_window()` asks the kernel to instantiate a new window object and returns a handle.
|
||||
- **Drawing**: Applications can request the kernel to fill rectangles or plot pixels inside their designated window area.
|
||||
- **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.
|
||||
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*)
|
||||
}
|
||||
|
||||
.requests : {
|
||||
KEEP(*(.requests_start))
|
||||
KEEP(*(.requests))
|
||||
KEEP(*(.requests_end))
|
||||
}
|
||||
|
||||
.data : {
|
||||
*(.data*)
|
||||
}
|
||||
@@ -24,14 +30,6 @@ SECTIONS
|
||||
*(.bss*)
|
||||
}
|
||||
|
||||
/* Limine requests section */
|
||||
.requests : {
|
||||
KEEP(*(.requests_start))
|
||||
KEEP(*(.requests))
|
||||
KEEP(*(.requests_end))
|
||||
}
|
||||
|
||||
/* Discard unnecessary sections */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.note .note.*)
|
||||
|
||||
BIN
screenshot.jpg
Normal file
BIN
screenshot.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 317 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
|
||||
191
src/arch/interrupts.asm
Normal file
191
src/arch/interrupts.asm
Normal file
@@ -0,0 +1,191 @@
|
||||
; 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
|
||||
extern timer_handler
|
||||
extern keyboard_handler
|
||||
extern mouse_handler
|
||||
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
|
||||
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
|
||||
|
||||
; 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
|
||||
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
|
||||
19
src/arch/test_syscall.asm
Normal file
19
src/arch/test_syscall.asm
Normal file
@@ -0,0 +1,19 @@
|
||||
; 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 test_syscall
|
||||
section .text
|
||||
|
||||
test_syscall:
|
||||
; syscall number in RDI
|
||||
mov rdi, 1
|
||||
; string pointer in RSI
|
||||
lea rsi, [rel test_msg]
|
||||
|
||||
; The SYSCALL instruction
|
||||
syscall
|
||||
|
||||
ret
|
||||
|
||||
section .rodata
|
||||
test_msg: db "Hello from Syscall!", 10, 0
|
||||
25
src/arch/user_test.asm
Normal file
25
src/arch/user_test.asm
Normal file
@@ -0,0 +1,25 @@
|
||||
; 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 user_test_function
|
||||
|
||||
section .text
|
||||
user_test_function:
|
||||
; Syscall convention
|
||||
.loop:
|
||||
; Invoke SYS_WRITE (Syscall #1)
|
||||
mov rdi, 1 ; arg1: fd = 1 (stdout)
|
||||
lea rsi, [rel msg] ; arg2: buffer (RIP-relative)
|
||||
mov rdx, 15 ; arg3: length
|
||||
mov eax, 1 ; syscall_num = 1 (SYS_WRITE)
|
||||
syscall
|
||||
|
||||
; Some delay loop
|
||||
mov rcx, 100000000
|
||||
.delay:
|
||||
dec rcx
|
||||
jnz .delay
|
||||
|
||||
jmp .loop
|
||||
|
||||
msg: db "Hello syscall!", 10
|
||||
2405
src/core/cmd.c
Normal file
2405
src/core/cmd.c
Normal file
File diff suppressed because it is too large
Load Diff
31
src/core/cmd.h
Normal file
31
src/core/cmd.h
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.
|
||||
#ifndef CMD_H
|
||||
#define CMD_H
|
||||
|
||||
#include "wm.h"
|
||||
|
||||
extern Window win_cmd;
|
||||
|
||||
void cmd_init(void);
|
||||
void cmd_reset(void);
|
||||
|
||||
// IO Functions
|
||||
void cmd_write(const char *str);
|
||||
void cmd_putchar(char c);
|
||||
void cmd_write_int(int n);
|
||||
void cmd_write_hex(uint64_t n);
|
||||
int cmd_get_cursor_col(void);
|
||||
void cmd_screen_clear(void);
|
||||
|
||||
void cmd_increment_msg_count(void);
|
||||
void cmd_reset_msg_count(void);
|
||||
|
||||
void cmd_handle_resize(Window *win, int w, int h);
|
||||
void cmd_handle_click(Window *win, int x, int y);
|
||||
|
||||
uint32_t cmd_get_config_value(const char *key);
|
||||
void cmd_set_current_color(uint32_t color);
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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.
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
@@ -11,6 +14,12 @@ static inline void outw(uint16_t port, uint16_t val) {
|
||||
asm volatile ("outw %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
|
||||
static inline uint16_t inw(uint16_t port) {
|
||||
uint16_t ret;
|
||||
asm volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint8_t inb(uint16_t port) {
|
||||
uint8_t ret;
|
||||
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
126
src/core/kutils.c
Normal file
126
src/core/kutils.c
Normal file
@@ -0,0 +1,126 @@
|
||||
// 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.
|
||||
#include "kutils.h"
|
||||
#include "wm.h"
|
||||
#include "io.h"
|
||||
|
||||
void k_memset(void *dest, int val, size_t len) {
|
||||
unsigned char *ptr = (unsigned char *)dest;
|
||||
while (len-- > 0) *ptr++ = (unsigned char)val;
|
||||
}
|
||||
|
||||
void k_memcpy(void *dest, const void *src, size_t len) {
|
||||
unsigned char *d = (unsigned char *)dest;
|
||||
const unsigned char *s = (const unsigned char *)src;
|
||||
while (len-- > 0) *d++ = *s++;
|
||||
}
|
||||
|
||||
size_t k_strlen(const char *str) {
|
||||
size_t len = 0;
|
||||
while (str[len]) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
int k_strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
void k_strcpy(char *dest, const char *src) {
|
||||
while (*src) *dest++ = *src++;
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
int k_atoi(const char *str) {
|
||||
int res = 0;
|
||||
int sign = 1;
|
||||
if (*str == '-') { sign = -1; str++; }
|
||||
while (*str >= '0' && *str <= '9') {
|
||||
res = res * 10 + (*str - '0');
|
||||
str++;
|
||||
}
|
||||
return res * sign;
|
||||
}
|
||||
|
||||
void k_itoa(int n, char *buf) {
|
||||
if (n == 0) {
|
||||
buf[0] = '0'; buf[1] = 0; return;
|
||||
}
|
||||
int i = 0;
|
||||
int sign = n < 0;
|
||||
if (sign) n = -n;
|
||||
while (n > 0) {
|
||||
buf[i++] = (n % 10) + '0';
|
||||
n /= 10;
|
||||
}
|
||||
if (sign) buf[i++] = '-';
|
||||
buf[i] = 0;
|
||||
for (int j = 0; j < i / 2; j++) {
|
||||
char t = buf[j];
|
||||
buf[j] = buf[i - 1 - j];
|
||||
buf[i - 1 - j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void k_itoa_hex(uint64_t n, char *buf) {
|
||||
const char *digits = "0123456789ABCDEF";
|
||||
if (n == 0) {
|
||||
buf[0] = '0';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while (n > 0) {
|
||||
buf[i++] = digits[n & 0xF];
|
||||
n >>= 4;
|
||||
}
|
||||
buf[i] = 0;
|
||||
for (int j = 0; j < i / 2; j++) {
|
||||
char t = buf[j];
|
||||
buf[j] = buf[i - 1 - j];
|
||||
buf[i - 1 - j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void k_delay(int iterations) {
|
||||
for (volatile int i = 0; i < iterations; i++) {
|
||||
__asm__ __volatile__("nop");
|
||||
}
|
||||
}
|
||||
|
||||
void k_sleep(int ms) {
|
||||
// Timer is ~60Hz, so 1 tick = 16.66ms
|
||||
uint32_t ticks = ms / 16;
|
||||
if (ticks == 0 && ms > 0) ticks = 1;
|
||||
|
||||
uint32_t target = wm_get_ticks() + ticks;
|
||||
while (wm_get_ticks() < target) {
|
||||
__asm__ __volatile__("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
void k_reboot(void) {
|
||||
outb(0x64, 0xFE);
|
||||
}
|
||||
|
||||
void k_shutdown(void) {
|
||||
outw(0xB004, 0x2000); // QEMU older / some pc machines
|
||||
outw(0x604, 0x2000); // QEMU newer (i440fx/q35)
|
||||
outw(0x4004, 0x3400); // VirtualBox fallback
|
||||
}
|
||||
|
||||
void k_beep(int freq, int ms) {
|
||||
if (freq <= 0) return;
|
||||
int div = 1193180 / freq;
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, div & 0xFF);
|
||||
outb(0x42, (div >> 8) & 0xFF);
|
||||
outb(0x61, inb(0x61) | 0x03);
|
||||
k_sleep(ms);
|
||||
outb(0x61, inb(0x61) & 0xFC);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user