134 lines
4.4 KiB
Python
134 lines
4.4 KiB
Python
Import('env')
|
|
|
|
### Kernel
|
|
kernel_env = env.Clone()
|
|
kernel_env['AS'] = 'x86_64-elf-as'
|
|
kernel_env['CC'] = 'x86_64-elf-gcc'
|
|
kernel_env['CXX'] = 'x86_64-elf-g++'
|
|
kernel_env['LD'] = 'x86_64-elf-g++'
|
|
|
|
kernel_env.Append(CFLAGS = ['-ffreestanding'])
|
|
kernel_env.Append(CPPDEFINES = ['__baos_kernel_source__=1'])
|
|
kernel_env.Append(CXXFLAGS = ['-ffreestanding', '-fno-exceptions', '-fno-rtti', '-std=c++20'])
|
|
kernel_env.Append(LINKFLAGS = ['-T', kernel_env.File('linker.ld').abspath, '-ffreestanding', '-nostdlib', '-mcmodel=large', '-mno-red-zone', '-mno-mmx', '-mno-sse', '-mno-sse2'])
|
|
kernel_env.Append(CPPPATH = ['#targets/_any/include', '#targets/_any/bastl/include', 'include', '/usr/include/efi', '#targets/_any/kernel/include', '#targets/_any/stdlib/include'])
|
|
|
|
def get_crt_object(name: str) -> str:
|
|
import subprocess
|
|
|
|
cmd = [kernel_env['CXX']]
|
|
cmd.extend(kernel_env['CXXFLAGS'])
|
|
cmd.append(f'-print-file-name={name}')
|
|
result = subprocess.run(cmd, stdout=subprocess.PIPE)
|
|
return result.stdout.decode('utf-8').strip()
|
|
|
|
crtbegin_o = get_crt_object('crtbegin.o')
|
|
crtend_o = get_crt_object('crtend.o')
|
|
crti_o = kernel_env.Object(kernel_env['CRTI_PATH'])
|
|
crtn_o = kernel_env.Object(kernel_env['CRTN_PATH'])
|
|
kernel_env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0].abspath} {crtbegin_o} -Wl,--start-group $_LIBFLAGS -Wl,--end-group -lgcc {crtend_o} {crtn_o[0].abspath}')
|
|
|
|
kernel_isr_sources = env['KERNEL_ISR_SOURCES'] + Split('''
|
|
|
|
''')
|
|
kernel_sources = env['KERNEL_SOURCES'] + Split('''
|
|
src/kernel/boot.s
|
|
src/kernel/startup.cpp
|
|
''') + [kernel_env.Object(f, CCFLAGS = kernel_env['CCFLAGS'] + ['-mgeneral-regs-only']) for f in kernel_isr_sources]
|
|
|
|
kernel_target = kernel_env.File('#kernel.x86_64.bin')
|
|
prog_kernel = kernel_env.Program(
|
|
target = kernel_target,
|
|
source = kernel_sources
|
|
)
|
|
kernel_env.Depends(prog_kernel, [crti_o, crtn_o] + kernel_sources)
|
|
kernel_env.Default(prog_kernel)
|
|
|
|
x86_64_iso_files = [
|
|
{
|
|
"source": env.File("boot/grub.cfg"),
|
|
"target": "boot/grub/grub.cfg"
|
|
},
|
|
{
|
|
"source": env.File("#os.bin"),
|
|
"target": "boot/os.bin"
|
|
},
|
|
{
|
|
"source": env.File("#loader.bin"),
|
|
"target": "boot/loader.bin"
|
|
}
|
|
]
|
|
|
|
### UEFI Loader
|
|
uefi_env = env.Clone()
|
|
uefi_env['AS'] = 'x86_64-w64-mingw32-as'
|
|
uefi_env['CC'] = 'x86_64-w64-mingw32-gcc'
|
|
uefi_env['CXX'] = 'x86_64-w64-mingw32-g++'
|
|
uefi_env['LD'] = 'x86_64-w64-mingw32-g++'
|
|
|
|
uefi_env.Append(CFLAGS = ['-ffreestanding'])
|
|
uefi_env.Append(CXXFLAGS = ['-ffreestanding', '-fno-exceptions', '-fno-rtti', '-std=c++20'])
|
|
uefi_env.Append(LINKFLAGS = ['-nostdlib', '-Wl,-dll', '-shared', '-Wl,--subsystem,10', '-e', 'efi_main'])
|
|
uefi_env.Append(CPPPATH = ['/usr/include/efi', 'include'])
|
|
|
|
loader_sources = Split('''
|
|
src/loader/main.cpp
|
|
src/loader/miniprintf.cpp
|
|
''')
|
|
loader_target = uefi_env.File('#loader.x86_64.efi')
|
|
prog_loader = uefi_env.Program(
|
|
target = loader_target,
|
|
source = loader_sources
|
|
)
|
|
uefi_env.Default(prog_loader)
|
|
|
|
### Bootable Image
|
|
def runcmd(*args, **kwargs):
|
|
from subprocess import run
|
|
run(*args, **kwargs, check=True)
|
|
|
|
def build_img(target, source, env):
|
|
fatfile = target[0].abspath
|
|
runcmd(['dd', 'if=/dev/zero', f'of={fatfile}', 'bs=1K', 'count=1440'])
|
|
runcmd(['mformat', '-i', fatfile, '-f', '1440', '::'])
|
|
runcmd(['mmd', '-i', fatfile, '::/EFI'])
|
|
runcmd(['mmd', '-i', fatfile, '::/EFI/BOOT'])
|
|
runcmd(['mcopy', '-i', fatfile, loader_target.abspath, '::/EFI/BOOT/BOOTX64.EFI'])
|
|
runcmd(['mcopy', '-i', fatfile, kernel_target.abspath, '::/kernel.bin'])
|
|
|
|
img_target = env.File('#boot.x86_64.fat.img')
|
|
cmd_image = env.Command(
|
|
target = img_target,
|
|
source = [prog_kernel, prog_loader],
|
|
action = build_img
|
|
)
|
|
|
|
def build_iso(target, source, env):
|
|
import os
|
|
import shutil
|
|
|
|
isofile = target[0].abspath
|
|
|
|
# prepare the staging folder
|
|
staging_dir = env.Dir('#staging/x86_64_iso').abspath
|
|
shutil.rmtree(staging_dir, ignore_errors=True)
|
|
os.makedirs(staging_dir)
|
|
|
|
# copy files to the staging folder
|
|
shutil.copy(img_target.abspath, os.path.join(staging_dir, 'fat.img'))
|
|
|
|
runcmd(['xorriso', '-as', 'mkisofs', '-R', '-f', '-e', 'fat.img', '-no-emul-boot', '-o', target[0].abspath, staging_dir])
|
|
|
|
iso_target = env.File('#system.x86_64.iso')
|
|
cmd_iso = env.Command(
|
|
target = iso_target,
|
|
source = [cmd_image],
|
|
action = build_iso
|
|
)
|
|
env.Default(cmd_iso)
|
|
|
|
# finally update the environment
|
|
env.Append(ISO_FILES = x86_64_iso_files)
|
|
|
|
Return('env')
|