mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
Merge branch 'main' of https://github.com/boreddevnl/BoredOS
This commit is contained in:
commit
7a480b44b9
2 changed files with 391 additions and 21 deletions
150
Makefile
150
Makefile
|
|
@ -17,6 +17,18 @@ ISO_DIR = iso_root
|
||||||
KERNEL_ELF = $(BUILD_DIR)/boredos.elf
|
KERNEL_ELF = $(BUILD_DIR)/boredos.elf
|
||||||
ISO_IMAGE = boredos.iso
|
ISO_IMAGE = boredos.iso
|
||||||
|
|
||||||
|
BLUE = \033[1;34m
|
||||||
|
GREEN = \033[1;32m
|
||||||
|
YELLOW= \033[1;33m
|
||||||
|
RESET = \033[0m
|
||||||
|
|
||||||
|
define PRINT_STEP
|
||||||
|
@printf ""
|
||||||
|
@printf "\n$(BLUE)============================================================$(RESET)\n"
|
||||||
|
@printf "$(BLUE)== %s$(RESET)\n" "$(1)"
|
||||||
|
@printf "$(BLUE)============================================================$(RESET)\n"
|
||||||
|
endef
|
||||||
|
|
||||||
DOCK_COLLOID_ICONS = $(shell sed -n 's/^[[:space:]]*{"\([^"]*\.png\)",[[:space:]]*DOCK_ICON_UNTRIED.*/\1/p' $(SRC_DIR)/wm/wm.c)
|
DOCK_COLLOID_ICONS = $(shell sed -n 's/^[[:space:]]*{"\([^"]*\.png\)",[[:space:]]*DOCK_ICON_UNTRIED.*/\1/p' $(SRC_DIR)/wm/wm.c)
|
||||||
USERLAND_COLLOID_ICONS = $(shell { \
|
USERLAND_COLLOID_ICONS = $(shell { \
|
||||||
find $(SRC_DIR)/userland -type f -name '*.c' ! -path '*/third_party/*' -exec grep -hoE '"[^"]+\.png"' {} + 2>/dev/null; \
|
find $(SRC_DIR)/userland -type f -name '*.c' ! -path '*/third_party/*' -exec grep -hoE '"[^"]+\.png"' {} + 2>/dev/null; \
|
||||||
|
|
@ -67,89 +79,123 @@ NASMFLAGS = -f elf64
|
||||||
LIMINE_VERSION = 10.8.2
|
LIMINE_VERSION = 10.8.2
|
||||||
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 run-windows run-mac run-linux
|
||||||
|
|
||||||
all: $(ISO_IMAGE)
|
all:
|
||||||
|
$(call PRINT_STEP,STARTING BOREDOS BUILD)
|
||||||
|
$(MAKE) $(ISO_IMAGE)
|
||||||
|
$(call PRINT_STEP,BUILD COMPLETE)
|
||||||
|
|
||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
|
$(call PRINT_STEP,CREATING BUILD DIRECTORY)
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
limine-setup:
|
limine-setup:
|
||||||
|
$(call PRINT_STEP,SETTING UP LIMINE)
|
||||||
@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..."; \
|
printf "$(YELLOW)[LIMINE] Limine binaries missing or invalid. Cloning v$(LIMINE_VERSION)-binary...$(RESET)"; \
|
||||||
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; \
|
||||||
|
else \
|
||||||
|
printf "$(YELLOW)[LIMINE] Existing Limine binaries found.$(RESET)"; \
|
||||||
fi
|
fi
|
||||||
@if [ ! -f $(SRC_DIR)/core/limine.h ]; then \
|
@if [ ! -f $(SRC_DIR)/core/limine.h ]; then \
|
||||||
echo "Copying limine.h..."; \
|
printf "$(YELLOW)[LIMINE] Copying limine.h...$(RESET)"; \
|
||||||
cp limine/limine.h $(SRC_DIR)/core/limine.h; \
|
cp limine/limine.h $(SRC_DIR)/core/limine.h; \
|
||||||
|
else \
|
||||||
|
printf "$(YELLOW)[LIMINE] limine.h already present.$(RESET)"; \
|
||||||
fi
|
fi
|
||||||
@echo "Building Limine host utility..."; \
|
@printf "$(YELLOW)[LIMINE] Building Limine host utility...$(RESET)"
|
||||||
$(MAKE) -C limine
|
$(MAKE) -C limine
|
||||||
|
@printf "$(GREEN)[OK] Limine setup complete.$(RESET)"
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET) $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/core/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/core/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[core] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/sys/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/sys/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[sys] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/mem/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/mem/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[mem] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/dev/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/dev/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[dev] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/input/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/input/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[input] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/net/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/net/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[net] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/net/nic/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/net/nic/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[net/nic] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/fs/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/fs/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[fs] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/wm/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/wm/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[wm] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/lwip/%.o: $(SRC_DIR)/net/third_party/lwip/%.c | $(BUILD_DIR) limine-setup
|
$(BUILD_DIR)/lwip/%.o: $(SRC_DIR)/net/third_party/lwip/%.c | $(BUILD_DIR) limine-setup
|
||||||
|
@printf "$(YELLOW)[CC]$(RESET)[lwIP] $< -> $@"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/arch/%.asm | $(BUILD_DIR)
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/arch/%.asm | $(BUILD_DIR)
|
||||||
|
@printf "$(YELLOW)[ASM]$(RESET) $< -> $@"
|
||||||
$(NASM) $(NASMFLAGS) $< -o $@
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/test_syscall.o: $(SRC_DIR)/arch/test_syscall.asm | $(BUILD_DIR)
|
$(BUILD_DIR)/test_syscall.o: $(SRC_DIR)/arch/test_syscall.asm | $(BUILD_DIR)
|
||||||
|
@printf "$(YELLOW)[ASM][test_syscall]$(RESET) $< -> $@"
|
||||||
$(NASM) $(NASMFLAGS) $< -o $@
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/user_test.o: $(SRC_DIR)/arch/user_test.asm | $(BUILD_DIR)
|
$(BUILD_DIR)/user_test.o: $(SRC_DIR)/arch/user_test.asm | $(BUILD_DIR)
|
||||||
|
@printf "$(YELLOW)[ASM][user_test]$(RESET) $< -> $@"
|
||||||
$(NASM) $(NASMFLAGS) $< -o $@
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/process_asm.o: $(SRC_DIR)/arch/process_asm.asm | $(BUILD_DIR)
|
$(BUILD_DIR)/process_asm.o: $(SRC_DIR)/arch/process_asm.asm | $(BUILD_DIR)
|
||||||
|
@printf "$(YELLOW)[ASM][process]$(RESET) $< -> $@"
|
||||||
$(NASM) $(NASMFLAGS) $< -o $@
|
$(NASM) $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
$(KERNEL_ELF): $(OBJ_FILES)
|
$(KERNEL_ELF): $(OBJ_FILES)
|
||||||
|
$(call PRINT_STEP,LINKING KERNEL)
|
||||||
|
@printf "$(YELLOW)[LD]$(RESET) Linking kernel ELF: $@"
|
||||||
$(LD) $(LDFLAGS) -o $@ $(OBJ_FILES)
|
$(LD) $(LDFLAGS) -o $@ $(OBJ_FILES)
|
||||||
|
@printf "$(GREEN)[OK]$(RESET) Kernel ELF built: $@"
|
||||||
|
$(call PRINT_STEP,BUILDING USERLAND)
|
||||||
$(MAKE) -C $(SRC_DIR)/userland
|
$(MAKE) -C $(SRC_DIR)/userland
|
||||||
|
@printf "$(GREEN)[OK]$(RESET) Userland build complete."
|
||||||
|
|
||||||
$(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
|
$(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
|
||||||
|
$(call PRINT_STEP,BUILDING INITRD)
|
||||||
|
@printf "$(YELLOW)[INITRD]$(RESET) Cleaning previous initrd directory..."
|
||||||
rm -rf $(BUILD_DIR)/initrd
|
rm -rf $(BUILD_DIR)/initrd
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[INITRD]$(RESET) Creating directory structure..."
|
||||||
mkdir -p $(BUILD_DIR)/initrd/bin
|
mkdir -p $(BUILD_DIR)/initrd/bin
|
||||||
mkdir -p $(BUILD_DIR)/initrd/Library/images/Wallpapers
|
mkdir -p $(BUILD_DIR)/initrd/Library/images/Wallpapers
|
||||||
mkdir -p $(BUILD_DIR)/initrd/Library/images/gif
|
mkdir -p $(BUILD_DIR)/initrd/Library/images/gif
|
||||||
|
|
@ -159,81 +205,142 @@ $(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
|
||||||
mkdir -p $(BUILD_DIR)/initrd/Library/bsh
|
mkdir -p $(BUILD_DIR)/initrd/Library/bsh
|
||||||
mkdir -p $(BUILD_DIR)/initrd/docs
|
mkdir -p $(BUILD_DIR)/initrd/docs
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Userland binaries..."
|
||||||
@for f in $(SRC_DIR)/userland/bin/*.elf; do \
|
@for f in $(SRC_DIR)/userland/bin/*.elf; do \
|
||||||
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/bin/; fi \
|
if [ -f "$$f" ]; then \
|
||||||
|
printf " -> $$f"; \
|
||||||
|
cp "$$f" $(BUILD_DIR)/initrd/bin/; \
|
||||||
|
fi \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Wallpapers..."
|
||||||
@for f in $(SRC_DIR)/images/wallpapers/*; do \
|
@for f in $(SRC_DIR)/images/wallpapers/*; do \
|
||||||
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/images/Wallpapers/; fi \
|
if [ -f "$$f" ]; then \
|
||||||
|
printf " -> $$f"; \
|
||||||
|
cp "$$f" $(BUILD_DIR)/initrd/Library/images/Wallpapers/; \
|
||||||
|
fi \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) GIF assets..."
|
||||||
@for f in $(SRC_DIR)/images/gif/*.gif; do \
|
@for f in $(SRC_DIR)/images/gif/*.gif; do \
|
||||||
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/images/gif/; fi \
|
if [ -f "$$f" ]; then \
|
||||||
|
printf " -> $$f"; \
|
||||||
|
cp "$$f" $(BUILD_DIR)/initrd/Library/images/gif/; \
|
||||||
|
fi \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Colloid icons..."
|
||||||
@for f in $(COLLOID_ICONS); do \
|
@for f in $(COLLOID_ICONS); do \
|
||||||
src="$(SRC_DIR)/images/icons/colloid/$$f"; \
|
src="$(SRC_DIR)/images/icons/colloid/$$f"; \
|
||||||
if [ -f "$$src" ]; then cp "$$src" $(BUILD_DIR)/initrd/Library/images/icons/colloid/; fi \
|
if [ -f "$$src" ]; then \
|
||||||
|
printf " -> $$src"; \
|
||||||
|
cp "$$src" $(BUILD_DIR)/initrd/Library/images/icons/colloid/; \
|
||||||
|
fi \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Fonts..."
|
||||||
@for f in $(SRC_DIR)/fonts/*.ttf; do \
|
@for f in $(SRC_DIR)/fonts/*.ttf; do \
|
||||||
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/Fonts/; fi \
|
if [ -f "$$f" ]; then \
|
||||||
|
printf " -> $$f"; \
|
||||||
|
cp "$$f" $(BUILD_DIR)/initrd/Library/Fonts/; \
|
||||||
|
fi \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Emoji fonts..."
|
||||||
@for f in $(SRC_DIR)/fonts/Emoji/*.ttf; do \
|
@for f in $(SRC_DIR)/fonts/Emoji/*.ttf; do \
|
||||||
if [ -f "$$f" ]; then cp "$$f" $(BUILD_DIR)/initrd/Library/Fonts/Emoji/; fi \
|
if [ -f "$$f" ]; then \
|
||||||
|
printf " -> $$f"; \
|
||||||
|
cp "$$f" $(BUILD_DIR)/initrd/Library/Fonts/Emoji/; \
|
||||||
|
fi \
|
||||||
done
|
done
|
||||||
@if [ -f $(SRC_DIR)/library/bsh/bshrc ]; then cp $(SRC_DIR)/library/bsh/bshrc $(BUILD_DIR)/initrd/Library/bsh/; fi
|
|
||||||
@if [ -f $(SRC_DIR)/library/bsh/startup.bsh ]; then cp $(SRC_DIR)/library/bsh/startup.bsh $(BUILD_DIR)/initrd/Library/bsh/; fi
|
@printf "$(YELLOW)[COPY]$(RESET) bsh configuration..."
|
||||||
@if [ -f $(SRC_DIR)/library/bsh/boot.bsh ]; then cp $(SRC_DIR)/library/bsh/boot.bsh $(BUILD_DIR)/initrd/Library/bsh/; fi
|
@if [ -f $(SRC_DIR)/library/bsh/bshrc ]; then printf " -> bshrc"; cp $(SRC_DIR)/library/bsh/bshrc $(BUILD_DIR)/initrd/Library/bsh/; fi
|
||||||
@if [ -f $(SRC_DIR)/userland/games/doom/doom1.wad ]; then cp $(SRC_DIR)/userland/games/doom/doom1.wad $(BUILD_DIR)/initrd/Library/DOOM/; fi
|
@if [ -f $(SRC_DIR)/library/bsh/startup.bsh ]; then printf " -> startup.bsh"; cp $(SRC_DIR)/library/bsh/startup.bsh $(BUILD_DIR)/initrd/Library/bsh/; fi
|
||||||
|
@if [ -f $(SRC_DIR)/library/bsh/boot.bsh ]; then printf " -> boot.bsh"; cp $(SRC_DIR)/library/bsh/boot.bsh $(BUILD_DIR)/initrd/Library/bsh/; fi
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) DOOM assets..."
|
||||||
|
@if [ -f $(SRC_DIR)/userland/games/doom/doom1.wad ]; then printf " -> doom1.wad"; cp $(SRC_DIR)/userland/games/doom/doom1.wad $(BUILD_DIR)/initrd/Library/DOOM/; fi
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Documentation..."
|
||||||
@for f in $$(find docs -name '*.md' 2>/dev/null); do \
|
@for f in $$(find docs -name '*.md' 2>/dev/null); do \
|
||||||
if [ -f "$$f" ]; then \
|
if [ -f "$$f" ]; then \
|
||||||
|
printf " -> $$f"; \
|
||||||
dir=$$(dirname "$$f"); \
|
dir=$$(dirname "$$f"); \
|
||||||
mkdir -p $(BUILD_DIR)/initrd/"$$dir"; \
|
mkdir -p $(BUILD_DIR)/initrd/"$$dir"; \
|
||||||
cp "$$f" $(BUILD_DIR)/initrd/"$$dir"/; \
|
cp "$$f" $(BUILD_DIR)/initrd/"$$dir"/; \
|
||||||
fi \
|
fi \
|
||||||
done
|
done
|
||||||
@if [ -f README.md ]; then cp README.md $(BUILD_DIR)/initrd/; fi
|
|
||||||
@if [ -f LICENSE ]; then cp LICENSE $(BUILD_DIR)/initrd/; fi
|
|
||||||
@if [ -f limine.conf ]; then cp limine.conf $(BUILD_DIR)/initrd/; fi
|
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Root files..."
|
||||||
|
@if [ -f README.md ]; then printf " -> README.md"; cp README.md $(BUILD_DIR)/initrd/; fi
|
||||||
|
@if [ -f LICENSE ]; then printf " -> LICENSE"; cp LICENSE $(BUILD_DIR)/initrd/; fi
|
||||||
|
@if [ -f limine.conf ]; then printf " -> limine.conf"; cp limine.conf $(BUILD_DIR)/initrd/; fi
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[TAR]$(RESET) Creating initrd.tar..."
|
||||||
cd $(BUILD_DIR)/initrd && COPYFILE_DISABLE=1 tar --exclude="._*" -cf ../initrd.tar *
|
cd $(BUILD_DIR)/initrd && COPYFILE_DISABLE=1 tar --exclude="._*" -cf ../initrd.tar *
|
||||||
|
@printf "$(GREEN)[OK]$(RESET) Initrd created: $(BUILD_DIR)/initrd.tar"
|
||||||
|
|
||||||
$(ISO_IMAGE): $(KERNEL_ELF) $(BUILD_DIR)/initrd.tar limine.conf limine-setup
|
$(ISO_IMAGE): $(KERNEL_ELF) $(BUILD_DIR)/initrd.tar limine.conf limine-setup
|
||||||
|
$(call PRINT_STEP,CREATING ISO IMAGE)
|
||||||
|
@printf "$(YELLOW)[ISO]$(RESET) Cleaning previous ISO root..."
|
||||||
rm -rf $(ISO_DIR)
|
rm -rf $(ISO_DIR)
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[ISO]$(RESET) Creating ISO directory structure..."
|
||||||
mkdir -p $(ISO_DIR)
|
mkdir -p $(ISO_DIR)
|
||||||
mkdir -p $(ISO_DIR)/EFI/BOOT
|
mkdir -p $(ISO_DIR)/EFI/BOOT
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Kernel ELF..."
|
||||||
cp $(KERNEL_ELF) $(ISO_DIR)/
|
cp $(KERNEL_ELF) $(ISO_DIR)/
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Limine config..."
|
||||||
cp limine.conf $(ISO_DIR)/
|
cp limine.conf $(ISO_DIR)/
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Initrd..."
|
||||||
cp $(BUILD_DIR)/initrd.tar $(ISO_DIR)/
|
cp $(BUILD_DIR)/initrd.tar $(ISO_DIR)/
|
||||||
echo " module_path: boot():/initrd.tar" >> $(ISO_DIR)/limine.conf
|
|
||||||
|
|
||||||
@if [ -f splash.jpg ]; then cp splash.jpg $(ISO_DIR)/; fi
|
@printf "$(YELLOW)[CONFIG]$(RESET) Adding initrd module path..."
|
||||||
|
printf " module_path: boot():/initrd.tar" >> $(ISO_DIR)/limine.conf
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Optional splash image..."
|
||||||
|
@if [ -f splash.jpg ]; then printf " -> splash.jpg"; cp splash.jpg $(ISO_DIR)/; else printf " -> no splash.jpg found"; fi
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) Limine boot files..."
|
||||||
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)/
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[COPY]$(RESET) EFI bootloaders..."
|
||||||
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/
|
||||||
|
|
||||||
|
$(call PRINT_STEP,GENERATING BOOTABLE ISO)
|
||||||
$(XORRISO) -as mkisofs -R -J -b limine-bios-cd.bin \
|
$(XORRISO) -as mkisofs -R -J -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)
|
||||||
|
|
||||||
|
@printf "$(YELLOW)[LIMINE]$(RESET) Installing BIOS bootloader..."
|
||||||
./limine/limine bios-install $(ISO_IMAGE)
|
./limine/limine bios-install $(ISO_IMAGE)
|
||||||
|
@printf "$(GREEN)[OK]$(RESET) ISO image ready: $(ISO_IMAGE)"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
$(call PRINT_STEP,CLEANING BUILD OUTPUT)
|
||||||
rm -rf $(BUILD_DIR) $(ISO_DIR) $(ISO_IMAGE)
|
rm -rf $(BUILD_DIR) $(ISO_DIR) $(ISO_IMAGE)
|
||||||
$(MAKE) -C $(SRC_DIR)/userland clean
|
$(MAKE) -C $(SRC_DIR)/userland clean
|
||||||
|
@printf "$(GREEN)[OK]$(RESET) Clean complete."
|
||||||
|
|
||||||
run-windows: $(ISO_IMAGE)
|
run-windows: $(ISO_IMAGE)
|
||||||
|
$(call PRINT_STEP,RUNNING BOREDOS IN QEMU ON WINDOWS)
|
||||||
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||||
-smp 4 \
|
-smp 4 \
|
||||||
-audiodev dsound,id=audio0 -machine pcspk-audiodev=audio0 \
|
-audiodev dsound,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
||||||
-drive file=disk.img,format=raw,file.locking=off
|
-drive file=disk.img,format=raw,file.locking=off
|
||||||
|
|
||||||
run-mac: $(ISO_IMAGE)
|
run-mac: $(ISO_IMAGE)
|
||||||
|
$(call PRINT_STEP,RUNNING BOREDOS IN QEMU ON MACOS)
|
||||||
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||||
-smp 4 \
|
-smp 4 \
|
||||||
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \
|
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||||
|
|
@ -241,7 +348,9 @@ run-mac: $(ISO_IMAGE)
|
||||||
-display cocoa,show-cursor=off \
|
-display cocoa,show-cursor=off \
|
||||||
-drive file=disk.img,format=raw,file.locking=off \
|
-drive file=disk.img,format=raw,file.locking=off \
|
||||||
-cpu max
|
-cpu max
|
||||||
|
|
||||||
run-linux: $(ISO_IMAGE)
|
run-linux: $(ISO_IMAGE)
|
||||||
|
$(call PRINT_STEP,RUNNING BOREDOS IN QEMU ON LINUX)
|
||||||
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||||
-smp 4 \
|
-smp 4 \
|
||||||
-audiodev pa,id=audio0 -machine pcspk-audiodev=audio0 \
|
-audiodev pa,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||||
|
|
@ -249,4 +358,3 @@ run-linux: $(ISO_IMAGE)
|
||||||
-display gtk,show-cursor=off \
|
-display gtk,show-cursor=off \
|
||||||
-drive file=disk.img,format=raw,file.locking=off \
|
-drive file=disk.img,format=raw,file.locking=off \
|
||||||
-cpu max
|
-cpu max
|
||||||
|
|
||||||
|
|
|
||||||
262
docs/appdev/inputs_api_(utf8).md
Normal file
262
docs/appdev/inputs_api_(utf8).md
Normal file
|
|
@ -0,0 +1,262 @@
|
||||||
|
# UTF-8 Library — Application Development Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The userland libc provides a lightweight UTF-8 utility module located in:
|
||||||
|
|
||||||
|
- src/userland/libc/utf-8.c
|
||||||
|
- src/userland/libc/utf-8.h
|
||||||
|
|
||||||
|
This module is designed for **direct use in applications** requiring UTF-8 handling. It provides basic primitives for decoding, encoding, and traversing UTF-8 strings safely.
|
||||||
|
|
||||||
|
It is intended for:
|
||||||
|
|
||||||
|
- text rendering
|
||||||
|
- terminal input/output
|
||||||
|
- cursor movement
|
||||||
|
- string processing at the character level
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Synopsis
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "utf-8.h"
|
||||||
|
|
||||||
|
uint32_t text_decode_utf8(const char *s, int *advance);
|
||||||
|
int text_encode_utf8(uint32_t cp, char *out);
|
||||||
|
|
||||||
|
const char* text_next_utf8(const char *s);
|
||||||
|
const char* text_prev_utf8(const char *start, const char *s);
|
||||||
|
|
||||||
|
int text_strlen_utf8(const char *s);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### text_decode_utf8
|
||||||
|
|
||||||
|
```c
|
||||||
|
uint32_t text_decode_utf8(const char *s, int *advance);
|
||||||
|
```
|
||||||
|
|
||||||
|
Decodes a UTF-8 sequence into a Unicode code point.
|
||||||
|
|
||||||
|
- `s`: pointer to current position in a UTF-8 string
|
||||||
|
- `advance`: receives number of bytes consumed
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
- decoded Unicode code point (`uint32_t`)
|
||||||
|
- `0` if input is null or empty
|
||||||
|
- `0xFFFD` for invalid sequences
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### text_encode_utf8
|
||||||
|
|
||||||
|
```c
|
||||||
|
int text_encode_utf8(uint32_t cp, char *out);
|
||||||
|
```
|
||||||
|
|
||||||
|
Encodes a Unicode code point into UTF-8.
|
||||||
|
|
||||||
|
- `cp`: Unicode code point
|
||||||
|
- `out`: buffer receiving encoded bytes
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
- number of bytes written (1–4)
|
||||||
|
- writes replacement character if `cp` is invalid
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### text_next_utf8
|
||||||
|
|
||||||
|
```c
|
||||||
|
const char* text_next_utf8(const char *s);
|
||||||
|
```
|
||||||
|
|
||||||
|
Advances to the next UTF-8 character.
|
||||||
|
|
||||||
|
Returns a pointer to the next character boundary.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### text_prev_utf8
|
||||||
|
|
||||||
|
```c
|
||||||
|
const char* text_prev_utf8(const char *start, const char *s);
|
||||||
|
```
|
||||||
|
|
||||||
|
Moves backward to the previous UTF-8 character.
|
||||||
|
|
||||||
|
- `start`: beginning of the buffer
|
||||||
|
- `s`: current position
|
||||||
|
|
||||||
|
Used for reverse traversal and cursor movement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### text_strlen_utf8
|
||||||
|
|
||||||
|
```c
|
||||||
|
int text_strlen_utf8(const char *s);
|
||||||
|
```
|
||||||
|
|
||||||
|
Counts UTF-8 characters (code points), not bytes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Iterating over UTF-8 characters
|
||||||
|
|
||||||
|
```c
|
||||||
|
const char *p = text;
|
||||||
|
|
||||||
|
while (*p) {
|
||||||
|
int adv;
|
||||||
|
uint32_t cp = text_decode_utf8(p, &adv);
|
||||||
|
|
||||||
|
/* process cp */
|
||||||
|
|
||||||
|
p += adv;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cursor movement
|
||||||
|
|
||||||
|
```c
|
||||||
|
cursor = text_next_utf8(cursor);
|
||||||
|
cursor = text_prev_utf8(buffer_start, cursor);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Encoding a character
|
||||||
|
|
||||||
|
```c
|
||||||
|
char out[4];
|
||||||
|
int len = text_encode_utf8(0x20AC, out);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backspace handling
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *prev = (char*)text_prev_utf8(buffer, cursor);
|
||||||
|
cursor = prev;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
### UTF-8 Encoding
|
||||||
|
|
||||||
|
The implementation supports:
|
||||||
|
|
||||||
|
- 1 byte: `0x00 – 0x7F`
|
||||||
|
- 2 bytes: `0x80 – 0x7FF`
|
||||||
|
- 3 bytes: `0x800 – 0xFFFF`
|
||||||
|
- 4 bytes: `0x10000 – 0x10FFFF`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Replacement Character
|
||||||
|
|
||||||
|
Invalid sequences are replaced with:
|
||||||
|
|
||||||
|
- code point: `0xFFFD`
|
||||||
|
- UTF-8 encoding: `0xEF 0xBF 0xBD`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Control Signals
|
||||||
|
|
||||||
|
Some decoded code points correspond to control signals instead of printable characters.
|
||||||
|
|
||||||
|
ASCII control range:
|
||||||
|
|
||||||
|
- `0x00 – 0x1F`
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `0x08` → Backspace
|
||||||
|
- `0x09` → Tab
|
||||||
|
- `0x0A` → Line Feed
|
||||||
|
- `0x0D` → Carriage Return
|
||||||
|
- `0x1B` → Escape
|
||||||
|
|
||||||
|
These are typically interpreted by:
|
||||||
|
|
||||||
|
- terminal logic
|
||||||
|
- shell input handling
|
||||||
|
- system interfaces
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Non-ASCII Characters
|
||||||
|
|
||||||
|
Characters outside the ASCII range (`0x00 – 0x7F`) are encoded using multi-byte UTF-8 sequences.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- 'é' → `0xC3 0xA9`
|
||||||
|
- '€' → `0xE2 0x82 0xAC`
|
||||||
|
|
||||||
|
Decoded values:
|
||||||
|
|
||||||
|
- 'é' → `U+00E9`
|
||||||
|
- '€' → `U+20AC`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Modifiers and Layout
|
||||||
|
|
||||||
|
Character output depends on:
|
||||||
|
|
||||||
|
- keyboard layout
|
||||||
|
- modifier keys (Shift, Ctrl, AltGr)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
- `KEY_E` → 'e'
|
||||||
|
- `KEY_E + SHIFT` → 'E'
|
||||||
|
- `KEY_E + AltGr` → '€'
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- No full UTF-8 validation (overlong, surrogates not fully rejected)
|
||||||
|
- No grapheme cluster handling
|
||||||
|
- No Unicode normalization
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Never iterate UTF-8 strings byte-by-byte
|
||||||
|
- Always use provided helpers for navigation
|
||||||
|
- Separate byte length from character count
|
||||||
|
- Handle invalid sequences safely
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This module provides essential UTF-8 primitives for userland applications.
|
||||||
|
|
||||||
|
It should be used whenever an application needs to safely:
|
||||||
|
|
||||||
|
- decode UTF-8
|
||||||
|
- encode Unicode
|
||||||
|
- traverse text
|
||||||
|
- handle user input correctly
|
||||||
Loading…
Reference in a new issue