From ffb91b1ef9fd15e340ab603de2ea0969d5273552 Mon Sep 17 00:00:00 2001 From: Waldemar Kozaczuk Date: Mon, 7 Mar 2022 23:14:32 -0500 Subject: [PATCH] build: support driver profiles V2: Comparing to the previous version this one improves the gen-drivers-config-header by using awk mechanism to evaluate environment variables. It also addresses couple of nitpicks. 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 It is also possible to enable or disable individual drivers on top of what given profiles defines like so: ./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 Partially addresses #1110 Signed-off-by: Waldemar Kozaczuk --- 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 | 7 ++ 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 | 37 +++++++++ 45 files changed, 616 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 59cc6de4c5..c1c0eb844f 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 63db8b0092..7a7ef51f4a 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 #include #include #include @@ -16,7 +17,9 @@ #include #include #include +#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 bfa47f9f05..f9854b6a40 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 #include "arch-setup.hh" #include #include @@ -16,7 +17,9 @@ #include #include #include +#if CONF_drivers_xen #include +#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 +#endif #include "drivers/mmio-isa-serial.hh" #include @@ -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 dc59197b31..5fce78532a 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 .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 d4da09d4bc..3b803afc61 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 #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 4799460975..50f752c4b4 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 #include #include diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc index d0ea6a7da7..03518deb65 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 #include "apic.hh" #include "msr.hh" #include diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc index 439d06508d..582cb1b554 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 #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 +#endif #include #include #include @@ -21,15 +24,21 @@ #include #include #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(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(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 29bc8d6e4d..73064158ad 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 #include "cpuid.hh" #include "processor.hh" +#if CONF_drivers_xen #include "xen.hh" +#endif +#if CONF_drivers_hyperv #include +#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 be67b33df2..451d35e436 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 #include #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 c9656fe0f5..71cba9723a 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 #include #include #include #include #include +#if CONF_drivers_acpi extern "C" { #include "acpi.h" } #include +#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 be6558819f..7141c2a936 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 #include #include "processor.hh" #include "msr.hh" @@ -12,10 +13,12 @@ #include "ioapic.hh" #include #include +#if CONF_drivers_acpi extern "C" { #include "acpi.h" } #include +#endif #include #include #include @@ -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 d642c4fa80..2482c56ad4 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 #include diff --git a/conf/profiles/README.md b/conf/profiles/README.md new file mode 100644 index 0000000000..5350fe704c --- /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 0000000000..afc5195440 --- /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 0000000000..a3894f54ad --- /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 0000000000..d85dd828d3 --- /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 0000000000..d8d9669b2a --- /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 0000000000..599a530c6d --- /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 0000000000..2c5f0c87ec --- /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 0000000000..c13790e2be --- /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 0000000000..26dd054ed8 --- /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 0000000000..aa8695dcec --- /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 0000000000..69af65cacc --- /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 0000000000..d85dd828d3 --- /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 0000000000..f0a26b2dd7 --- /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 0000000000..d8d9669b2a --- /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 0000000000..a1d0a1efb0 --- /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 0000000000..1a37e1d14b --- /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 0000000000..8a0d49fa76 --- /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 16065a3da8..adb4e3da78 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 #include #include diff --git a/drivers/acpi.cc b/drivers/acpi.cc index 55ea126e88..d1f5f422a2 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 #include #include @@ -19,7 +20,9 @@ extern "C" { #include #include "processor.hh" #include +#if CONF_drivers_xen #include +#endif #include #include @@ -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 6b67d8b7d3..f0828b892f 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 extern "C" { #include "acpi.h" } @@ -15,7 +16,9 @@ extern "C" { #include #include #include "arch.hh" +#if CONF_drivers_xen #include +#endif #include #include "rtc.hh" #include @@ -146,8 +149,10 @@ s64 hpetclock::boot_time() void __attribute__((constructor(init_prio::hpet))) hpet_init() { +#if CONF_drivers_xen XENPV_ALTERNATIVE( { +#endif auto c = clock::get(); // HPET should be only used as a fallback, if no other pvclocks @@ -178,5 +183,7 @@ void __attribute__((constructor(init_prio::hpet))) hpet_init() else { clock::register_clock(new hpet_32bit_clock(hpet_mmio_address)); } +#if CONF_drivers_xen }, {}); +#endif } diff --git a/drivers/pci-generic.cc b/drivers/pci-generic.cc index 6b0a918511..ff96771566 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 #include #include @@ -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 91ca492e98..e03d41f764 100644 --- a/drivers/virtio-blk.cc +++ b/drivers/virtio-blk.cc @@ -6,6 +6,7 @@ */ +#include #include #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 0c5ffb4eeb..e87d0ce1c3 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 #include #include @@ -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 4be60f102c..d2ab7c7662 100644 --- a/drivers/virtio-net.cc +++ b/drivers/virtio-net.cc @@ -6,6 +6,7 @@ */ +#include #include #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 6f5093cdee..e9269d60dd 100644 --- a/drivers/xenclock.cc +++ b/drivers/xenclock.cc @@ -14,6 +14,7 @@ #include "string.h" #include "cpuid.hh" #include +#define CONF_drivers_xen 1 #include #include #include diff --git a/drivers/xenfront-xenbus.cc b/drivers/xenfront-xenbus.cc index ba143841b9..36e7f3dc6e 100644 --- a/drivers/xenfront-xenbus.cc +++ b/drivers/xenfront-xenbus.cc @@ -11,6 +11,7 @@ #include "cpuid.hh" #include #include +#define CONF_drivers_xen 1 #include #include "processor.hh" #include "xenfront.hh" diff --git a/drivers/xenplatform-pci.cc b/drivers/xenplatform-pci.cc index 16488cfa42..15f1ea51af 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 4a54cb9781..48211e7789 100644 --- a/fs/vfs/vfs_conf.cc +++ b/fs/vfs/vfs_conf.cc @@ -38,6 +38,7 @@ * vfs_conf.c - File system configuration. */ +#include #include #include #include @@ -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 5b50c2b631..76ca3b4949 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 da254492c0..4871658753 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 #include "fs/fs.hh" #include #include @@ -20,7 +21,9 @@ #include "smp.hh" #ifdef __x86_64__ +#if CONF_drivers_acpi #include "drivers/acpi.hh" +#endif #endif /* __x86_64__ */ #include @@ -43,7 +46,9 @@ #include #include #include +#if CONF_drivers_xen #include +#endif #include #include #include @@ -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 10c72cca96..3942982c11 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 #include #include #include @@ -48,7 +49,9 @@ #include #include #include +#if CONF_drivers_acpi #include "drivers/pvpanic.hh" +#endif #include #include #include @@ -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 0000000000..4967990a42 --- /dev/null +++ b/scripts/gen-drivers-config-header @@ -0,0 +1,37 @@ +#!/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 <> $tmp + +cat >>$tmp <