diff --git a/.gitignore b/.gitignore index c9c376a..c121858 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ *.d *.sys *.iso - +/service/boot/stand/ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..a77cf37 --- /dev/null +++ b/build.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Copyright (c) 2026, Chloe M. +# Provided under the BSD-3 clause +# +# Description: Top-level build driver +# Author: Chloe M. +# + +# Globals +MAKE=make + +# +# Check if a list of programs are installed on the system +# +# <@>: List of programs to check +# +check_deps() { + for dep in $@; do + printf "\033[33;40mChecking if $dep is installed... " + which $dep &>/dev/null + if [ $? -ne 0 ]; then + echo -e "\033[31;40mno" + echo -e "fatal: Please install '$dep'!\033[0m" + exit 1 + fi + + echo -e "\033[32;40myes\033[0m" + done +} + +# +# Verify that the build environment is sane before we actually +# start. +# +build_verify() { + check_deps \ + clang \ + rsync \ + xorriso + + # We need build envs !! + if [ -z "${PT_BUILD_SOURCED}" ] + then + echo -e "\033[31;40mfatal\033[0m: Please run '. service/dev/build.env' first!" + exit 1 + fi +} + +# +# <$1>: Build target +# <$2>: Build message +# +make_build() { + echo -e "\033[37m[\033[35m*\033[37m] \033[32;40m$2\033[0m" + pushd $1; \ + $MAKE + popd +} + +# +# Kick off the actual build process +# +build() { + mkdir -p artifacts/ + + make_build \ + service/ptos/ \ + "Building kernel..." + + make_build \ + service/boot/ \ + "Building bootloader..." +} + +build_verify +build diff --git a/service/base/boot/limine.conf b/service/base/boot/limine.conf new file mode 100644 index 0000000..4ef42db --- /dev/null +++ b/service/base/boot/limine.conf @@ -0,0 +1,11 @@ +timeout: 16 + +interface_branding: -- PtOS -- + +editor_enabled: no +interface_help_hidden: yes +randomize_hhdm_base: yes + +/PtOS + protocol: limine + kernel_path: boot():/boot/ptsv.sys diff --git a/service/boot/Makefile b/service/boot/Makefile new file mode 100644 index 0000000..dececd9 --- /dev/null +++ b/service/boot/Makefile @@ -0,0 +1,15 @@ +# +# Copyright (c) 2026, Chloe M., et al +# Provided under the BSD-3 clause +# + +.PHONY: all +all: deps iso + +.PHONY: deps +deps: + ./host/deps.sh + +.PHONY: iso +iso: + ./host/iso.sh diff --git a/service/boot/host/deps.sh b/service/boot/host/deps.sh new file mode 100755 index 0000000..316b267 --- /dev/null +++ b/service/boot/host/deps.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# Copyright (c) 2026, Chloe M., et al +# Provided under the BSD-3 clause +# + +if [ ! -d stand/limine ]; then + curl -L https://github.com/Limine-Bootloader/Limine/releases/latest/download/limine-binary.tar.gz | gunzip | tar -xf - + mkdir -p stand/ + mv limine-binary stand/limine/ + make -C stand/limine/ +fi diff --git a/service/boot/host/iso.sh b/service/boot/host/iso.sh new file mode 100755 index 0000000..671475d --- /dev/null +++ b/service/boot/host/iso.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Copyright (c) 2026, Chloe M., et al +# Provided under the BSD-3 clause +# + +set -e + +ISO=$PT_PROJECT_ROOT/artifacts/ptos.iso +CONFIG=$PT_PROJECT_ROOT/service/base/boot/limine.conf +KERNEL=$PT_PROJECT_ROOT/artifacts/ptsv.sys + +mkdir -p iso_root/boot/ + +# Copy the kernel to the ISO root +cp $KERNEL iso_root/boot + +# Copy boot files +cp $CONFIG stand/limine/limine-bios.sys \ + stand/limine/limine-bios-cd.bin \ + stand/limine/limine-uefi-cd.bin \ + iso_root/ + +# Generate the ISO +xorriso -as mkisofs -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_root/ -o $ISO 2>/dev/null + +stand/limine/limine bios-install $ISO 2>/dev/null +rm -rf iso_root diff --git a/service/dev/build.env b/service/dev/build.env new file mode 100644 index 0000000..1add698 --- /dev/null +++ b/service/dev/build.env @@ -0,0 +1,23 @@ +# +# Copyright (c) 2026, Chloe M., et al. +# Provided under the BSD-3 clause. +# +# Description: Build variables +# Author: Chloe M. +# + +# Source the build variables +. service/dev/bvars.env + +# Export envs +export PT_PROJECT_ROOT=$PT_PROJECT_ROOT +export PT_TARGET_ARCH=$PT_TARGET_ARCH + +if [ "$PT_BUILD_SOURCED" != "1" ] +then + echo "[*] build environment prepared" + PS1="(PTOS) $PS1" +fi + +# Indicate that we have been sourced +export PT_BUILD_SOURCED=1 diff --git a/service/dev/bvars.env b/service/dev/bvars.env new file mode 100644 index 0000000..fd120b4 --- /dev/null +++ b/service/dev/bvars.env @@ -0,0 +1,10 @@ +# +# Copyright (c) 2026, Chloe M., et al. +# Provided under the BSD-3 clause. +# +# Description: Build variables +# Author: Chloe M. +# + +PT_PROJECT_ROOT=$(pwd) +PT_TARGET_ARCH=amd64 diff --git a/service/mk/ptos.mk b/service/mk/ptos.mk new file mode 100644 index 0000000..76dfc52 --- /dev/null +++ b/service/mk/ptos.mk @@ -0,0 +1,51 @@ +# +# Copyright (c) 2026, Chloe M. +# Provided under the BSD-3 clause +# +# Description: Build flags, etc +# Author: Chloe M. +# + +.SILENT: +PROMPT := printf "%s\t\t%s\n" + +ifeq ($(PT_TARGET_ARCH), amd64) + CC_TARGET = x86_64-unknown-elf +else + CC_TARGET = +endif + +CC = \ + clang +ld = \ + ld + +SYS_CFLAGS = \ + -nostdlib \ + -nostdinc \ + -ffreestanding \ + -fexceptions \ + -target $(CC_TARGET)\ + -mcmodel=kernel \ + -Wno-attributes \ + -Wno-multichar \ + -fno-stack-protector\ + -D_ST_MULTICORE \ + +ifeq ($(ST_TARGET_ARCH),amd64) + SYS_CFLAGS += \ + -mno-sse \ + -mno-sse2 \ + -mno-sse3 \ + -mno-avx \ + -mno-avx2 \ + -mno-80387 \ + -mno-3dnow \ + -mno-mmx +endif + +PASSDOWN_ARGS = \ + ARCH=$(ST_TARGET_ARCH) \ + SYS_CC=$(CC) \ + SYS_LD=$(LD) \ + SYS_CFLAGS="$(SYS_CFLAGS)" diff --git a/service/ptos/Makefile b/service/ptos/Makefile new file mode 100644 index 0000000..43ee0e4 --- /dev/null +++ b/service/ptos/Makefile @@ -0,0 +1,16 @@ +# +# Copyright (c) 2026, Chloe M. +# Provided under the BSD-3 clause +# +# Description: Kernel build script +# Author: Chloe M. +# + +include ../mk/ptos.mk + +.PHONY: all +all: machine + +.PHONY: machine +machine: + cd arch/$(PT_TARGET_ARCH)/; $(MAKE) $(PASSDOWN_ARGS) diff --git a/service/ptos/arch/amd64/Makefile b/service/ptos/arch/amd64/Makefile new file mode 100644 index 0000000..a2d9f7e --- /dev/null +++ b/service/ptos/arch/amd64/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (c) 2026, Chloe M. +# Provided under the BSD-3 clause +# +# Description: AMD64 port build script +# Author: Chloe M. +# + +.SILENT: +include ../../../mk/ptos.mk + +ASMFILES = $(shell find . -name "*.S") +ASMOFILES = $(ASMFILES:.S=.S.o) + +CFILES = $(shell find . -name "*.c") +OFILES = $(CFILES:.c=.o) +CDFILES = $(OFILES:.o.d) +ASMDFILES = $(ASMOFILES:.S.o=.S.d) + +MISC_OFILES = $(shell find $(PT_PROJECT_ROOT)/service/ptos/ -name "*.o") +KERNEL_PATH = \ + $(PT_PROJECT_ROOT)/artifacts/ptsv.sys + +CFLAGS = \ + $(SYS_CFLAGS) \ + -I../../target \ + -I../../head/ \ + -D_KERNEL \ + -MMD \ + -I$(PT_PROJECT_ROOT)/sdk/head \ + +.PHONY: all +all: bin + +.PHONY: bin +bin: $(OFILES) $(ASMOFILES) + $(PROMPT) "LD" $(KERNEL_PATH) + $(SYS_LD) -Tdev/link.ld $(MISC_OFILES) -o $(KERNEL_PATH) + +-include $(CDFILES) +%.o: %.c + $(PROMPT) "CC" $< + $(SYS_CC) -c $< $(CFLAGS) -o $@ + +-include $(ASMDFILES) +%.S.o: %.S + $(PROMPT) "AS" $< + $(SYS_CC) -c $< $(CFLAGS) -o $@ diff --git a/service/ptos/arch/amd64/cpu/locore.S b/service/ptos/arch/amd64/cpu/locore.S new file mode 100644 index 0000000..405903e --- /dev/null +++ b/service/ptos/arch/amd64/cpu/locore.S @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: Low-level AMD64 processor init + * Author: Chloe M. + */ + + .text + .globl MdBspEntry +MdBspEntry: + cli + hlt + jmp MdBspEntry diff --git a/service/ptos/arch/amd64/dev/link.ld b/service/ptos/arch/amd64/dev/link.ld new file mode 100644 index 0000000..71943dc --- /dev/null +++ b/service/ptos/arch/amd64/dev/link.ld @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: Kernel linker script + * Author: Chloe M. + */ + +OUTPUT_FORMAT(elf64-x86-64) +OUTPUT_ARCH(i386:x86-64) +ENTRY(MdBspEntry) + +PHDRS { + text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; + rodata PT_LOAD FLAGS((1 << 2)) ; + data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; +} + +SECTIONS +{ + . = 0xFFFFFFFF80000000; + __KernelStart = .; + + .text : { + *(.text .text.*) + } :text + + . += CONSTANT(MAXPAGESIZE); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + . += CONSTANT(MAXPAGESIZE); + + .driver : { + __driver_start = .; + KEEP(*(.driver .driver)); + __driver_end = .; + } + + . += CONSTANT(MAXPAGESIZE); + + .data : { + *(.data) + } :data + + .bss : { + *(COMMON) + *(.bss .bss.*) + } :data + + __KernelEnd = .; + . += CONSTANT(MAXPAGESIZE); + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + *(.note .note.*) + } +}