147 lines
4.8 KiB
Python
147 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
|