You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.8 KiB
Python

""" The doit file. Because makefiles are old and hard to read.
Can't promise this will be more readable, but at least it wont be old :)
"""
import os
from enum import Enum
from types import SimpleNamespace
from typing import Iterator
from pathlib import Path
from doit.tools import Interactive
class BoardTarget(Enum):
RPI3B = 1
RPI4 = 2
## Target
BOARD_TARGET = BoardTarget.RPI3B
## Common constants
consts = SimpleNamespace()
consts.WORK_DIR = os.getcwd()
# Rust equivalent to -Werror
consts.RUSTC_FLAGS = "-D warnings "
# Force documentation
consts.RUSTC_FLAGS += "-D missing_docs"
consts.CARGO_COMPILE_FLAGS = "--release"
if BOARD_TARGET == BoardTarget.RPI3B:
consts.TARGET = "aarch64-unknown-none-softfloat"
consts.KERNEL_NAME = "kernel8.img"
consts.QEMU_CMD = "qemu-system-aarch64"
consts.QEMU_MACHINE = "raspi3b"
consts.QEMU_ARGS = "-serial stdio -display none"
consts.OBJDUMP_CMD = "aarch64-none-elf-objdump"
consts.OBJDUMP_ARGS = "-D"
consts.NM_CMD = "aarch64-none-elf-nm"
consts.READELF_CMD = "aarch64-none-elf-readelf"
consts.LD_SCRIPT_PATH = f"{consts.WORK_DIR}/linker.ld"
consts.RUSTC_FLAGS = f"-C target-cpu=cortex-a53 -C link-arg=--script={consts.LD_SCRIPT_PATH} {consts.RUSTC_FLAGS}"
consts.CARGO_COMPILE_FLAGS = f"--features target_rpi3 {consts.CARGO_COMPILE_FLAGS}"
elif BOARD_TARGET == BoardTarget.RPI4:
consts.TARGET = "aarch64-unknown-none-softfloat"
consts.KERNEL_NAME = "kernel8.img"
consts.QEMU_CMD = "qemu-system-aarch64"
consts.QEMU_MACHINE = None
consts.QEMU_ARGS = "-serial stdio -display none"
consts.OBJDUMP_CMD = "aarch64-none-elf-objdump"
consts.OBJDUMP_ARGS = "-D"
consts.NM_CMD = "aarch64-none-elf-nm"
consts.READELF_CMD = "aarch64-none-elf-readelf"
consts.LD_SCRIPT_PATH = f"{consts.WORK_DIR}/linker.ld"
consts.RUSTC_FLAGS = f"-C target-cpu=cortex-a72 -C link-arg=--script={consts.LD_SCRIPT_PATH} {consts.RUSTC_FLAGS}"
consts.CARGO_COMPILE_FLAGS = f"--features target_rpi4 {consts.CARGO_COMPILE_FLAGS}"
DOIT_CONFIG = {
'default_tasks': ['build'],
}
def get_rust_files() -> Iterator[str]:
""" Get a list of the rust source files.
"""
return map(lambda p: str(p.resolve()), Path('./src').glob('**/*.rs'))
def get_asm_files() -> Iterator[str]:
""" Get a list of the assembly source files.
"""
return map(lambda p: str(p.resolve()), Path('./src').glob('**/*.s'))
def get_build_dep() -> list[str]:
""" Get a list of the files impacting the binary.
"""
# TODO: add dodo.py to the list?
return [
consts.LD_SCRIPT_PATH,
*get_rust_files(),
*get_asm_files(),
]
def task_install_dep():
""" Install some required tools.
"""
return {
'actions': [
'cargo install cargo-binutils',
f'rustup target add {consts.TARGET}',
'rustup component add llvm-tools-preview',
],
}
def task_check():
""" Run a compiler check on the code.
"""
task = {
'file_dep': get_build_dep(),
'actions': [f'RUSTFLAGS="{consts.RUSTC_FLAGS}" cargo check --target={consts.TARGET} {consts.CARGO_COMPILE_FLAGS}'],
}
print(task)
return task
def task_compile():
""" Compile the sources.
"""
task = {
'file_dep': get_build_dep(),
'targets': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'actions': [f'RUSTFLAGS="{consts.RUSTC_FLAGS}" cargo rustc --target={consts.TARGET} {consts.CARGO_COMPILE_FLAGS}'],
'clean': [f'cargo clean']
}
print(task)
return task
def task_build():
""" Strip the binary from ELF format to raw binary.
"""
return {
'file_dep': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'targets': [f'{consts.WORK_DIR}/consts.KERNEL_NAME'],
'actions': [
f'rust-objcopy --strip-all -O binary {consts.WORK_DIR}/target/{consts.TARGET}/release/kernel {consts.WORK_DIR}/{consts.KERNEL_NAME}',
],
'clean': True,
}
def task_qemu():
""" Run the kernel in qemu.
"""
if consts.QEMU_MACHINE is None:
raise Exception("qemu does not support emulation for this board yet")
r = {
'file_dep': [f'{consts.WORK_DIR}/{consts.KERNEL_NAME}'],
'uptodate': [False], # Always run the cmd
'actions': [Interactive(f'{consts.QEMU_CMD} -M {consts.QEMU_MACHINE} {consts.QEMU_ARGS} -kernel {consts.KERNEL_NAME}')],
}
print(r)
return r
def task_objdump():
""" Inspect the ELF binary file.
"""
r = {
'file_dep': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'uptodate': [False], # Always run the cmd
'actions': [Interactive(f'{consts.OBJDUMP_CMD} {consts.OBJDUMP_ARGS} {consts.WORK_DIR}/target/{consts.TARGET}/release/kernel')]
}
print(r)
return r