Skip to content

Commit

Permalink
Support aarch64 in the main Theseus workspace (theseus-os#817)
Browse files Browse the repository at this point in the history
Merges the separate `aarch64` workspace into the main workspace.

**Note that support for aarch64 is a WIP and does not fully boot yet.**

To build:
```bash
make ARCH=aarch64 FEATURES= CROSS=aarch64-linux-gnu- run
```

List of notable changes:
- renamed `logger` → `logger_x86_64` and aarch64 logger `logger_aarch64`.
- changed `theseus-os/pl011_qemu` so that the PL011 address isn't a fixed constant anymore; changed `logger_aarch64` to reflect that.
- arch-gated some dependencies of nano_core: dependencies either temporarily incompatible like `captain` or forever incompatible such as `vga_buffer`.
- made `context_switch_regular` cross-platform.
- modified `panic_entry` so that it builds for aarch64: arch-gated some dependencies and handling code, replaced latter with infinite loop.
- introduced an aarch64-specific linker script which is identical to the x86_64 one except for the kernel offset.
- Make `kernel_config::memory` arch-agnostic by using arch-specific address canonicalization.
- Modified Makefile to support building on aarch64. `boot_spec` = `uefi` is forced for aarch64 builds.
- `memory`: some flag changes, arch-gated VGA-specific code, added `tlb_flush_all()` for page table switching.
- EFI firmware is downloaded from <https://github.com/retrage/edk2-nightly> automatically
- new json target file: `cfg/aarch64-unknown-theseus.json`
- removed the aarch64 workspace

Co-authored-by: Kevin Boos <[email protected]>
  • Loading branch information
NathanRoyer and kevinaboos authored Feb 10, 2023
1 parent 346a116 commit 89489db
Show file tree
Hide file tree
Showing 66 changed files with 1,253 additions and 4,114 deletions.
67 changes: 59 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 57 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ debug ?= none
net ?= none
merge_sections ?= yes
bootloader ?= grub
boot_spec ?= bios

## aarch64 only supports booting via UEFI
ifeq ($(ARCH),aarch64)
boot_spec = uefi
else
boot_spec ?= bios
endif

## Set up configuration based on the chosen bootloader specification (boot_spec).
export override FEATURES+=--features nano_core/$(boot_spec)
Expand Down Expand Up @@ -74,7 +80,9 @@ else
endif

### Handle multiple bootloader options and ensure the corresponding tools are installed.
ifeq ($(bootloader),grub)
ifeq ($(boot_spec),uefi)
## A bootloader isn't required with UEFI.
else ifeq ($(bootloader),grub)
## Look for `grub-mkrescue` (Debian-like distros) or `grub2-mkrescue` (Fedora)
ifneq (,$(shell command -v $(GRUB_CROSS)grub-mkrescue))
GRUB_MKRESCUE = $(GRUB_CROSS)grub-mkrescue
Expand All @@ -90,8 +98,7 @@ else ifeq ($(bootloader),limine)
else
$(error Error: missing '$(LIMINE_DIR)' directory! Please follow the limine instructions in the README)
endif
# bootloader option isn't required for UEFI
else ifneq ($(boot_spec), uefi)
else
$(error Error: unsupported option "bootloader=$(bootloader)". Options are 'grub' or 'limine')
endif

Expand All @@ -107,10 +114,13 @@ nano_core_static_lib := $(ROOT_DIR)/target/$(TARGET)/$(BUILD_MODE)/libnano_core.
## The output file path of the fully-linked nano_core kernel binary.
nano_core_binary := $(NANO_CORE_BUILD_DIR)/nano_core-$(ARCH).bin
## The linker script for linking the `nano_core_binary` with the compiled assembly files.
linker_script := $(ROOT_DIR)/kernel/nano_core/linker_higher_half.ld
efi_firmware := $(BUILD_DIR)/ovmf.fd
linker_script := $(ROOT_DIR)/kernel/nano_core/linker_higher_half-$(ARCH).ld
efi_firmware := $(BUILD_DIR)/$(OVMF_FILE)

ifeq ($(ARCH),x86_64)
## The assembly files compiled by the nano_core build script.
compiled_nano_core_asm := $(NANO_CORE_BUILD_DIR)/compiled_asm/$(boot_spec)/*.o
endif

## Specify which crates should be considered as application-level libraries.
## These crates can be instantiated multiply (per-task, per-namespace) rather than once (system-wide);
Expand Down Expand Up @@ -176,18 +186,20 @@ full: iso
iso: $(iso)

### This target builds an .iso OS image from all of the compiled crates.
$(iso) $(efi_firmware): clean-old-build build extra_files copy_kernel $(bootloader)
ifeq ($(boot_spec), uefi)
@cargo r \
$(iso): clean-old-build build extra_files copy_kernel $(iso)-$(boot_spec)

## This target is invoked by the '$(iso)' target when boot_spec = 'bios'.
$(iso)-bios: $(bootloader)

## This target is invoked by the '$(iso)' target when boot_spec = 'uefi'.
$(iso)-uefi: $(efi_firmware)
@cargo run \
--release \
-Z bindeps \
--manifest-path \
$(ROOT_DIR)/tools/uefi_builder/x86_64/Cargo.toml -- \
--manifest-path $(ROOT_DIR)/tools/uefi_builder/$(ARCH)/Cargo.toml -- \
--kernel $(nano_core_binary) \
--modules $(OBJECT_FILES_BUILD_DIR) \
--efi-image $(iso) \
--efi-firmware $(efi_firmware)
endif
--efi-image $(iso)

## Copy the kernel boot image into the proper ISOFILES directory.
## Should be invoked after building all Theseus kernel/application crates.
Expand Down Expand Up @@ -337,7 +349,7 @@ endif

## This builds the nano_core binary itself, which is the fully-linked code that first runs right after the bootloader
$(nano_core_binary): cargo $(nano_core_static_lib) $(linker_script)
@$(CROSS)ld -n -T $(linker_script) -o $(nano_core_binary) $(compiled_nano_core_asm) $(nano_core_static_lib)
$(CROSS)ld -n -T $(linker_script) -o $(nano_core_binary) $(compiled_nano_core_asm) $(nano_core_static_lib)
## Dump readelf output for verification. See pull request #542 for more details:
## @RUSTFLAGS="" cargo run --release --manifest-path $(ROOT_DIR)/tools/demangle_readelf_file/Cargo.toml \
## <($(CROSS)readelf -s -W $(nano_core_binary) | sed '/OBJECT LOCAL .* str\./d;/NOTYPE LOCAL /d;/FILE LOCAL /d;/SECTION LOCAL /d;') \
Expand Down Expand Up @@ -384,6 +396,15 @@ limine:
@$(LIMINE_DIR)/limine-deploy $(iso)


## This downloads the OVMF EFI firmware, needed by QEMU to boot an EFI app.
##
## These binary files are built by Github user retrage at:
## https://github.com/retrage/edk2-nightly.
$(efi_firmware):
@echo -e "\033[1;34m\nDownloading prebuilt EFI firmware from GitHub...\033[0m"
@wget -nv --show-progress https://raw.githubusercontent.com/retrage/edk2-nightly/$(OVMF_COMMIT)/bin/$(OVMF_FILE) -O $(efi_firmware)


### This target copies all extra files into the `ISOFILES` directory,
### collapsing their directory structure into a single file name with `!` as the directory delimiter.
### The contents of the EXTRA_FILES directory will be available at runtime within Theseus's root fs, too.
Expand Down Expand Up @@ -507,7 +528,7 @@ simd_personality_sse: clean-old-build build_sse build
@echo -e "********* AT THE END OF SIMD_BUILD: TARGET = $(TARGET), KERNEL_PREFIX = $(KERNEL_PREFIX), APP_PREFIX = $(APP_PREFIX)"
$(MAKE) bootloader=$(bootloader) copy_kernel $(bootloader)
## run it in QEMU
qemu-system-x86_64 $(QEMU_FLAGS)
$(QEMU_BIN) $(QEMU_FLAGS)



Expand All @@ -524,7 +545,7 @@ simd_personality_avx: clean-old-build build_avx build
@echo -e "********* AT THE END OF SIMD_BUILD: TARGET = $(TARGET), KERNEL_PREFIX = $(KERNEL_PREFIX), APP_PREFIX = $(APP_PREFIX)"
$(MAKE) bootloader=$(bootloader) copy_kernel $(bootloader)
## run it in QEMU
qemu-system-x86_64 $(QEMU_FLAGS)
$(QEMU_BIN) $(QEMU_FLAGS)



Expand Down Expand Up @@ -760,7 +781,6 @@ help:
@echo -e "\t Other options include 'stdio' (the default for 'SERIAL1'), 'file', 'pipe', etc."
@echo -e "\t For more details, search the QEMU manual for '-serial dev'."


@echo -e "\nThe following make targets exist for building documentation:"
@echo -e " doc:"
@echo -e "\t Builds Theseus documentation from its Rust source code (rustdoc)."
Expand Down Expand Up @@ -797,6 +817,10 @@ endif
ifeq ($(boot_spec), bios)
QEMU_FLAGS += -cdrom $(iso) -boot d
else ifeq ($(boot_spec), uefi)
## We use `-bios` instead of `-pflash` because `-pflash` requires the file to be exactly 64MB.
## See:
## - https://wiki.qemu.org/Features/PC_System_Flash
## - https://github.com/tianocore/edk2/blob/316e6df/OvmfPkg/README#L68
QEMU_FLAGS += -bios $(efi_firmware)
QEMU_FLAGS += -drive format=raw,file=$(iso)
endif
Expand Down Expand Up @@ -831,18 +855,21 @@ QEMU_FLAGS += -m $(QEMU_MEMORY)
QEMU_CPUS ?= 4
QEMU_FLAGS += -smp $(QEMU_CPUS)

## QEMU's OUI dictates that the MAC addr start with "52:54:00:"
MAC_ADDR ?= 52:54:00:d1:55:01

## Add a disk drive, a PATA drive over an IDE controller interface.
## Currently this is only supported on x86_64.
DISK_IMAGE ?= fat32.img
ifeq ($(ARCH),x86_64)
ifneq ($(wildcard $(DISK_IMAGE)),)
QEMU_FLAGS += -drive format=raw,file=fat32.img,if=ide
endif
endif

## We don't yet support SATA in Theseus, but this is how to add a SATA drive over the AHCI interface.
# QEMU_FLAGS += -drive id=my_disk,file=$(DISK_IMAGE),if=none -device ahci,id=ahci -device ide-drive,drive=my_disk,bus=ahci.0

## QEMU's OUI dictates that the MAC addr start with "52:54:00:"
MAC_ADDR ?= 52:54:00:d1:55:01

## Read about QEMU networking options here: https://www.qemu.org/2018/05/31/nic-parameter/
ifeq ($(net),user)
## user-based networking setup with standard e1000 ethernet NIC
Expand All @@ -868,6 +895,10 @@ endif
ifeq ($(host),yes)
## KVM acceleration is required when using the host cpu model
QEMU_FLAGS += -cpu host -accel kvm
else ifeq ($(ARCH),aarch64)
QEMU_FLAGS += -machine virt
QEMU_FLAGS += -device ramfb
QEMU_FLAGS += -cpu cortex-a72
else
QEMU_FLAGS += -cpu Broadwell
endif
Expand All @@ -894,12 +925,12 @@ QEMU_FLAGS += $(QEMU_EXTRA)

### Old Run: runs the most recent build without rebuilding
orun:
qemu-system-x86_64 $(QEMU_FLAGS)
$(QEMU_BIN) $(QEMU_FLAGS)


### Old Run Pause: runs the most recent build without rebuilding but waits for a GDB connection.
orun_pause:
qemu-system-x86_64 $(QEMU_FLAGS) -S
$(QEMU_BIN) $(QEMU_FLAGS) -S


### builds and runs Theseus in loadable mode, where all crates are dynamically loaded.
Expand All @@ -913,13 +944,13 @@ wasmtime: run


### builds and runs Theseus in QEMU
run: $(iso)
qemu-system-x86_64 $(QEMU_FLAGS)
run: $(iso)
$(QEMU_BIN) $(QEMU_FLAGS)


### builds and runs Theseus in QEMU, but pauses execution until a GDB instance is connected.
run_pause: $(iso)
qemu-system-x86_64 $(QEMU_FLAGS) -S
$(QEMU_BIN) $(QEMU_FLAGS) -S


### Runs a gdb instance on the host machine.
Expand Down
Loading

0 comments on commit 89489db

Please sign in to comment.