From 5dd2cf6b71c9a86a27a71a41bf7935d12c878267 Mon Sep 17 00:00:00 2001 From: Aren Date: Sat, 30 Sep 2023 16:11:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D1=8B=20?= =?UTF-8?q?=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ build.sh | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 build.py create mode 100644 build.sh diff --git a/build.py b/build.py new file mode 100644 index 0000000..ea188b9 --- /dev/null +++ b/build.py @@ -0,0 +1,121 @@ +import os +import shutil +import subprocess +import time +from multiprocessing import Pool + + +CC = "g++" +ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-80387 -mno-red-zone -mcmodel=kernel -MMD -MP" +WARN_FLAGS = "-Wall -Wextra" +STANDART_FLAGS = "-std=gnu11" +PROTECT_FLAGS = "-O0 -pipe -ffreestanding -fno-stack-protector -fno-lto -fno-stack-check -fno-PIC -fno-PIE" +CHARSET_FLAGS = "-finput-charset=UTF-8 -fexec-charset=cp1251" +LIBS_FLAGS = "-Ilimine" + + +def find_files(directory, extensions): + file_list = [] + for root, dirs, files in os.walk(directory): + for file in files: + if any(file.endswith(extension) for extension in extensions): + file_list.append(os.path.join(root, file)) + return file_list + + +def compile(file: str): + output_file = file.replace('/', '_') + obj_file = f"bin/{output_file}.o" + cmd = f"{CC} {WARN_FLAGS} {PROTECT_FLAGS} {ARCH_FLAGS} {CHARSET_FLAGS} {LIBS_FLAGS} -c {file} -o {obj_file}" + print(cmd) + os.system(cmd) + return obj_file + + +def compile_all(): + file_list = find_files("kernel/", [".c", ".cpp", ".s"]) + + with Pool() as pool: + results = pool.map(compile, file_list) + + while not all(results): + print(results) + time.sleep(1) + print(results) + cmd = f"ld -nostdlib -static -m elf_x86_64 -z max-page-size=0x1000 -T configs/linker.ld -o kernel.elf {' '.join(results)}" + print(cmd) + os.system(cmd) + + +def check_limine(): + if not os.path.isdir("limine"): + subprocess.run(["git", "clone", "https://github.com/limine-bootloader/limine.git", "--branch=v5.x-branch-binary", "--depth=1"]) + else: + os.chdir("limine") + subprocess.run(["git", "pull"]) + os.chdir("..") + os.chdir("limine") + subprocess.run(["make"]) + os.chdir("..") + + +def check_tools(): + required_tools = ["g++", "xorriso", "make", "mtools"] + missing_tools = [] + + for tool in required_tools: + if shutil.which(tool) is None: + missing_tools.append(tool) + + if len(missing_tools) > 0: + subprocess.run(["sudo", "apt", "install"] + missing_tools) + + +def create_iso(IMAGE_NAME): + subprocess.run(["rm", "-rf", "iso_root"]) + subprocess.run(["mkdir", "-p", "iso_root"]) + subprocess.run(["cp", "-v", "boot/CYRILL2.F16", "iso_root/"]) + subprocess.run(["cp", "-v", "kernel.elf", + "configs/limine.cfg", "limine/limine-bios.sys", + "limine/limine-bios-cd.bin", "limine/limine-uefi-cd.bin", + "iso_root/"]) + subprocess.run(["mkdir", "-p", "iso_root/EFI/BOOT"]) + subprocess.run(["cp", "-v", "limine/BOOTX64.EFI", "iso_root/EFI/BOOT/"]) + subprocess.run(["cp", "-v", "limine/BOOTIA32.EFI", "iso_root/EFI/BOOT/"]) + subprocess.run(["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", IMAGE_NAME+".iso"]) + subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".iso"]) + subprocess.run(["rm", "-rf", "iso_root"]) + +def create_hdd(IMAGE_NAME): + subprocess.run(["rm", "-f", IMAGE_NAME+".hdd"]) + subprocess.run(["dd", "if=/dev/zero", "bs=1M", "count=0", "seek=64", "of="+IMAGE_NAME+".hdd"]) + subprocess.run(["sgdisk", IMAGE_NAME+".hdd", "-n", "1:2048", "-t", "1:ef00"]) + subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".hdd"]) + subprocess.run(["mformat", "-i", IMAGE_NAME+".hdd@@1M"]) + subprocess.run(["mmd", "-i", IMAGE_NAME+".hdd@@1M", "::/EFI", "::/EFI/BOOT"]) + subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", + "kernel.elf", "configs/limine.cfg", "boot/CYRILL2.F16", "limine/limine-bios.sys", "::/"]) + subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", + "limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"]) + + +if __name__ == "__main__": + subprocess.run(["rm", "-rf", "bin"]) + subprocess.run(["mkdir", "-p", "bin"]) + + if not os.path.isdir("ovmf"): + subprocess.run(["mkdir", "-p", "ovmf"]) + os.chdir("ovmf") + subprocess.run(["curl", "-Lo", "OVMF.fd", "https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd"]) + os.chdir("..") + + check_limine() + check_tools() + compile_all() + create_hdd("mseos") + + os.system("qemu-system-x86_64 -M q35 -m 8G -smp 8 -bios ovmf/OVMF.fd -hda mseos.hdd") \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..6a32b89 --- /dev/null +++ b/build.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +CC="g++" +ARCH_FLAGS="-m64 -march=x86-64 -mabi=sysv -mno-80387 -mno-red-zone -mcmodel=kernel -MMD -MP" +WARN_FLAGS="-Wall -Wextra" +STANDART_FLAGS="-std=gnu11" +PROTECT_FLAGS="-O0 -pipe -ffreestanding -fno-stack-protector -fno-lto -fno-stack-check -fno-PIC -fno-PIE" +CHARSET_FLAGS="-finput-charset=UTF-8 -fexec-charset=cp1251" +LIBS_FLAGS="-Ilimine" + +find_files() { + file_list=() + directory=$1 + extensions=$2 + while IFS= read -r -d '' file; do + file_list+=("$file") + done < <(find "$directory" -type f \( -name "*.c" -o -name "*.cpp" -o -name "*.s" \) -print0) + printf '%s\n' "${file_list[@]}" +} + +compile() { + file=$1 + output_file="${file/\//-}" + obj_file="bin/${output_file}.o" + cmd="$CC $WARN_FLAGS $PROTECT_FLAGS $ARCH_FLAGS $CHARSET_FLAGS $LIBS_FLAGS -c $file -o $obj_file" + echo "$cmd" + eval "$cmd" + echo "$obj_file" +} + +compile_all() { + file_list=$(find_files "kernel/" ".c .cpp .s") + IFS=$'\n' read -rd '' -a file_array <<<"$file_list" + + for file in "${file_array[@]}"; do + compile "$file" + done + + while [[ $(grep -o "bin/.*\.o" <<<"${results[*]}") ]]; do + sleep 1 + done + + cmd="ld -nostdlib -static -m elf_x86_64 -z max-page-size=0x1000 -T configs/linker.ld -o kernel.elf ${results[*]}" + echo "$cmd" + eval "$cmd" +} + +check_limine() { + if [ ! -d "limine" ]; then + git clone "https://github.com/limine-bootloader/limine.git" --branch=v5.x-branch-binary --depth=1 + else + pushd "limine" + git pull + popd + fi + pushd "limine" + make + popd +} + +check_tools() { + required_tools=("g++" "xorriso" "make" "mtools") + missing_tools=() + + for tool in "${required_tools[@]}"; do + if ! command -v "$tool" >/dev/null 2>&1; then + missing_tools+=("$tool") + fi + done + + if (( ${#missing_tools[@]} > 0 )); then + sudo apt install "${missing_tools[@]}" + fi +} + +create_iso() { + IMAGE_NAME=$1 + rm -rf "iso_root" + mkdir -p "iso_root" + cp -v "boot/CYRILL2.F16" "iso_root/" + cp -v "kernel.elf" "configs/limine.cfg" "limine/limine-bios.sys" "limine/limine-bios-cd.bin" "limine/limine-uefi-cd.bin" "iso_root/" + mkdir -p "iso_root/EFI/BOOT" + cp -v "limine/BOOTX64.EFI" "iso_root/EFI/BOOT/" + cp -v "limine/BOOTIA32.EFI" "iso_root/EFI/BOOT/" + 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 "${IMAGE_NAME}.iso" + ./limine/limine bios-install "${IMAGE_NAME}.iso" + rm -rf "iso_root" +} + +create_hdd() { + IMAGE_NAME=$1 + rm -f "${IMAGE_NAME}.hdd" + dd if=/dev/zero bs=1M count=0 seek=64 of="${IMAGE_NAME}.hdd" + sgdisk "${IMAGE_NAME}.hdd" -n 1:2048 -t 1:ef00 + ./limine/limine bios-install "${IMAGE_NAME}.hdd" + mformat -i "${IMAGE_NAME}.hdd@@1M" + mmd -i "${IMAGE_NAME}.hdd@@1M" "::/EFI" "::/EFI/BOOT" + mcopy -i "${IMAGE_NAME}.hdd@@1M" "kernel.elf" "configs/limine.cfg" "boot/CYRILL2.F16" "limine/limine-bios.sys" "::/" + mcopy -i "${IMAGE_NAME}.hdd@@1M" "limine/BOOTX64.EFI" "limine/BOOTIA32.EFI" "::/EFI/BOOT" +} + +check_limine +check_tools +compile_all +create_iso "IMAGE_NAME" +create_hdd "IMAGE_NAME" \ No newline at end of file