BMOSP/pbuild.py
2023-10-13 21:00:22 +03:00

167 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import shutil
import subprocess
import time
from multiprocessing import Pool
ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-red-zone -mcmodel=kernel -MMD -MP"
WARN_FLAGS = "-w -Wall -Wextra -nostdlib"
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 -Iinclude"
def version_build():
with open("include/version.h", "r") as file:
lines = file.readlines()
major = 0
minor = 0
build = 0
with open("include/version.h", "w") as file:
for line in lines:
if line.startswith("#define VERSION_BUILD"):
parts = line.split()
build = int(parts[2]) + 1
if build > 255:
build = 0
minor += 1
file.write(f"#define VERSION_MINOR {minor}\n")
file.write(f"#define VERSION_BUILD {build}\n")
elif line.startswith("#define VERSION_MAJOR"):
parts = line.split()
major = int(parts[2])
file.write(line)
elif line.startswith("#define VERSION_MINOR"):
parts = line.split()
minor = int(parts[2])
file.write(line)
else:
file.write(line)
return [major, minor, build]
def sort_strings(strings):
return sorted(strings, key=lambda x: not x.endswith('.s.o'))
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):
CC = "g++" if file.endswith('cpp') else "gcc"
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/", [".s", ".cpp", ".c"])
file_list += find_files("kernel/*/*", [".s", ".cpp", ".c"])
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(sort_strings(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 = ["gcc", "g++", "xorriso", "make", "mtools", "curl"]
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_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", "::/mod", "::/EFI", "::/EFI/BOOT", "::/user"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"kernel.elf", "configs/limine.cfg", "limine/limine-bios.sys", "::/"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"modules/com/com.elf", "modules/helloworld/hello.so", "::/mod"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"boot.png", "::/"])
subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".hdd"])
def create_iso(IMAGE_NAME):
subprocess.run(["rm", "-f", IMAGE_NAME+".iso"])
subprocess.run(["rm", "-rf", "iso_root"])
subprocess.run(["mkdir", "-p", "iso_root"])
subprocess.run(["cp", "-v", "iso_root/"])
subprocess.run(["cp", "-v", "kernel.elf", "boot.png",
"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(["mkdir", "-p", "iso_root/mod"])
subprocess.run(["cp", "-v", "modules/helloworld/hello.so", "iso_root/mod/"])
subprocess.run(["cp", "-v", "modules/com/com.elf", "iso_root/mod/"])
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"])
if __name__ == "__main__":
os.system("""find . \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) -print0 | xargs -0 clang-format -i -style=file""")
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()
major, minor, build = version_build()
compile_all()
create_iso("bmosp")
create_hdd("bmosp")
os.system("cd modules/helloworld/ && ./build.sh")
print(f"Не забудьте сохранить изменения! Номер сборки: {major}.{minor}, {build}")