BUILD: Makefile support for multiple architectures.

This commit is contained in:
Udo Steinberg 2019-02-11 11:53:13 +01:00
parent c28daeace7
commit 273a919a03
7 changed files with 293 additions and 244 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
Makefile.conf
build-*
*.patch

View File

@ -1,44 +0,0 @@
0.4
---
* IOMMU fault fixes.
* Secure device and GSI assignment using capabilities.
* BSP indicator passed to bootstrap EC and removed from HIP.
* Added revoke filtering.
* Root capability of newly created objects now stored in creator PD.
* Added SC control hypercall.
* Added SC execution time statistics.
* Added capability permissions for EC bind and EC/SC control
* Improved RCU grace period handling.
* Bug fixes.
0.3
---
* ACPI-based CPU numbering.
* Additional capability permissions.
* Capability translation.
* TSC offsetting.
* vTLB support for SVM (enables VM support under QEMU).
* Improved vTLB fills.
* Improved initialization, paging, and RCU.
* Bug fixes.
0.2
---
* Number of supported CPUs increased to 32.
* Number of supported GSIs increased to 128.
* Removed 8259 PIC mode and made IOAPIC a requirement.
* Root PD no longer holds GSI capabilities at bootup.
* Incoming portal id no longer stored in UTCB.
* New mapping database and lookup hypercall.
* Selective memory delegation (host/guest/IOMMU).
* Revocation of platform resources (mem/IO).
* PCI topology discovery.
* VT-d interrupt remapping.
* Direct assignment of PCI devices and GSIs to PDs.
* VMX unrestricted guest.
* vTLB page splintering.
* Bug fixes.
0.1
---
* Initial release

193
Makefile Normal file
View File

@ -0,0 +1,193 @@
#
# Makefile
#
# Copyright (C) 2009-2011 Udo Steinberg <udo@hypervisor.org>
# Economic rights: Technische Universitaet Dresden (Germany)
#
# Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation.
# Copyright (C) 2019-2025 Udo Steinberg, BlueRock Security, Inc.
#
# This file is part of the NOVA microhypervisor.
#
# NOVA is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# NOVA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License version 2 for more details.
#
-include Makefile.conf
# Defaults
ARCH ?= x86_64
BOARD ?= acpi
COMP ?= gcc
# Tools
INSTALL ?= install -m 644
MKDIR ?= mkdir -p
ifeq ($(COMP),gcc)
HST_CC ?= g++
TGT_CC := $(PREFIX_$(ARCH))g++
TGT_LD := $(PREFIX_$(ARCH))ld
TGT_OC := $(PREFIX_$(ARCH))objcopy
TGT_SZ := $(PREFIX_$(ARCH))size
else
$(error $(COMP) is not a valid compiler type)
endif
H2E := $(H2E_$(ARCH))
H2B := $(H2B_$(ARCH))
RUN := $(RUN_$(ARCH))
# In-place editing works differently between GNU/BSD sed
SEDI := $(shell if sed --version 2>/dev/null | grep -q GNU; then echo "sed -i"; else echo "sed -i ''"; fi)
# Directories
CMD_DIR := cmd
SRC_DIR := src
INC_DIR := include
# Patterns
PAT_CMD := $(BLD_DIR)/%
PAT_OBJ := $(BLD_DIR)/$(ARCH)-%.o
# Files
MFL := $(MAKEFILE_LIST)
SRC := hypervisor.ld $(sort $(wildcard $(SRC_DIR)/*.S)) $(sort $(wildcard $(SRC_DIR)/*.cpp))
OBJ := $(patsubst %.ld,$(PAT_OBJ), $(patsubst %.S,$(PAT_OBJ), $(patsubst %.cpp,$(PAT_OBJ), $(notdir $(SRC)))))
OBJ_DEP := $(OBJ:%.o=%.d)
HYP := $(BLD_DIR)/$(ARCH)-nova
ELF := $(HYP).elf
BIN := $(HYP).bin
# Messages
ifneq ($(findstring s,$(MAKEFLAGS)),)
message = @echo $(1) $(2)
endif
# Tool check
tools = $(if $(shell command -v $($(1)) 2>/dev/null),, $(error Missing $(1)=$($(1)) *** Configure it in Makefile.conf (see Makefile.conf.example)))
# Feature check
check = $(shell if $(TGT_CC) $(1) -Werror -c -xc++ /dev/null -o /dev/null >/dev/null 2>&1; then echo "$(1)"; fi)
# Version check
gitrv = $(shell (git rev-parse HEAD 2>/dev/null || echo 0) | cut -c1-7)
# Search path
VPATH := $(SRC_DIR)
# Optimization options
DFLAGS := -MP -MMD -pipe
OFLAGS := -Os
ifeq ($(ARCH),x86_64)
AFLAGS := -Wa,--divide,--noexecstack -march=x86-64-v2 -mcmodel=kernel -mgeneral-regs-only -mno-red-zone
else
$(error $(ARCH) is not a valid architecture)
endif
# Preprocessor options
PFLAGS := $(addprefix -D, $(DEFINES)) $(addprefix -I, $(INC_DIR))
# Language options
FFLAGS := $(or $(call check,-std=gnu++26), $(call check,-std=gnu++23), $(call check,-std=gnu++20))
FFLAGS += -ffreestanding -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fomit-frame-pointer
FFLAGS += $(call check,-fdiagnostics-color=auto)
FFLAGS += $(call check,-fno-pic)
FFLAGS += $(call check,-fno-stack-protector)
FFLAGS += $(call check,-freg-struct-return)
FFLAGS += $(call check,-freorder-blocks)
# Warning options
WFLAGS := -Wall -Wextra -Walloca -Wcast-align -Wcast-qual -Wconversion -Wctor-dtor-privacy -Wdisabled-optimization -Wduplicated-branches -Wduplicated-cond -Wenum-conversion -Wextra-semi -Wformat=2 -Wmismatched-tags -Wmissing-format-attribute -Wmissing-noreturn -Wmultichar -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wpacked -Wpointer-arith -Wredundant-decls -Wredundant-tags -Wregister -Wshadow -Wsign-promo -Wvirtual-inheritance -Wvolatile -Wwrite-strings
WFLAGS += $(call check,-Wbidi-chars=any)
WFLAGS += $(call check,-Wlogical-op)
WFLAGS += $(call check,-Wstrict-null-sentinel)
WFLAGS += $(call check,-Wstrict-overflow=5)
WFLAGS += $(call check,-Wsuggest-override)
WFLAGS += $(call check,-Wvolatile-register-var)
WFLAGS += $(call check,-Wzero-as-null-pointer-constant)
ifeq ($(ARCH),aarch64)
WFLAGS += $(call check,-Wpedantic)
endif
# Compiler flags
CFLAGS := $(PFLAGS) $(DFLAGS) $(AFLAGS) $(FFLAGS) $(OFLAGS) $(WFLAGS)
# Linker flags
LFLAGS := --defsym=GIT_VER=0x$(call gitrv) --gc-sections --warn-common -static -n -s -T
# Rules
$(HYP): $(OBJ)
$(call message,LNK,$@)
$(TGT_LD) $(LFLAGS) $^ -o $@
$(ELF): $(HYP)
$(call message,ELF,$@)
$(H2E) $< $@
$(BIN): $(HYP)
$(call message,BIN,$@)
$(H2B) $< $@
$(PAT_OBJ): %.ld
$(call message,PRE,$@)
$(TGT_CC) $(CFLAGS) -xassembler-with-cpp -E -P -MT $@ $< -o $@
@$(SEDI) 's|$<|$(notdir $<)|' $(@:%.o=%.d)
$(PAT_OBJ): %.S
$(call message,ASM,$@)
$(TGT_CC) $(CFLAGS) -c $< -o $@
@$(SEDI) 's|$<|$(notdir $<)|' $(@:%.o=%.d)
$(PAT_OBJ): %.cpp
$(call message,CXX,$@)
$(TGT_CC) $(CFLAGS) -c $< -o $@
@$(SEDI) 's|$<|$(notdir $<)|' $(@:%.o=%.d)
$(PAT_CMD): $(CMD_DIR)/%.cpp
$(call message,CMD,$@)
$(HST_CC) $< -o $@
$(BLD_DIR):
$(call message,DIR,$@)
@$(MKDIR) $@
Makefile.conf:
$(call message,CFG,$@)
@cp $@.example $@
$(OBJ): $(MFL) | $(BLD_DIR) tool_tgt_cc
# Zap old-fashioned suffixes
.SUFFIXES:
.PHONY: clean install run tool_hst_cc tool_tgt_cc
clean:
$(call message,CLN,$@)
$(RM) $(OBJ) $(HYP) $(ELF) $(BIN) $(OBJ_DEP)
install: $(HYP)
$(call message,INS,$^ =\> $(INS_DIR))
$(INSTALL) $^ $(INS_DIR)
@$(TGT_SZ) $<
run: $(ELF)
$(RUN) $<
tool_hst_cc:
$(call tools,HST_CC)
tool_tgt_cc:
$(call tools,TGT_CC)
# Include Dependencies
ifneq ($(MAKECMDGOALS),clean)
-include $(OBJ_DEP)
endif

55
Makefile.conf.example Normal file
View File

@ -0,0 +1,55 @@
#
# Makefile.conf
#
# Copyright (C) 2019-2025 Udo Steinberg, BlueRock Security, Inc.
#
# This file is part of the NOVA microhypervisor.
#
# NOVA is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# NOVA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License version 2 for more details.
#
#############################################################################
# Makefile.conf can be used to configure the build environment permanently. #
# See Makefile.conf.example for an up-to-date configuration template. #
#############################################################################
# Configure target architecture
# Permitted values are: aarch64, x86_64
ARCH ?= x86_64
# Configure board (for aarch64)
# Permitted values are listed in README.md
BOARD ?= acpi
# Configure compiler type
# Permitted values are: gcc
COMP ?= gcc
# Configure build directory
BLD_DIR ?= build-$(ARCH)
# Configure install directory
INS_DIR ?= /home/tftp/nova
# Configure cross-toolchain prefix (see README.md)
PREFIX_aarch64 ?= # set your own, e.g. /opt/aarch64-linux/bin/aarch64-linux-
PREFIX_x86_64 ?= # set your own, e.g. /opt/x86_64-linux/bin/x86_64-linux-
# Configure architecture-specific ELF image tweaks
H2E_aarch64 ?= ln -frs
H2E_x86_64 ?= $(TGT_OC) -O elf32-i386
# Configure architecture-specific BIN image tweaks
H2B_aarch64 ?= $(TGT_OC) -O binary
H2B_x86_64 ?= $(TGT_OC) -O binary
# Configure architecture-specific run targets
RUN_aarch64 ?= qemu-system-aarch64 -m 512 -smp 4 -no-reboot -display none -serial mon:stdio -cpu max -M virt,virtualization=on,secure=off,gic-version=2,iommu=smmuv3 -kernel
RUN_x86_64 ?= qemu-system-x86_64 -m 512 -smp 4 -no-reboot -display none -serial mon:stdio -cpu host,vmx -M q35,accel=kvm,kernel-irqchip=split -enable-kvm -device intel-iommu,intremap=on -kernel

112
README.md
View File

@ -1,5 +1,4 @@
NOVA Microhypervisor
====================
# NOVA Microhypervisor
This is the source code for the NOVA microhypervisor.
@ -19,95 +18,72 @@ the microhypervisor.
**This code is experimental and not feature complete. If it breaks, you get
to keep both pieces.**
## Building
Supported platforms
-------------------
### Required Tools
The NOVA microhypervisor runs on single- and multi-processor x86 machines
that support ACPI.
The following tools are required to compile the source code:
The virtualization features are available on:
| **Tool** | **Minimum Version** | **Available From** |
| :------- | :-----------------: | :-------------------------------- |
| binutils | 2.38 | https://ftp.gnu.org/gnu/binutils/ |
| gcc | 12.4 | https://ftp.gnu.org/gnu/gcc/ |
| make | 4.0 | https://ftp.gnu.org/gnu/make/ |
- Intel CPUs with VMX,
regardless of whether the CPU supports nested paging (EPT) or not.
### Build Environment
- AMD CPUs with SVM,
regardless of whether the CPU supports nested paging (NPT) or not.
The build environment can be customized permanently in `Makefile.conf` or
ad hoc by passing the applicable `ARCH`, `BOARD` and `PREFIX_` variables to
the invocation of `make` as described below.
- `PREFIX_aarch64` sets the path for an **ARMv8-A** cross-toolchain
- `PREFIX_x86_64` sets the path for an **x86 (64bit)** cross-toolchain
Building from source code
-------------------------
For example, if the ARMv8-A cross-toolchain is located at
```
/opt/aarch64-linux/bin/aarch64-linux-gcc
/opt/aarch64-linux/bin/aarch64-linux-as
/opt/aarch64-linux/bin/aarch64-linux-ld
```
You need the following tools to compile the source code:
then set `PREFIX_aarch64=/opt/aarch64-linux/bin/aarch64-linux-`
- make 3.81 or higher,
available from http://www.gnu.org/software/make/
### Supported Architectures
- binutils 2.21.51.0.3 or higher,
available from http://www.kernel.org/pub/linux/devel/binutils/
#### ARMv8-A (64bit)
- gcc, available from http://gcc.gnu.org/
- for x86_32: gcc 4.2 or higher
- for x86_64: gcc 4.5 or higher
For CPUs with ARMv8-A architecture and boards with
- either Advanced Configuration and Power Interface (ACPI)
- or Flattened Device Tree (FDT)
#### x86 (64bit)
You can build a 32-bit microhypervisor binary as follows:
For CPUs with x86 architecture
- Intel VT-x (VMX+EPT) + optionally VT-d
- AMD-V (SVM+NPT)
cd build; make ARCH=x86_32
and boards with Advanced Configuration and Power Interface (ACPI).
You can build a 64-bit microhypervisor binary as follows:
| **Platform** | **Build Command** |
| :------------------------------------ | :----------------- |
| Generic x86 ACPI Platform | `make ARCH=x86_64` |
cd build; make ARCH=x86_64
## Booting
See the NOVA interface specification in the `doc` directory for details
regarding booting the NOVA microhypervisor.
Booting
-------
## License
The NOVA microhypervisor can be started from a multiboot-compliant
bootloader, such as GRUB or PXEGRUB. Here are some examples:
Boot from harddisk 0, partition 0
title NOVA
kernel (hd0,0)/boot/nova/hypervisor
module (hd0,0)/...
...
Boot from TFTP server aa.bb.cc.dd
title NOVA
tftpserver aa.bb.cc.dd
kernel (nd)/boot/nova/hypervisor
module (nd)/...
...
Command-Line Parameters
-----------------------
The following command-line parameters are supported for the microhypervisor.
They must be separated by spaces.
- *iommu* - Enables DMA and interrupt remapping.
- *keyb* - Enables the microhypervisor to drive the keyboard.
- *serial* - Enables the microhypervisor to drive the serial console.
- *spinner* - Enables event spinners.
- *vtlb* - Forces use of vTLB instead of nested paging (EPT/NPT).
- *nopcid* - Disables TLB tags for address spaces.
- *novga* - Disables VGA console.
- *novpid* - Disables TLB tags for virtual machines.
License
-------
The NOVA source code is licensed under the GPL version 2.
The NOVA source code is licensed under the **GPL version 2**.
```
Copyright (C) 2009-2011 Udo Steinberg <udo@hypervisor.org>
Economic rights: Technische Universitaet Dresden (Germany)
Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation.
Copyright (C) 2014 Udo Steinberg, FireEye, Inc.
Copyright (C) 2019-2025 Udo Steinberg, BlueRock Security, Inc.
NOVA is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
@ -119,8 +95,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License version 2 for more details.
```
Contact
-------
## Contact
Feedback and comments should be sent to udo@hypervisor.org

3
build/.gitignore vendored
View File

@ -1,3 +0,0 @@
hypervisor-*
*.[od]
*~

View File

@ -1,128 +0,0 @@
#
# Makefile
#
# Copyright (C) 2009-2011 Udo Steinberg <udo@hypervisor.org>
# Economic rights: Technische Universitaet Dresden (Germany)
#
# Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation.
#
# This file is part of the NOVA microhypervisor.
#
# NOVA is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# NOVA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License version 2 for more details.
#
ARCH ?= x86_32
CC := gcc
ECHO := echo
INSTALL := install
LD := ld
RM := rm -f
SIZE := size
SRC_DIR := ../src
INC_DIR := ../include
INS_DIR ?= /boot/tftp/nova
TARGET := hypervisor-$(ARCH)
SRC := hypervisor.ld $(sort $(wildcard $(SRC_DIR)/*.S)) $(sort $(wildcard $(SRC_DIR)/*.cpp))
OBJ := $(notdir $(patsubst %.ld,%-$(ARCH).o, $(patsubst %.S,%-$(ARCH).o, $(patsubst %.cpp,%-$(ARCH).o, $(SRC)))))
DEP := $(patsubst %.o,%.d, $(OBJ))
# Messages
ifneq ($(findstring s,$(MAKEFLAGS)),)
message = @$(ECHO) $(1) $(2)
endif
# Feature check
check = $(shell if $(CC) $(1) -c -xc++ /dev/null -o /dev/null >/dev/null 2>&1; then echo "$(1)"; fi)
gitrv = $(shell (git rev-parse HEAD 2>/dev/null || echo 0) | cut -c1-7)
# Preprocessor options
DEFINES :=
VPATH := $(SRC_DIR)
PFLAGS := $(addprefix -D, $(DEFINES)) $(addprefix -I, $(INC_DIR))
# Optimization options
DFLAGS := -MP -MMD -pipe
OFLAGS := -Os
ifeq ($(ARCH),x86_32)
AFLAGS := -m32 -march=i686 -mpreferred-stack-boundary=2 -mregparm=3
else ifeq ($(ARCH),x86_64)
AFLAGS := -m64 -march=core2 -mpreferred-stack-boundary=4 -mcmodel=kernel -mno-red-zone
else
$(error $(ARCH) is not a valid architecture)
endif
# Language options
FFLAGS := -fdata-sections -ffunction-sections -fomit-frame-pointer -freg-struct-return -freorder-blocks -funit-at-a-time
FFLAGS += -fno-asynchronous-unwind-tables -fno-exceptions -fno-rtti
FFLAGS += $(call check,-fno-stack-protector)
FFLAGS += $(call check,-fvisibility-inlines-hidden)
FFLAGS += $(call check,-fdiagnostics-color=auto)
FFLAGS += $(or $(call check,-std=gnu++11), $(call check,-std=gnu++0x), $(call check,-std=gnu++98))
# Warning options
WFLAGS := -Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual -Wconversion -Wdisabled-optimization -Wformat=2 -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wshadow -Wwrite-strings
WFLAGS += -Wabi -Wctor-dtor-privacy -Wno-non-virtual-dtor -Wold-style-cast -Woverloaded-virtual -Wsign-promo
WFLAGS += $(call check,-Wframe-larger-than=64)
WFLAGS += $(call check,-Wlogical-op)
WFLAGS += $(call check,-Wstrict-null-sentinel)
WFLAGS += $(call check,-Wstrict-overflow=5)
WFLAGS += $(call check,-Wvolatile-register-var)
WFLAGS += $(call check,-Wzero-as-null-pointer-constant)
# Compiler flags
SFLAGS := $(PFLAGS) $(DFLAGS) $(AFLAGS)
CFLAGS := $(PFLAGS) $(DFLAGS) $(AFLAGS) $(OFLAGS) $(FFLAGS) $(WFLAGS)
# Linker flags
LFLAGS := --defsym=GIT_VER=0x$(call gitrv) --gc-sections --warn-common -static -n -T
# Rules
%-$(ARCH).o: %.ld $(MAKEFILE_LIST)
$(call message,PRE,$@)
$(CC) $(SFLAGS) -xc -E -P -MT $@ $< -o $@
%-$(ARCH).o: %.S $(MAKEFILE_LIST)
$(call message,ASM,$@)
$(CC) $(SFLAGS) -c $< -o $@
%-$(ARCH).o: %.cpp $(MAKEFILE_LIST)
$(call message,CMP,$@)
$(CC) $(CFLAGS) -c $< -o $@
$(TARGET): $(OBJ)
$(call message,LNK,$@)
$(LD) $(LFLAGS) $^ -o $@
.PHONY: install
.PHONY: clean
.PHONY: cleanall
install: $(TARGET)
$(call message,INS,$@)
$(INSTALL) -s -m 644 $(TARGET) $(INS_DIR)
@$(SIZE) $<
clean:
$(call message,CLN,$@)
$(RM) $(OBJ) $(TARGET)
cleanall: clean
$(call message,CLN,$@)
$(RM) $(DEP)
# Include Dependencies
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),cleanall)
-include $(DEP)
endif
endif