2023-09-30 16:11:59 +03:00
|
|
|
|
import os
|
|
|
|
|
import shutil
|
|
|
|
|
import subprocess
|
|
|
|
|
import time
|
|
|
|
|
from multiprocessing import Pool
|
|
|
|
|
|
|
|
|
|
|
2023-10-12 22:30:54 +03:00
|
|
|
|
ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-red-zone -mcmodel=kernel -MMD -MP"
|
|
|
|
|
WARN_FLAGS = "-w -Wall -Wextra -nostdlib"
|
2023-09-30 16:11:59 +03:00
|
|
|
|
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"
|
2023-09-30 22:51:57 +03:00
|
|
|
|
LIBS_FLAGS = "-Ilimine -Iinclude"
|
2023-09-30 16:11:59 +03:00
|
|
|
|
|
2023-10-12 22:30:54 +03:00
|
|
|
|
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
|
2023-10-17 13:10:01 +03:00
|
|
|
|
if build > 999:
|
2023-10-12 22:30:54 +03:00
|
|
|
|
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'))
|
2023-09-30 16:11:59 +03:00
|
|
|
|
|
|
|
|
|
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):
|
2023-10-21 20:27:23 +03:00
|
|
|
|
CC = "gcc"
|
2023-09-30 16:11:59 +03:00
|
|
|
|
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():
|
2023-10-12 22:30:54 +03:00
|
|
|
|
file_list = find_files("kernel/", [".s", ".cpp", ".c"])
|
|
|
|
|
file_list += find_files("kernel/*/*", [".s", ".cpp", ".c"])
|
2023-09-30 16:11:59 +03:00
|
|
|
|
|
|
|
|
|
with Pool() as pool:
|
|
|
|
|
results = pool.map(compile, file_list)
|
|
|
|
|
|
|
|
|
|
while not all(results):
|
|
|
|
|
print(results)
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
print(results)
|
2023-10-12 22:30:54 +03:00
|
|
|
|
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))}"
|
2023-09-30 16:11:59 +03:00
|
|
|
|
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("..")
|
|
|
|
|
|
|
|
|
|
|
2023-10-22 15:27:02 +03:00
|
|
|
|
|
|
|
|
|
def check_os():
|
2023-10-22 15:32:53 +03:00
|
|
|
|
import platform
|
|
|
|
|
using_distro = False
|
|
|
|
|
try:
|
|
|
|
|
import distro
|
|
|
|
|
using_distro = True
|
|
|
|
|
except ImportError:
|
|
|
|
|
pass
|
|
|
|
|
if using_distro:
|
|
|
|
|
linux_distro = distro.like()
|
|
|
|
|
else:
|
|
|
|
|
linux_distro = platform.linux_distribution()[0]
|
2023-10-22 15:34:35 +03:00
|
|
|
|
if linux_distro.lower() in ['debian', 'ubuntu']:
|
2023-10-22 15:32:53 +03:00
|
|
|
|
return 1
|
2023-10-22 15:27:02 +03:00
|
|
|
|
return 0
|
|
|
|
|
|
2023-09-30 16:11:59 +03:00
|
|
|
|
def check_tools():
|
2023-10-13 21:00:22 +03:00
|
|
|
|
required_tools = ["gcc", "g++", "xorriso", "make", "mtools", "curl"]
|
2023-09-30 16:11:59 +03:00
|
|
|
|
missing_tools = []
|
|
|
|
|
|
|
|
|
|
for tool in required_tools:
|
|
|
|
|
if shutil.which(tool) is None:
|
|
|
|
|
missing_tools.append(tool)
|
|
|
|
|
|
|
|
|
|
if len(missing_tools) > 0:
|
2023-10-22 15:27:02 +03:00
|
|
|
|
if check_os():
|
|
|
|
|
subprocess.run(["sudo", "apt", "install"] + missing_tools)
|
|
|
|
|
return
|
2023-10-22 02:45:51 +03:00
|
|
|
|
subprocess.run(["sudo", "pacman", "-S"] + missing_tools)
|
2023-09-30 16:11:59 +03:00
|
|
|
|
|
|
|
|
|
|
2023-10-07 18:28:48 +03:00
|
|
|
|
def create_hdd(IMAGE_NAME):
|
2023-10-29 16:12:00 +03:00
|
|
|
|
os.system("rm -f {}.hdd".format(IMAGE_NAME))
|
|
|
|
|
os.system("dd if=/dev/zero bs=1M count=0 seek=4 of={}.hdd".format(IMAGE_NAME))
|
|
|
|
|
os.system("sgdisk {}.hdd -n 1:2048 -t 1:ef00".format(IMAGE_NAME))
|
|
|
|
|
os.system("./limine/limine bios-install {}.hdd".format(IMAGE_NAME))
|
|
|
|
|
os.system("mformat -i {}.hdd@@1M".format(IMAGE_NAME))
|
|
|
|
|
os.system("mmd -i {}.hdd@@1M ::/mod ::/EFI ::/EFI/BOOT ::/user".format(IMAGE_NAME))
|
|
|
|
|
os.system("mcopy -i {}.hdd@@1M kernel.elf configs/limine.cfg limine/limine-bios.sys ::/".format(IMAGE_NAME))
|
2023-10-29 18:41:16 +03:00
|
|
|
|
os.system("mcopy -i {}.hdd@@1M modules/music/music.ko modules/simd/simd.ko modules/helloworld/hello.ko ::/mod".format(IMAGE_NAME))
|
2023-10-29 16:12:00 +03:00
|
|
|
|
os.system("mcopy -i {}.hdd@@1M limine/BOOTX64.EFI limine/BOOTIA32.EFI ::/EFI/BOOT".format(IMAGE_NAME))
|
|
|
|
|
os.system("mcopy -i {}.hdd@@1M boot.tga ::/".format(IMAGE_NAME))
|
|
|
|
|
os.system("./limine/limine bios-install {}.hdd".format(IMAGE_NAME))
|
2023-10-07 18:28:48 +03:00
|
|
|
|
|
|
|
|
|
|
2023-09-30 16:11:59 +03:00
|
|
|
|
def create_iso(IMAGE_NAME):
|
2023-10-29 16:12:00 +03:00
|
|
|
|
os.system("rm -f {}.iso".format(IMAGE_NAME))
|
|
|
|
|
os.system("rm -rf iso_root")
|
|
|
|
|
os.system("mkdir -p iso_root")
|
|
|
|
|
os.system("cp -v iso_root/")
|
|
|
|
|
os.system("cp -v kernel.elf boot.tga configs/limine.cfg limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/")
|
|
|
|
|
os.system("mkdir -p iso_root/EFI/BOOT")
|
|
|
|
|
os.system("mkdir -p iso_root/mod")
|
|
|
|
|
os.system("cp -v modules/helloworld/hello.ko iso_root/mod/")
|
|
|
|
|
os.system("cp -v modules/music/music.ko iso_root/mod/")
|
2023-10-29 18:41:16 +03:00
|
|
|
|
os.system("cp -v modules/simd/simd.ko iso_root/mod/")
|
2023-10-29 16:12:00 +03:00
|
|
|
|
os.system("cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/")
|
|
|
|
|
os.system("cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/")
|
|
|
|
|
os.system("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".format(IMAGE_NAME))
|
|
|
|
|
os.system("./limine/limine bios-install {}.iso".format(IMAGE_NAME))
|
2023-09-30 16:11:59 +03:00
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2023-10-07 18:28:48 +03:00
|
|
|
|
os.system("""find . \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) -print0 | xargs -0 clang-format -i -style=file""")
|
2023-09-30 16:11:59 +03:00
|
|
|
|
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("..")
|
|
|
|
|
|
2023-10-29 16:12:00 +03:00
|
|
|
|
if not os.path.isdir("limine"):
|
|
|
|
|
check_limine()
|
2023-09-30 16:11:59 +03:00
|
|
|
|
check_tools()
|
2023-10-12 22:50:46 +03:00
|
|
|
|
major, minor, build = version_build()
|
2023-09-30 16:11:59 +03:00
|
|
|
|
compile_all()
|
2023-10-12 22:30:54 +03:00
|
|
|
|
create_iso("bmosp")
|
|
|
|
|
create_hdd("bmosp")
|
2023-09-30 16:11:59 +03:00
|
|
|
|
|
2023-10-22 15:27:02 +03:00
|
|
|
|
print(f"Не забудьте сохранить изменения! Номер сборки: {major}.{minor}.{build}")
|