This patch introduces new build mechanism that allows creating
custom kernel with specific list of device drivers intended to target
given hypervisor. Such kernel benefits from smaller size and better
security as all unneeded code is removed. This patch partially addresses
the modularization/librarization functionality as explained by the issue
#1110 and this part of the roadmap -
https://github.com/cloudius-systems/osv/wiki/Roadmap#modularizationlibrarization.
This idea was also mentioned in the P99 OSv presentation - see slide 11.
In essence, we introduce new build script and makefile parameter:
`drivers_profile`. This new parameter is intended to specify a
drivers profile which is simply a list of device drivers to be linked
into kernel with some extra functionality like PCI or ACPI these drivers
depend on. Each profile is specified in a tiny make include file (*.mk)
under new conf/profiles/$(arch) directory and included by the main
makefile as requested by drivers_profile parameter. The main makefile
has number of new ifeq conditions that add given driver object file
to the linked objects list depending on the value (0 or 1) of given
conf_drivers_* variable specified in the relevant profile file.
Sometimes it is necessary to conditionally enable/disable given
code depending on the drivers selected. The good example of it is
arch-setup.cc which actually registers individual drivers and this
is where we need some kind of #if-way of registering given driver.
To that end, this patch adds new script gen-drivers-config-header and
new rule to the makefile, which automatically generates driver-config.h
header file under build/$(mode)/gen/include/osv. The driver-config.h
is comprised of the #define CONF_drivers_* macros that specify if given
driver is enabled or not (1, 0) and is included by relatively few source
file like arch-setup.cc. The extra benefit of this approach is that
every time we change value of drivers_profile, all relevant files are
recompiled and new kernel linked.
Most of the patch are changes to the relevant source file to include
new #if CONF_drivers_* conditional logic, changes to the main makefile
to conditionality link specific object files and new makefile include
file under conf/profiles/.
The benefits of using drivers are most profound when building kernel
with most symbols hidden. Below you can see examples of some build
commands along with the kernel size produced:
./scripts/build fs=rofs conf_hide_symbols=1 image=native-example #all
3632K build/release/kernel-stripped.elf
./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
3380K build/release/kernel-stripped.elf
./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=vmware
3308K build/release/kernel-stripped.elf
./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-mmio
3120K build/release/kernel-stripped.elf
./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=base #most drivers out
3036K build/release/kernel-stripped.elf
Partially addresses #1110
Signed-off-by: Waldemar Kozaczuk <
jwkoz...@gmail.com>
---
Makefile | 109 ++++++++++++++++++++++++--
arch/aarch64/arch-dtb.cc | 7 ++
arch/aarch64/arch-setup.cc | 41 +++++++++-
arch/aarch64/boot.S | 3 +
arch/aarch64/cpuid.cc | 5 ++
arch/aarch64/xen.cc | 1 +
arch/x64/apic.cc | 1 +
arch/x64/arch-setup.cc | 74 +++++++++++++++++
arch/x64/cpuid.cc | 15 ++++
arch/x64/entry-xen.S | 5 ++
arch/x64/power.cc | 9 +++
arch/x64/smp.cc | 9 +++
arch/x64/xen.cc | 1 +
conf/profiles/README.md | 71 +++++++++++++++++
conf/profiles/aarch64/
all.mk | 5 ++
conf/profiles/aarch64/
base.mk | 26 ++++++
conf/profiles/aarch64/
microvm.mk | 1 +
conf/profiles/aarch64/
virtio-mmio.mk | 4 +
conf/profiles/aarch64/
virtio-pci.mk | 6 ++
conf/profiles/aarch64/
xen.mk | 2 +
conf/profiles/x64/
all.mk | 8 ++
conf/profiles/x64/
base.mk | 74 +++++++++++++++++
conf/profiles/x64/
cloud_hypervisor.mk | 2 +
conf/profiles/x64/
hyperv.mk | 6 ++
conf/profiles/x64/
microvm.mk | 1 +
conf/profiles/x64/
vbox.mk | 8 ++
conf/profiles/x64/
virtio-mmio.mk | 4 +
conf/profiles/x64/
virtio-pci.mk | 10 +++
conf/profiles/x64/
vmware.mk | 10 +++
conf/profiles/x64/
xen.mk | 6 ++
core/xen_intr.cc | 1 +
drivers/acpi.cc | 9 ++-
drivers/hpet.cc | 9 +++
drivers/pci-generic.cc | 5 ++
drivers/virtio-blk.cc | 5 ++
drivers/virtio-fs.cc | 5 ++
drivers/virtio-net.cc | 5 ++
drivers/xenclock.cc | 1 +
drivers/xenfront-xenbus.cc | 1 +
drivers/xenplatform-pci.cc | 1 +
fs/vfs/vfs_conf.cc | 7 ++
include/osv/xen.hh | 4 +
loader.cc | 9 +++
runtime.cc | 5 ++
scripts/gen-drivers-config-header | 40 ++++++++++
45 files changed, 621 insertions(+), 10 deletions(-)
create mode 100644 conf/profiles/README.md
create mode 100644 conf/profiles/aarch64/
all.mk
create mode 100644 conf/profiles/aarch64/
base.mk
create mode 120000 conf/profiles/aarch64/
microvm.mk
create mode 100644 conf/profiles/aarch64/
virtio-mmio.mk
create mode 100644 conf/profiles/aarch64/
virtio-pci.mk
create mode 100644 conf/profiles/aarch64/
xen.mk
create mode 100644 conf/profiles/x64/
all.mk
create mode 100644 conf/profiles/x64/
base.mk
create mode 100644 conf/profiles/x64/
cloud_hypervisor.mk
create mode 100644 conf/profiles/x64/
hyperv.mk
create mode 120000 conf/profiles/x64/
microvm.mk
create mode 100644 conf/profiles/x64/
vbox.mk
create mode 100644 conf/profiles/x64/
virtio-mmio.mk
create mode 100644 conf/profiles/x64/
virtio-pci.mk
create mode 100644 conf/profiles/x64/
vmware.mk
create mode 100644 conf/profiles/x64/
xen.mk
create mode 100755 scripts/gen-drivers-config-header
diff --git a/Makefile b/Makefile
index 59cc6de4..c1c0eb84 100644
--- a/Makefile
+++ b/Makefile
@@ -82,6 +82,25 @@ ifeq (,$(wildcard conf/$(arch).mk))
endif
include conf/$(arch).mk
+# This parameter can be passed in to the build command to specify name of
+# a drivers profile. The drivers profile allows to build custom kernel with
+# a specific set of drivers enabled in the corresponding makefile include
+# file - conf/profiles/$(arch)/$(drivers_profile).mk). The default profile is
+# 'all' which incorporates all drivers into kernel.
+# In general the profiles set variables named conf_drivers_*, which then in turn
+# are used in the rules below to decide which object files are linked into
+# kernel.
+drivers_profile?=all
+ifeq (,$(wildcard conf/profiles/$(arch)/$(drivers_profile).mk))
+ $(error unsupported drivers profile $(drivers_profile))
+endif
+include conf/profiles/$(arch)/$(drivers_profile).mk
+# The base profile disables all drivers unless they are explicitly enabled
+# by the profile file included in the line above. The base profile also enforces
+# certain dependencies between drivers, for example the ide driver needs pci support, etc.
+# For more details please read comments in the profile file.
+include conf/profiles/$(arch)/
base.mk
+
CROSS_PREFIX ?= $(if $(filter-out $(arch),$(host_arch)),$(arch)-linux-gnu-)
CXX=$(CROSS_PREFIX)g++
CC=$(CROSS_PREFIX)gcc
@@ -617,10 +636,13 @@ bsd += bsd/sys/netinet/cc/cc_cubic.o
bsd += bsd/sys/netinet/cc/cc_htcp.o
bsd += bsd/sys/netinet/cc/cc_newreno.o
bsd += bsd/sys/netinet/arpcache.o
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/evtchn.o
+endif
ifeq ($(arch),x64)
$(out)/bsd/%.o: COMMON += -DXEN -DXENHVM
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/gnttab.o
bsd += bsd/sys/xen/xenstore/xenstore.o
bsd += bsd/sys/xen/xenbus/xenbus.o
@@ -628,8 +650,11 @@ bsd += bsd/sys/xen/xenbus/xenbusb.o
bsd += bsd/sys/xen/xenbus/xenbusb_front.o
bsd += bsd/sys/dev/xen/netfront/netfront.o
bsd += bsd/sys/dev/xen/blkfront/blkfront.o
+endif
+ifeq ($(conf_drivers_hyperv),1)
bsd += bsd/sys/dev/hyperv/vmbus/hyperv.o
endif
+endif
bsd += bsd/sys/dev/random/hash.o
bsd += bsd/sys/dev/random/randomdev_soft.o
@@ -817,54 +842,101 @@ drivers += drivers/random.o
drivers += drivers/zfs.o
drivers += drivers/null.o
drivers += drivers/device.o
+ifeq ($(conf_drivers_pci),1)
drivers += drivers/pci-generic.o
drivers += drivers/pci-device.o
drivers += drivers/pci-function.o
drivers += drivers/pci-bridge.o
+endif
drivers += drivers/driver.o
ifeq ($(arch),x64)
+ifeq ($(conf_drivers_vga),1)
drivers += $(libtsm)
-drivers += drivers/vga.o drivers/kbd.o drivers/isa-serial.o
+drivers += drivers/vga.o
+endif
+drivers += drivers/kbd.o drivers/isa-serial.o
drivers += arch/$(arch)/pvclock-abi.o
+
+ifeq ($(conf_drivers_virtio),1)
drivers += drivers/virtio.o
+ifeq ($(conf_drivers_pci),1)
drivers += drivers/virtio-pci-device.o
+endif
drivers += drivers/virtio-vring.o
+ifeq ($(conf_drivers_mmio),1)
drivers += drivers/virtio-mmio.o
+endif
drivers += drivers/virtio-net.o
-drivers += drivers/vmxnet3.o
-drivers += drivers/vmxnet3-queues.o
drivers += drivers/virtio-blk.o
drivers += drivers/virtio-scsi.o
drivers += drivers/virtio-rng.o
drivers += drivers/virtio-fs.o
-drivers += drivers/kvmclock.o drivers/xenclock.o drivers/hypervclock.o
+endif
+
+ifeq ($(conf_drivers_vmxnet3),1)
+drivers += drivers/vmxnet3.o
+drivers += drivers/vmxnet3-queues.o
+endif
+drivers += drivers/kvmclock.o
+ifeq ($(conf_drivers_hyperv),1)
+drivers += drivers/hypervclock.o
+endif
+ifeq ($(conf_drivers_acpi),1)
drivers += drivers/acpi.o
+endif
+ifeq ($(conf_drivers_hpet),1)
drivers += drivers/hpet.o
-drivers += drivers/rtc.o
-drivers += drivers/xenfront.o drivers/xenfront-xenbus.o drivers/xenfront-blk.o
+endif
+ifeq ($(conf_drivers_pvpanic),1)
drivers += drivers/pvpanic.o
+endif
+drivers += drivers/rtc.o
+ifeq ($(conf_drivers_ahci),1)
drivers += drivers/ahci.o
-drivers += drivers/ide.o
+endif
+ifeq ($(conf_drivers_scsi),1)
drivers += drivers/scsi-common.o
+endif
+ifeq ($(conf_drivers_ide),1)
+drivers += drivers/ide.o
+endif
+ifeq ($(conf_drivers_pvscsi),1)
drivers += drivers/vmw-pvscsi.o
+endif
+
+ifeq ($(conf_drivers_xen),1)
+drivers += drivers/xenclock.o
+drivers += drivers/xenfront.o drivers/xenfront-xenbus.o drivers/xenfront-blk.o
drivers += drivers/xenplatform-pci.o
+endif
endif # x64
ifeq ($(arch),aarch64)
drivers += drivers/mmio-isa-serial.o
drivers += drivers/pl011.o
drivers += drivers/pl031.o
+ifeq ($(conf_drivers_cadence),1)
drivers += drivers/cadence-uart.o
+endif
+ifeq ($(conf_drivers_xen),1)
drivers += drivers/xenconsole.o
+endif
+
+ifeq ($(conf_drivers_virtio),1)
drivers += drivers/virtio.o
+ifeq ($(conf_drivers_pci),1)
drivers += drivers/virtio-pci-device.o
+endif
+ifeq ($(conf_drivers_mmio),1)
drivers += drivers/virtio-mmio.o
+endif
drivers += drivers/virtio-vring.o
drivers += drivers/virtio-rng.o
drivers += drivers/virtio-blk.o
drivers += drivers/virtio-net.o
drivers += drivers/virtio-fs.o
+endif
endif # aarch64
objects += arch/$(arch)/arch-trace.o
@@ -883,11 +955,15 @@ objects += arch/$(arch)/cpuid.o
objects += arch/$(arch)/firmware.o
objects += arch/$(arch)/hypervisor.o
objects += arch/$(arch)/interrupt.o
+ifeq ($(conf_drivers_pci),1)
objects += arch/$(arch)/pci.o
objects += arch/$(arch)/msi.o
+endif
objects += arch/$(arch)/power.o
objects += arch/$(arch)/feexcept.o
+ifeq ($(conf_drivers_xen),1)
objects += arch/$(arch)/xen.o
+endif
$(out)/arch/x64/string-ssse3.o: CXXFLAGS += -mssse3
@@ -917,10 +993,14 @@ objects += arch/x64/entry-xen.o
objects += arch/x64/vmlinux.o
objects += arch/x64/vmlinux-boot64.o
objects += arch/x64/pvh-boot.o
+ifeq ($(conf_drivers_acpi),1)
objects += $(acpi)
+endif
endif # x64
+ifeq ($(conf_drivers_xen),1)
objects += core/xen_intr.o
+endif
objects += core/math.o
objects += core/spinlock.o
objects += core/lfmutex.o
@@ -1847,9 +1927,11 @@ fs_objs += rofs/rofs_vfsops.o \
rofs/rofs_cache.o \
rofs/rofs_common.o
+ifeq ($(conf_drivers_virtio),1)
fs_objs += virtiofs/virtiofs_vfsops.o \
virtiofs/virtiofs_vnops.o \
virtiofs/virtiofs_dax.o
+endif
fs_objs += pseudofs/pseudofs.o
fs_objs += procfs/procfs_vnops.o
@@ -2055,7 +2137,7 @@ $(out)/tools/cpiod/cpiod.so: $(out)/tools/cpiod/cpiod.o $(out)/tools/cpiod/cpio.
# re-created on every compilation. "generated-headers" is used as an order-
# only dependency on C compilation rules above, so we don't try to compile
# C code before generating these headers.
-generated-headers: $(out)/gen/include/bits/alltypes.h perhaps-modify-version-h
+generated-headers: $(out)/gen/include/bits/alltypes.h perhaps-modify-version-h perhaps-modify-drivers-config-h
.PHONY: generated-headers
# While other generated headers only need to be generated once, version.h
@@ -2066,6 +2148,17 @@ perhaps-modify-version-h:
$(call quiet, sh scripts/gen-version-header $(out)/gen/include/osv/version.h, GEN gen/include/osv/version.h)
.PHONY: perhaps-modify-version-h
+# Using 'if ($(conf_drivers_*),1)' in the rules below is enough to include whole object
+# files. Sometimes though we need to enable or disable portions of the code specific
+# to given driver (the arch-setup.cc is best example). To that end the rule below
+# generates drivers_config.h header file with the macros CONF_drivers_* which is
+# then included by relevant source files.
+# This allows for fairly rapid rebuilding of the kernel for specified profiles
+# as only few files need to be re-compiled.
+perhaps-modify-drivers-config-h:
+ $(call quiet, sh scripts/gen-drivers-config-header $(arch) $(out)/gen/include/osv/drivers_config.h, GEN gen/include/osv/drivers_config.h)
+.PHONY: perhaps-modify-drivers-config-h
+
$(out)/gen/include/bits/alltypes.h: include/api/$(arch)/bits/
alltypes.h.sh
$(makedir)
$(call quiet, sh $^ > $@, GEN $@)
diff --git a/arch/aarch64/arch-dtb.cc b/arch/aarch64/arch-dtb.cc
index 63db8b00..7a7ef51f 100644
--- a/arch/aarch64/arch-dtb.cc
+++ b/arch/aarch64/arch-dtb.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <osv/types.h>
#include <osv/debug.h>
#include <stdlib.h>
@@ -16,7 +17,9 @@
#include <osv/mempool.hh>
#include <osv/commands.hh>
#include <osv/elf.hh>
+#if CONF_drivers_mmio
#include "drivers/virtio-mmio.hh"
+#endif
#define DTB_INTERRUPT_CELLS 3
@@ -279,6 +282,7 @@ u64 dtb_get_cadence_uart(int *irqid)
return addr;
}
+#if CONF_drivers_mmio
#define VIRTIO_MMIO_DEV_COMPAT "virtio,mmio"
#define DTB_MAX_VIRTIO_MMIO_DEV_COUNT 8
static virtio::mmio_device_info dtb_dtb_virtio_mmio_devices_infos[DTB_MAX_VIRTIO_MMIO_DEV_COUNT];
@@ -321,6 +325,7 @@ void dtb_collect_parsed_mmio_virtio_devices()
virtio::add_mmio_device_configuration(dtb_dtb_virtio_mmio_devices_infos[idx]);
}
}
+#endif
/* this gets the virtual timer irq, we are not interested
* about the other timers.
@@ -796,7 +801,9 @@ void __attribute__((constructor(init_prio::dtb))) dtb_setup()
abort("dtb_setup: failed to parse pci_irq_map.\n");
}
+#if CONF_drivers_mmio
dtb_parse_mmio_virtio_devices();
+#endif
register u64 edata;
asm volatile ("adrp %0, .edata" : "=r"(edata));
diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
index bfa47f9f..f9854b6a 100644
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -7,6 +7,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include "arch-setup.hh"
#include <osv/sched.hh>
#include <osv/mempool.hh>
@@ -16,7 +17,9 @@
#include <osv/boot.hh>
#include <osv/debug.hh>
#include <osv/commands.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include "arch-mmu.hh"
#include "arch-dtb.hh"
@@ -24,7 +27,9 @@
#include "drivers/console.hh"
#include "drivers/pl011.hh"
#include "early-console.hh"
+#if CONF_drivers_pci
#include <osv/pci.hh>
+#endif
#include "drivers/mmio-isa-serial.hh"
#include <alloca.h>
@@ -41,6 +46,7 @@ void setup_temporary_phys_map()
mmu::flush_tlb_all();
}
+#if CONF_drivers_pci
void arch_setup_pci()
{
pci::set_pci_ecam(dtb_get_pci_is_ecam());
@@ -71,6 +77,7 @@ void arch_setup_pci()
mmu::linear_map((void *)ranges[1], (mmu::phys)ranges[1], ranges_len[1],
mmu::page_size, mmu::mattr::dev);
}
+#endif
extern bool opt_pci_disabled;
void arch_setup_free_memory()
@@ -101,12 +108,14 @@ void arch_setup_free_memory()
mmu::mattr::dev);
}
+#if CONF_drivers_cadence
if (console::Cadence_Console::active) {
// linear_map [TTBR0 - UART]
addr = (mmu::phys)console::aarch64_console.cadence.get_base_addr();
mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
mmu::mattr::dev);
}
+#endif
/* linear_map [TTBR0 - GIC DIST and GIC CPU] */
u64 dist, cpu;
@@ -120,15 +129,19 @@ void arch_setup_free_memory()
mmu::linear_map((void *)cpu, (mmu::phys)cpu, cpu_len, mmu::page_size,
mmu::mattr::dev);
+#if CONF_drivers_pci
if (!opt_pci_disabled) {
arch_setup_pci();
}
+#endif
// get rid of the command line, before memory is unmapped
console::mmio_isa_serial_console::clean_cmdline(cmdline);
osv::parse_cmdline(cmdline);
+#if CONF_drivers_mmio
dtb_collect_parsed_mmio_virtio_devices();
+#endif
mmu::switch_to_runtime_page_tables();
@@ -155,17 +168,28 @@ void arch_init_premain()
}
#include "drivers/driver.hh"
+#if CONF_drivers_virtio
#include "drivers/virtio.hh"
+#include "drivers/virtio-mmio.hh"
+#endif
+#if CONF_drivers_virtio_rng
#include "drivers/virtio-rng.hh"
+#endif
+#if CONF_drivers_virtio_blk
#include "drivers/virtio-blk.hh"
+#endif
+#if CONF_drivers_virtio_net
#include "drivers/virtio-net.hh"
-#include "drivers/virtio-mmio.hh"
+#endif
+#if CONF_drivers_virtio_fs
#include "drivers/virtio-fs.hh"
+#endif
void arch_init_drivers()
{
extern boot_time_chart boot_time;
+#if CONF_drivers_pci
if (!opt_pci_disabled) {
int irqmap_count = dtb_get_pci_irqmap_count();
if (irqmap_count > 0) {
@@ -189,16 +213,27 @@ void arch_init_drivers()
boot_time.event("pci enumerated");
}
}
+#endif
+#if CONF_drivers_mmio
// Register any parsed virtio-mmio devices
virtio::register_mmio_devices(device_manager::instance());
+#endif
// Initialize all drivers
hw::driver_manager* drvman = hw::driver_manager::instance();
+#if CONF_drivers_virtio_rng
drvman->register_driver(virtio::rng::probe);
+#endif
+#if CONF_drivers_virtio_blk
drvman->register_driver(virtio::blk::probe);
+#endif
+#if CONF_drivers_virtio_net
drvman->register_driver(virtio::net::probe);
+#endif
+#if CONF_drivers_virtio_fs
drvman->register_driver(virtio::fs::probe);
+#endif
boot_time.event("drivers probe");
drvman->load_all();
drvman->list_drivers();
@@ -208,11 +243,13 @@ void arch_init_early_console()
{
console::mmio_isa_serial_console::_phys_mmio_address = 0;
+#if CONF_drivers_xen
if (is_xen()) {
new (&console::aarch64_console.xen) console::XEN_Console();
console::arch_early_console = console::aarch64_console.xen;
return;
}
+#endif
int irqid;
u64 mmio_serial_address = dtb_get_mmio_serial_console(&irqid);
@@ -225,6 +262,7 @@ void arch_init_early_console()
return;
}
+#if CONF_drivers_cadence
mmio_serial_address = dtb_get_cadence_uart(&irqid);
if (mmio_serial_address) {
new (&console::aarch64_console.cadence) console::Cadence_Console();
@@ -234,6 +272,7 @@ void arch_init_early_console()
console::Cadence_Console::active = true;
return;
}
+#endif
new (&console::aarch64_console.pl011) console::PL011_Console();
console::arch_early_console = console::aarch64_console.pl011;
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index dc59197b..5fce7853 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
.text
.align 16
.globl start_elf
@@ -31,8 +32,10 @@ start_elf:
adrp x1, dtb // store dtb (arch-setup.cc)
str x5, [x1, #:lo12:dtb]
+#if CONF_drivers_xen
mov x29, xzr
bl init_xen
+#endif
mov x29, xzr
bl premain
diff --git a/arch/aarch64/cpuid.cc b/arch/aarch64/cpuid.cc
index d4da09d4..3b803afc 100644
--- a/arch/aarch64/cpuid.cc
+++ b/arch/aarch64/cpuid.cc
@@ -5,9 +5,12 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include "cpuid.hh"
#include "processor.hh"
+#if CONF_drivers_xen
#include "xen.hh"
+#endif
namespace processor {
@@ -131,7 +134,9 @@ const unsigned long hwcap32()
void process_cpuid(features_type& features)
{
+#if CONF_drivers_xen
xen::get_features(features);
+#endif
}
const features_type& features()
diff --git a/arch/aarch64/xen.cc b/arch/aarch64/xen.cc
index 47994609..50f752c4 100644
--- a/arch/aarch64/xen.cc
+++ b/arch/aarch64/xen.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#define CONF_drivers_xen 1
#include <osv/types.h>
#include <osv/xen.hh>
#include <xen/interface/xen.h>
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
index d0ea6a7d..03518deb 100644
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include "apic.hh"
#include "msr.hh"
#include <osv/xen.hh>
diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc
index 439d0650..582cb1b5 100644
--- a/arch/x64/arch-setup.cc
+++ b/arch/x64/arch-setup.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include "arch.hh"
#include "arch-cpu.hh"
#include "arch-setup.hh"
@@ -13,7 +14,9 @@
#include "processor.hh"
#include "processor-flags.h"
#include "msr.hh"
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/elf.hh>
#include <osv/types.h>
#include <alloca.h>
@@ -21,15 +24,21 @@
#include <osv/boot.hh>
#include <osv/commands.hh>
#include "dmi.hh"
+#if CONF_drivers_acpi
#include "drivers/acpi.hh"
+#endif
osv_multiboot_info_type* osv_multiboot_info;
+#if CONF_drivers_mmio
#include "drivers/virtio-mmio.hh"
+#endif
void parse_cmdline(multiboot_info_type& mb)
{
auto p = reinterpret_cast<char*>(mb.cmdline);
+#if CONF_drivers_mmio
virtio::parse_mmio_device_configuration(p);
+#endif
osv::parse_cmdline(p);
}
@@ -214,8 +223,13 @@ void arch_setup_tls(void *tls, const elf::tls_data& info)
static inline void disable_pic()
{
+#if CONF_drivers_xen
// PIC not present in Xen
XENPV_ALTERNATIVE({ processor::outb(0xff, 0x21); processor::outb(0xff, 0xa1); }, {});
+#else
+ processor::outb(0xff, 0x21);
+ processor::outb(0xff, 0xa1);
+#endif
}
extern "C" void syscall_entry(void);
@@ -247,53 +261,105 @@ void arch_init_premain()
if (omb.disk_err)
debug_early_u64("Error reading disk (real mode): ", static_cast<u64>(omb.disk_err));
+#if CONF_drivers_acpi
acpi::pvh_rsdp_paddr = omb.pvh_rsdp;
+#endif
disable_pic();
}
#include "drivers/driver.hh"
+#if CONF_drivers_acpi
#include "drivers/pvpanic.hh"
+#endif
+#if CONF_drivers_virtio
#include "drivers/virtio.hh"
+#endif
+#if CONF_drivers_virtio_blk
#include "drivers/virtio-blk.hh"
+#endif
+#if CONF_drivers_virtio_scsi
#include "drivers/virtio-scsi.hh"
+#endif
+#if CONF_drivers_virtio_net
#include "drivers/virtio-net.hh"
+#endif
+#if CONF_drivers_virtio_rng
#include "drivers/virtio-rng.hh"
+#endif
+#if CONF_drivers_virtio_fs
#include "drivers/virtio-fs.hh"
+#endif
+#if CONF_drivers_xen
#include "drivers/xenplatform-pci.hh"
+#endif
+#if CONF_drivers_ahci
#include "drivers/ahci.hh"
+#endif
+#if CONF_drivers_pvscsi
#include "drivers/vmw-pvscsi.hh"
+#endif
+#if CONF_drivers_vmxnet3
#include "drivers/vmxnet3.hh"
+#endif
+#if CONF_drivers_ide
#include "drivers/ide.hh"
+#endif
extern bool opt_pci_disabled;
void arch_init_drivers()
{
+#if CONF_drivers_acpi
// initialize panic drivers
panic::pvpanic::probe_and_setup();
boot_time.event("pvpanic done");
+#endif
+#if CONF_drivers_pci
if (!opt_pci_disabled) {
// Enumerate PCI devices
pci::pci_device_enumeration();
boot_time.event("pci enumerated");
}
+#endif
+#if CONF_drivers_mmio
// Register any parsed virtio-mmio devices
virtio::register_mmio_devices(device_manager::instance());
+#endif
// Initialize all drivers
hw::driver_manager* drvman = hw::driver_manager::instance();
+#if CONF_drivers_virtio_blk
drvman->register_driver(virtio::blk::probe);
+#endif
+#if CONF_drivers_virtio_scsi
drvman->register_driver(virtio::scsi::probe);
+#endif
+#if CONF_drivers_virtio_net
drvman->register_driver(virtio::net::probe);
+#endif
+#if CONF_drivers_virtio_rng
drvman->register_driver(virtio::rng::probe);
+#endif
+#if CONF_drivers_virtio_fs
drvman->register_driver(virtio::fs::probe);
+#endif
+#if CONF_drivers_xen
drvman->register_driver(xenfront::xenplatform_pci::probe);
+#endif
+#if CONF_drivers_ahci
drvman->register_driver(ahci::hba::probe);
+#endif
+#if CONF_drivers_pvscsi
drvman->register_driver(vmw::pvscsi::probe);
+#endif
+#if CONF_drivers_vmxnet3
drvman->register_driver(vmw::vmxnet3::probe);
+#endif
+#if CONF_drivers_ide
drvman->register_driver(ide::ide_drive::probe);
+#endif
boot_time.event("drivers probe");
drvman->load_all();
drvman->list_drivers();
@@ -301,7 +367,9 @@ void arch_init_drivers()
#include "drivers/console.hh"
#include "drivers/isa-serial.hh"
+#if CONF_drivers_vga
#include "drivers/vga.hh"
+#endif
#include "early-console.hh"
void arch_init_early_console()
@@ -311,15 +379,21 @@ void arch_init_early_console()
bool arch_setup_console(std::string opt_console)
{
+#if CONF_drivers_vga
hw::driver_manager* drvman = hw::driver_manager::instance();
+#endif
if (opt_console.compare("serial") == 0) {
console::console_driver_add(&console::arch_early_console);
+#if CONF_drivers_vga
} else if (opt_console.compare("vga") == 0) {
drvman->register_driver(console::VGAConsole::probe);
+#endif
} else if (opt_console.compare("all") == 0) {
console::console_driver_add(&console::arch_early_console);
+#if CONF_drivers_vga
drvman->register_driver(console::VGAConsole::probe);
+#endif
} else {
return false;
}
diff --git a/arch/x64/cpuid.cc b/arch/x64/cpuid.cc
index 29bc8d6e..73064158 100644
--- a/arch/x64/cpuid.cc
+++ b/arch/x64/cpuid.cc
@@ -5,10 +5,15 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include "cpuid.hh"
#include "processor.hh"
+#if CONF_drivers_xen
#include "xen.hh"
+#endif
+#if CONF_drivers_hyperv
#include <dev/hyperv/include/hyperv.h>
+#endif
namespace processor {
@@ -96,6 +101,7 @@ static void process_cpuid_bit(features_type& features, const cpuid_bit& b)
features.*(b.flag) = (w >> b.bit) & 1;
}
+#if CONF_drivers_xen
static void process_xen_bits(features_type &features)
{
signature sig = { 0x566e6558, 0x65584d4d, 0x4d4d566e };
@@ -109,20 +115,27 @@ static void process_xen_bits(features_type &features)
break;
}
}
+#endif
+#if CONF_drivers_hyperv
static void process_hyperv_bits(features_type &features) {
if(hyperv_identify() && hyperv_is_timecount_available()) {
features.hyperv_clocksource = true;
}
}
+#endif
static void process_cpuid(features_type& features)
{
for (unsigned i = 0; i < nr_cpuid_bits; ++i) {
process_cpuid_bit(features, cpuid_bits[i]);
}
+#if CONF_drivers_xen
process_xen_bits(features);
+#endif
+#if CONF_drivers_hyperv
process_hyperv_bits(features);
+#endif
}
}
@@ -140,6 +153,7 @@ const std::string& features_str()
}
}
+#if CONF_drivers_xen
// FIXME: Even though Xen does not have its features in cpuid, there has to
// be a better way to do it, by creating a string map directly from the xen
// PV features. But since we add features here very rarely, leave it be for now.
@@ -152,6 +166,7 @@ const std::string& features_str()
if (features().xen_pci) {
cpuid_str += std::string("xen_pci ");
}
+#endif
cpuid_str.pop_back();
return cpuid_str;
diff --git a/arch/x64/entry-xen.S b/arch/x64/entry-xen.S
index be67b33d..451d35e4 100644
--- a/arch/x64/entry-xen.S
+++ b/arch/x64/entry-xen.S
@@ -3,6 +3,7 @@
# This work is open source software, licensed under the terms of the
# BSD license as described in the LICENSE file in the top-level directory.
+#include <osv/drivers_config.h>
#include <xen/interface/elfnote.h>
#define elfnote(type, valtype, value) \
@@ -21,6 +22,7 @@
#define elfnote_val(type, value) elfnote(type, .quad, value)
#define elfnote_str(type, value) elfnote(type, .asciz, value)
+#if CONF_drivers_xen
elfnote_val(XEN_ELFNOTE_ENTRY, xen_start)
elfnote_val(XEN_ELFNOTE_HYPERCALL_PAGE, hypercall_page)
elfnote_val(XEN_ELFNOTE_VIRT_BASE, OSV_KERNEL_VM_SHIFT)
@@ -30,6 +32,7 @@ elfnote_str(XEN_ELFNOTE_GUEST_VERSION, "?.?")
elfnote_str(XEN_ELFNOTE_LOADER, "generic")
elfnote_str(XEN_ELFNOTE_FEATURES, "!writable_page_tables")
elfnote_str(XEN_ELFNOTE_BSD_SYMTAB, "yes")
+#endif
elfnote_val(XEN_ELFNOTE_PHYS32_ENTRY, hvm_xen_start-OSV_KERNEL_VM_SHIFT)
.data
@@ -41,6 +44,7 @@ elfnote_val(XEN_ELFNOTE_PHYS32_ENTRY, hvm_xen_start-OSV_KERNEL_VM_SHIFT)
xen_bootstrap_end: .quad 0
.text
+#if CONF_drivers_xen
.align 4096
.globl hypercall_page
.hidden hypercall_page
@@ -54,6 +58,7 @@ xen_start:
call xen_init
mov $0x0, %rdi
jmp start64
+#endif
.code32
hvm_xen_start:
diff --git a/arch/x64/power.cc b/arch/x64/power.cc
index c9656fe0..71cba972 100644
--- a/arch/x64/power.cc
+++ b/arch/x64/power.cc
@@ -5,17 +5,20 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <osv/power.hh>
#include <osv/debug.hh>
#include <smp.hh>
#include <processor.hh>
#include <arch.hh>
+#if CONF_drivers_acpi
extern "C" {
#include "acpi.h"
}
#include <drivers/acpi.hh>
+#endif
namespace osv {
@@ -29,6 +32,7 @@ void halt(void)
void poweroff(void)
{
+#if CONF_drivers_acpi
if (acpi::is_enabled()) {
ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
if (ACPI_FAILURE(status)) {
@@ -41,6 +45,7 @@ void poweroff(void)
halt();
}
} else {
+#endif
// On hypervisors that do not support ACPI like firecracker we
// resort to a reset using the 8042 PS/2 Controller ("keyboard controller")
// as a way to shutdown the VM
@@ -49,7 +54,9 @@ void poweroff(void)
// then cause triple fault by loading a broken IDT and triggering an interrupt.
processor::lidt(processor::desc_ptr(0, 0));
__asm__ __volatile__("int3");
+#if CONF_drivers_acpi
}
+#endif
// We shouldn't get here on x86.
halt();
@@ -71,9 +78,11 @@ static void kbd_reboot(void) {
void reboot(void)
{
+#if CONF_drivers_acpi
// Method 1: AcpiReset, does not work on qemu or kvm now because the reset
// register is not supported. Nevertheless, we should try it first
AcpiReset();
+#endif
// Method 2: "fast reset" via System Control Port A (port 0x92)
processor::outb(1, 0x92);
// Method 3: Reset using the 8042 PS/2 Controller ("keyboard controller")
diff --git a/arch/x64/smp.cc b/arch/x64/smp.cc
index be655881..7141c2a9 100644
--- a/arch/x64/smp.cc
+++ b/arch/x64/smp.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <smp.hh>
#include "processor.hh"
#include "msr.hh"
@@ -12,10 +13,12 @@
#include "ioapic.hh"
#include <osv/mmu.hh>
#include <string.h>
+#if CONF_drivers_acpi
extern "C" {
#include "acpi.h"
}
#include <drivers/acpi.hh>
+#endif
#include <boost/intrusive/parent_from_member.hpp>
#include <osv/debug.hh>
#include <osv/sched.hh>
@@ -49,6 +52,7 @@ static void register_cpu(unsigned cpu_id, u32 apic_id, u32 acpi_id = 0)
sched::cpus.push_back(c);
}
+#if CONF_drivers_acpi
void parse_madt()
{
char madt_sig[] = ACPI_SIG_MADT;
@@ -88,6 +92,7 @@ void parse_madt()
}
debug(fmt("%d CPUs detected\n") % nr_cpus);
}
+#endif
#define MPF_IDENTIFIER (('_'<<24) | ('P'<<16) | ('M'<<8) | '_')
struct mpf_structure {
@@ -195,11 +200,15 @@ void parse_mp_table()
void smp_init()
{
+#if CONF_drivers_acpi
if (acpi::is_enabled()) {
parse_madt();
} else {
+#endif
parse_mp_table();
+#if CONF_drivers_acpi
}
+#endif
sched::current_cpu = sched::cpus[0];
for (auto c : sched::cpus) {
diff --git a/arch/x64/xen.cc b/arch/x64/xen.cc
index d642c4fa..2482c56a 100644
--- a/arch/x64/xen.cc
+++ b/arch/x64/xen.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#define CONF_drivers_xen 1
#include "xen.hh"
#include <osv/debug.hh>
#include <osv/mmu.hh>
diff --git a/conf/profiles/README.md b/conf/profiles/README.md
new file mode 100644
index 00000000..5350fe70
--- /dev/null
+++ b/conf/profiles/README.md
@@ -0,0 +1,71 @@
+The two subdirectories `aarch64` and `x64` contain tiny makefile
+include files (`*.mk`) which specify which drivers should be linked
+and enabled into kernel.
+
+The `
base.mk` is the file included last by the main makefile and is
+intended to disable all drivers unless enabled specifically in a
+given profile file. For example, each driver configuration variable
+like `conf_drivers_virtio_fs` is disabled in a line in the `
base.mk` like this:
+```make
+export conf_drivers_virtio_fs?=0
+```
+but would be enabled by this line in the `
virtio-pci.mk`:
+```make
+conf_drivers_virtio_fs?=1
+```
+if the profile `virtio-pci` is selected when building the kernel like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
+```
+The `
base.mk` also enforces some dependencies between given driver and other kernel
+components. For example this line:
+```make
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+```
+enables ACPI support if the hpet driver is selected. There is also another rule that
+enables PCI support if ACPI is selected. And so on.
+
+The individual files under given architecture directory other than `
base.mk` enable
+list of drivers for each profile that typically corresponds to a hypervisor like `
vbox.mk`
+for Virtual Box or a type of hypervisor like `
microvm.mk`. One exception is the `
all.mk`
+file which enables all drivers and is a default profile.
+
+Please note that one can build custom kernel with specific list of drivers by passing
+corresponding `conf_drivers_*` parameters to the build script like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=base \
+ conf_drivers_acpi=1 conf_drivers_virtio_fs=1 conf_drivers_virtio_net=1 conf_drivers_pvpanic=1
+```
+The kernel built using the command line above comes with enough drivers to mount virtio-FS filesystem and support networking over virtio-net device.
+
+Lastly if you want to verify which exact drivers were enabled, you can examine content of the generated `drivers-config.h` header:
+```c
+cat build/release/gen/include/osv/drivers_config.h
+/* This file is generated automatically. */
+#ifndef OSV_DRIVERS_CONFIG_H
+#define OSV_DRIVERS_CONFIG_H
+
+#define CONF_drivers_acpi 1
+#define CONF_drivers_ahci 0
+#define CONF_drivers_hpet 0
+#define CONF_drivers_hyperv 0
+#define CONF_drivers_ide 0
+#define CONF_drivers_mmio 0
+#define CONF_drivers_pci 1
+#define CONF_drivers_pvpanic 1
+#define CONF_drivers_pvscsi 0
+#define CONF_drivers_scsi 0
+#define CONF_drivers_vga 0
+#define CONF_drivers_virtio 1
+#define CONF_drivers_virtio_blk 0
+#define CONF_drivers_virtio_fs 1
+#define CONF_drivers_virtio_net 1
+#define CONF_drivers_virtio_rng 0
+#define CONF_drivers_virtio_scsi 0
+#define CONF_drivers_vmxnet3 0
+#define CONF_drivers_xen 0
+
+#endif
+```
diff --git a/conf/profiles/aarch64/
all.mk b/conf/profiles/aarch64/
all.mk
new file mode 100644
index 00000000..afc51954
--- /dev/null
+++ b/conf/profiles/aarch64/
all.mk
@@ -0,0 +1,5 @@
+include conf/profiles/$(arch)/
virtio-mmio.mk
+include conf/profiles/$(arch)/
virtio-pci.mk
+include conf/profiles/$(arch)/
xen.mk
+
+conf_drivers_cadence?=1
diff --git a/conf/profiles/aarch64/
base.mk b/conf/profiles/aarch64/
base.mk
new file mode 100644
index 00000000..a3894f54
--- /dev/null
+++ b/conf/profiles/aarch64/
base.mk
@@ -0,0 +1,26 @@
+export conf_drivers_xen?=0
+
+export conf_drivers_virtio_blk?=0
+ifeq ($(conf_drivers_virtio_blk),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_fs?=0
+ifeq ($(conf_drivers_virtio_fs),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_net?=0
+ifeq ($(conf_drivers_virtio_net),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_rng?=0
+ifeq ($(conf_drivers_virtio_rng),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_cadence?=0
+export conf_drivers_virtio?=0
+export conf_drivers_pci?=0
+export conf_drivers_mmio?=0
diff --git a/conf/profiles/aarch64/
microvm.mk b/conf/profiles/aarch64/
microvm.mk
new file mode 120000
index 00000000..d85dd828
--- /dev/null
+++ b/conf/profiles/aarch64/
microvm.mk
@@ -0,0 +1 @@
+
virtio-mmio.mk
\ No newline at end of file
diff --git a/conf/profiles/aarch64/
virtio-mmio.mk b/conf/profiles/aarch64/
virtio-mmio.mk
new file mode 100644
index 00000000..d8d9669b
--- /dev/null
+++ b/conf/profiles/aarch64/
virtio-mmio.mk
@@ -0,0 +1,4 @@
+conf_drivers_mmio?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_net?=1
diff --git a/conf/profiles/aarch64/
virtio-pci.mk b/conf/profiles/aarch64/
virtio-pci.mk
new file mode 100644
index 00000000..599a530c
--- /dev/null
+++ b/conf/profiles/aarch64/
virtio-pci.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_fs?=1
+conf_drivers_virtio_net?=1
+conf_drivers_virtio_rng?=1
diff --git a/conf/profiles/aarch64/
xen.mk b/conf/profiles/aarch64/
xen.mk
new file mode 100644
index 00000000..2c5f0c87
--- /dev/null
+++ b/conf/profiles/aarch64/
xen.mk
@@ -0,0 +1,2 @@
+conf_drivers_pci?=1
+conf_drivers_xen?=1
diff --git a/conf/profiles/x64/
all.mk b/conf/profiles/x64/
all.mk
new file mode 100644
index 00000000..c13790e2
--- /dev/null
+++ b/conf/profiles/x64/
all.mk
@@ -0,0 +1,8 @@
+include conf/profiles/$(arch)/
hyperv.mk
+include conf/profiles/$(arch)/
vbox.mk
+include conf/profiles/$(arch)/
virtio-mmio.mk
+include conf/profiles/$(arch)/
virtio-pci.mk
+include conf/profiles/$(arch)/
vmware.mk
+include conf/profiles/$(arch)/
xen.mk
+
+conf_drivers_vga?=1
diff --git a/conf/profiles/x64/
base.mk b/conf/profiles/x64/
base.mk
new file mode 100644
index 00000000..26dd054e
--- /dev/null
+++ b/conf/profiles/x64/
base.mk
@@ -0,0 +1,74 @@
+export conf_drivers_xen?=0
+export conf_drivers_hyperv?=0
+
+export conf_drivers_virtio_blk?=0
+ifeq ($(conf_drivers_virtio_blk),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_scsi?=0
+ifeq ($(conf_drivers_virtio_scsi),1)
+export conf_drivers_virtio?=1
+export conf_drivers_scsi?=1
+endif
+
+export conf_drivers_virtio_fs?=0
+ifeq ($(conf_drivers_virtio_fs),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_net?=0
+ifeq ($(conf_drivers_virtio_net),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_rng?=0
+ifeq ($(conf_drivers_virtio_rng),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_ahci?=0
+ifeq ($(conf_drivers_ahci),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_pvscsi?=0
+ifeq ($(conf_drivers_pvscsi),1)
+export conf_drivers_pci?=1
+export conf_drivers_scsi?=1
+endif
+
+export conf_drivers_vmxnet3?=0
+ifeq ($(conf_drivers_vmxnet3),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_ide?=0
+ifeq ($(conf_drivers_ide),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_vga?=0
+ifeq ($(conf_drivers_vga),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_pvpanic?=0
+ifeq ($(conf_drivers_pvpanic),1)
+export conf_drivers_acpi?=1
+endif
+
+export conf_drivers_hpet?=0
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+
+export conf_drivers_acpi?=0
+ifeq ($(conf_drivers_acpi),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_virtio?=0
+export conf_drivers_pci?=0
+export conf_drivers_mmio?=0
+export conf_drivers_scsi?=0
diff --git a/conf/profiles/x64/
cloud_hypervisor.mk b/conf/profiles/x64/
cloud_hypervisor.mk
new file mode 100644
index 00000000..aa8695dc
--- /dev/null
+++ b/conf/profiles/x64/
cloud_hypervisor.mk
@@ -0,0 +1,2 @@
+include conf/profiles/$(arch)/
virtio-pci.mk
+conf_drivers_pvpanic?=1
diff --git a/conf/profiles/x64/
hyperv.mk b/conf/profiles/x64/
hyperv.mk
new file mode 100644
index 00000000..69af65ca
--- /dev/null
+++ b/conf/profiles/x64/
hyperv.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_hyperv?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/
microvm.mk b/conf/profiles/x64/
microvm.mk
new file mode 120000
index 00000000..d85dd828
--- /dev/null
+++ b/conf/profiles/x64/
microvm.mk
@@ -0,0 +1 @@
+
virtio-mmio.mk
\ No newline at end of file
diff --git a/conf/profiles/x64/
vbox.mk b/conf/profiles/x64/
vbox.mk
new file mode 100644
index 00000000..f0a26b2d
--- /dev/null
+++ b/conf/profiles/x64/
vbox.mk
@@ -0,0 +1,8 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_ahci?=1
+conf_drivers_virtio_net?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/
virtio-mmio.mk b/conf/profiles/x64/
virtio-mmio.mk
new file mode 100644
index 00000000..d8d9669b
--- /dev/null
+++ b/conf/profiles/x64/
virtio-mmio.mk
@@ -0,0 +1,4 @@
+conf_drivers_mmio?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_net?=1
diff --git a/conf/profiles/x64/
virtio-pci.mk b/conf/profiles/x64/
virtio-pci.mk
new file mode 100644
index 00000000..a1d0a1ef
--- /dev/null
+++ b/conf/profiles/x64/
virtio-pci.mk
@@ -0,0 +1,10 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_scsi?=1
+conf_drivers_virtio_fs?=1
+conf_drivers_virtio_net?=1
+conf_drivers_virtio_rng?=1
+
+conf_drivers_pvpanic?=1
diff --git a/conf/profiles/x64/
vmware.mk b/conf/profiles/x64/
vmware.mk
new file mode 100644
index 00000000..1a37e1d1
--- /dev/null
+++ b/conf/profiles/x64/
vmware.mk
@@ -0,0 +1,10 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_scsi?=1
+
+conf_drivers_pvscsi?=1
+conf_drivers_vmxnet3?=1
+conf_drivers_ide?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/
xen.mk b/conf/profiles/x64/
xen.mk
new file mode 100644
index 00000000..8a0d49fa
--- /dev/null
+++ b/conf/profiles/x64/
xen.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_xen?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/core/xen_intr.cc b/core/xen_intr.cc
index 16065a3d..adb4e3da 100644
--- a/core/xen_intr.cc
+++ b/core/xen_intr.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include <osv/xen_intr.hh>
#include <bsd/porting/bus.h>
diff --git a/drivers/acpi.cc b/drivers/acpi.cc
index 55ea126e..d1f5f422 100644
--- a/drivers/acpi.cc
+++ b/drivers/acpi.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <map>
#include <memory>
@@ -19,7 +20,9 @@ extern "C" {
#include <osv/shutdown.hh>
#include "processor.hh"
#include <osv/align.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/debug.h>
#include <osv/mutex.h>
@@ -635,5 +638,9 @@ void init()
void __attribute__((constructor(init_prio::acpi))) acpi_init_early()
{
- XENPV_ALTERNATIVE({ acpi::early_init(); }, {});
+#if CONF_drivers_xen
+ XENPV_ALTERNATIVE({ acpi::early_init(); }, {});
+#else
+ acpi::early_init();
+#endif
}
diff --git a/drivers/hpet.cc b/drivers/hpet.cc
index 6b67d8b7..8c582f80 100644
--- a/drivers/hpet.cc
+++ b/drivers/hpet.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
extern "C" {
#include "acpi.h"
}
@@ -15,7 +16,9 @@ extern "C" {
#include <osv/mmu.hh>
#include <osv/mmio.hh>
#include "arch.hh"
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/irqlock.hh>
#include "rtc.hh"
#include <osv/percpu.hh>
@@ -146,7 +149,9 @@ s64 hpetclock::boot_time()
void __attribute__((constructor(init_prio::hpet))) hpet_init()
{
+#if CONF_drivers_xen
XENPV_ALTERNATIVE(
+#endif
{
auto c = clock::get();
@@ -178,5 +183,9 @@ void __attribute__((constructor(init_prio::hpet))) hpet_init()
else {
clock::register_clock(new hpet_32bit_clock(hpet_mmio_address));
}
+#if CONF_drivers_xen
}, {});
+#else
+ }
+#endif
}
diff --git a/drivers/pci-generic.cc b/drivers/pci-generic.cc
index 6b0a9185..ff967715 100644
--- a/drivers/pci-generic.cc
+++ b/drivers/pci-generic.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <sstream>
#include <iomanip>
@@ -16,8 +17,10 @@
#include "drivers/pci-function.hh"
#include "drivers/pci-bridge.hh"
#include "drivers/pci-device.hh"
+#if CONF_drivers_virtio
#include "drivers/virtio.hh"
#include "drivers/virtio-pci-device.hh"
+#endif
extern bool opt_pci_disabled;
@@ -102,6 +105,7 @@ bool check_bus(u16 bus)
}
hw_device *dev_to_register = dev;
+#if CONF_drivers_virtio
//
// Create virtio_device if vendor is VIRTIO_VENDOR_ID
if (dev->get_vendor_id() == virtio::VIRTIO_VENDOR_ID) {
@@ -117,6 +121,7 @@ bool check_bus(u16 bus)
pci_e("Error: expected regular pci device %02x:%02x.%x",
bus, slot, func);
}
+#endif
if (dev_to_register && !device_manager::instance()->register_device(dev_to_register)) {
pci_e("Error: couldn't register device %02x:%02x.%x",
diff --git a/drivers/virtio-blk.cc b/drivers/virtio-blk.cc
index 91ca492e..e03d41f7 100644
--- a/drivers/virtio-blk.cc
+++ b/drivers/virtio-blk.cc
@@ -6,6 +6,7 @@
*/
+#include <osv/drivers_config.h>
#include <sys/cdefs.h>
#include "drivers/virtio.hh"
@@ -133,6 +134,7 @@ blk::blk(virtio_device& virtio_dev)
auto queue = get_virt_queue(0);
interrupt_factory int_factory;
+#if CONF_drivers_pci
int_factory.register_msi_bindings = [queue, t](interrupt_manager &msi) {
msi.easy_register( {{ 0, [=] { queue->disable_interrupts(); }, t }});
};
@@ -143,6 +145,7 @@ blk::blk(virtio_device& virtio_dev)
[=] { return this->ack_irq(); },
[=] { t->wake(); });
};
+#endif
#ifdef __aarch64__
int_factory.create_spi_edge_interrupt = [this,t]() {
@@ -153,11 +156,13 @@ blk::blk(virtio_device& virtio_dev)
[=] { t->wake(); });
};
#else
+#if CONF_drivers_mmio
int_factory.create_gsi_edge_interrupt = [this,t]() {
return new gsi_edge_interrupt(
_dev.get_irq(),
[=] { if (this->ack_irq()) t->wake(); });
};
+#endif
#endif
_dev.register_interrupt(int_factory);
diff --git a/drivers/virtio-fs.cc b/drivers/virtio-fs.cc
index 0c5ffb4e..e87d0ce1 100644
--- a/drivers/virtio-fs.cc
+++ b/drivers/virtio-fs.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <string>
#include <osv/debug.h>
@@ -101,6 +102,7 @@ fs::fs(virtio_device& virtio_dev)
auto* queue = get_virt_queue(VQ_REQUEST);
interrupt_factory int_factory;
+#if CONF_drivers_pci
int_factory.register_msi_bindings = [queue, t](interrupt_manager& msi) {
msi.easy_register({
{VQ_HIPRIO, nullptr, nullptr},
@@ -114,13 +116,16 @@ fs::fs(virtio_device& virtio_dev)
[=] { return this->ack_irq(); },
[=] { t->wake(); });
};
+#endif
#ifdef __x86_64__
+#if CONF_drivers_mmio
int_factory.create_gsi_edge_interrupt = [this, t]() {
return new gsi_edge_interrupt(
_dev.get_irq(),
[=] { if (this->ack_irq()) t->wake(); });
};
+#endif
#endif
_dev.register_interrupt(int_factory);
diff --git a/drivers/virtio-net.cc b/drivers/virtio-net.cc
index 4be60f10..d2ab7c76 100644
--- a/drivers/virtio-net.cc
+++ b/drivers/virtio-net.cc
@@ -6,6 +6,7 @@
*/
+#include <osv/drivers_config.h>
#include <sys/cdefs.h>
#include "drivers/virtio.hh"
@@ -303,6 +304,7 @@ net::net(virtio_device& dev)
ether_ifattach(_ifn, _config.mac);
interrupt_factory int_factory;
+#if CONF_drivers_pci
int_factory.register_msi_bindings = [this,poll_task](interrupt_manager &msi) {
msi.easy_register({
{ 0, [&] { this->_rxq.vqueue->disable_interrupts(); }, poll_task },
@@ -316,6 +318,7 @@ net::net(virtio_device& dev)
[=] { return this->ack_irq(); },
[=] { poll_task->wake(); });
};
+#endif
#ifdef __aarch64__
int_factory.create_spi_edge_interrupt = [this,poll_task]() {
@@ -326,11 +329,13 @@ net::net(virtio_device& dev)
[=] { poll_task->wake(); });
};
#else
+#if CONF_drivers_mmio
int_factory.create_gsi_edge_interrupt = [this,poll_task]() {
return new gsi_edge_interrupt(
_dev.get_irq(),
[=] { if (this->ack_irq()) poll_task->wake(); });
};
+#endif
#endif
_dev.register_interrupt(int_factory);
diff --git a/drivers/xenclock.cc b/drivers/xenclock.cc
index 6f5093cd..e9269d60 100644
--- a/drivers/xenclock.cc
+++ b/drivers/xenclock.cc
@@ -14,6 +14,7 @@
#include "string.h"
#include "cpuid.hh"
#include <osv/barrier.hh>
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include <osv/debug.hh>
#include <osv/prio.hh>
diff --git a/drivers/xenfront-xenbus.cc b/drivers/xenfront-xenbus.cc
index ba143841..36e7f3dc 100644
--- a/drivers/xenfront-xenbus.cc
+++ b/drivers/xenfront-xenbus.cc
@@ -11,6 +11,7 @@
#include "cpuid.hh"
#include <osv/barrier.hh>
#include <osv/debug.hh>
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include "processor.hh"
#include "xenfront.hh"
diff --git a/drivers/xenplatform-pci.cc b/drivers/xenplatform-pci.cc
index 16488cfa..15f1ea51 100644
--- a/drivers/xenplatform-pci.cc
+++ b/drivers/xenplatform-pci.cc
@@ -6,6 +6,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#define CONF_drivers_xen 1
#include "xen.hh"
#include "xenplatform-pci.hh"
diff --git a/fs/vfs/vfs_conf.cc b/fs/vfs/vfs_conf.cc
index 4a54cb97..48211e77 100644
--- a/fs/vfs/vfs_conf.cc
+++ b/fs/vfs/vfs_conf.cc
@@ -38,6 +38,7 @@
* vfs_conf.c - File system configuration.
*/
+#include <osv/drivers_config.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
@@ -52,11 +53,15 @@ extern struct vfsops nfs_vfsops;
extern struct vfsops procfs_vfsops;
extern struct vfsops sysfs_vfsops;
extern struct vfsops zfs_vfsops;
+#if CONF_drivers_virtio_fs
extern struct vfsops virtiofs_vfsops;
+#endif
extern int ramfs_init(void);
extern int rofs_init(void);
+#if CONF_drivers_virtio_fs
extern int virtiofs_init(void);
+#endif
extern int devfs_init(void);
extern int nfs_init(void);
extern int procfs_init(void);
@@ -74,6 +79,8 @@ const struct vfssw vfssw[] = {
{"sysfs", sysfs_init, &sysfs_vfsops},
{"zfs", zfs_init, &zfs_vfsops},
{"rofs", rofs_init, &rofs_vfsops},
+#if CONF_drivers_virtio_fs
{"virtiofs", virtiofs_init, &virtiofs_vfsops},
+#endif
{nullptr, fs_noop, nullptr},
};
diff --git a/include/osv/xen.hh b/include/osv/xen.hh
index 5b50c2b6..76ca3b49 100644
--- a/include/osv/xen.hh
+++ b/include/osv/xen.hh
@@ -24,7 +24,11 @@ extern struct start_info* xen_start_info;
extern "C" shared_info_t *HYPERVISOR_shared_info;
#define XENPV_ALTERNATIVE(x, y) ALTERNATIVE((xen_start_info != nullptr), x, y)
+#if CONF_drivers_xen
#define is_xen() (HYPERVISOR_shared_info != nullptr)
+#else
+#define is_xen() (0)
+#endif
// We don't support 32 bit
struct xen_vcpu_info {
diff --git a/loader.cc b/loader.cc
index da254492..48716587 100644
--- a/loader.cc
+++ b/loader.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include "fs/fs.hh"
#include <bsd/init.hh>
#include <bsd/net.hh>
@@ -20,7 +21,9 @@
#include "smp.hh"
#ifdef __x86_64__
+#if CONF_drivers_acpi
#include "drivers/acpi.hh"
+#endif
#endif /* __x86_64__ */
#include <osv/sched.hh>
@@ -43,7 +46,9 @@
#include <osv/sampler.hh>
#include <osv/app.hh>
#include <osv/firmware.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/options.hh>
#include <dirent.h>
#include <iostream>
@@ -672,7 +677,9 @@ void main_cont(int loader_argc, char** loader_argv)
setenv("OSV_VERSION", osv::version().c_str(), 1);
+#if CONF_drivers_xen
xen::irq_init();
+#endif
smp_launch();
setenv("OSV_CPUS", std::to_string(sched::cpus.size()).c_str(), 1);
boot_time.event("SMP launched");
@@ -685,7 +692,9 @@ void main_cont(int loader_argc, char** loader_argv)
memory::enable_debug_allocator();
#ifdef __x86_64__
+#if CONF_drivers_acpi
acpi::init();
+#endif
#endif /* __x86_64__ */
if (sched::cpus.size() > sched::max_cpus) {
diff --git a/runtime.cc b/runtime.cc
index 10c72cca..3942982c 100644
--- a/runtime.cc
+++ b/runtime.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/
+#include <osv/drivers_config.h>
#include <osv/sched.hh>
#include <osv/elf.hh>
#include <stdlib.h>
@@ -48,7 +49,9 @@
#include <boost/range/adaptor/reversed.hpp>
#include <osv/align.hh>
#include <osv/stubbing.hh>
+#if CONF_drivers_acpi
#include "drivers/pvpanic.hh"
+#endif
#include <api/sys/resource.h>
#include <api/math.h>
#include <osv/shutdown.hh>
@@ -128,7 +131,9 @@ void abort(const char *fmt, ...)
debug_early("Halting.\n");
}
#ifndef AARCH64_PORT_STUB
+#if CONF_drivers_acpi
panic::pvpanic::panicked();
+#endif
#endif /* !AARCH64_PORT_STUB */
if (opt_power_off_on_abort) {
diff --git a/scripts/gen-drivers-config-header b/scripts/gen-drivers-config-header
new file mode 100755
index 00000000..daa0f373
--- /dev/null
+++ b/scripts/gen-drivers-config-header
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+if [ "$#" -ne 2 ]; then
+ echo "usage: $(basename $0) ARCH OUTPUT" >&2
+ exit 1
+fi
+
+arch=$1
+
+output=$2
+
+drivers_config_base_file=`dirname $0`/../conf/profiles/$arch/
base.mk
+
+tmp=$(mktemp)
+
+cat >$tmp <<EOL
+/* This file is generated automatically. */
+#ifndef OSV_DRIVERS_CONFIG_H
+#define OSV_DRIVERS_CONFIG_H
+
+EOL
+
+template_tmp=$(mktemp)
+cat $drivers_config_base_file | grep "export conf" | cut --delimiter=_ -f 2- | cut --delimiter=? -f 1 | \
+ sort | uniq | awk '{ printf("echo define CONF_%s $conf_%s\n", $0, $0) }' > $template_tmp
+. $template_tmp | awk '{printf("#%s\n",$0)}' >> $tmp
+rm $template_tmp
+
+cat >>$tmp <<EOL
+
+#endif
+EOL
+
+if cmp -s $tmp $output
+then
+ rm $tmp
+else
+ mkdir -p $(dirname $output)
+ mv $tmp $output
+fi
--
2.31.1