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 <jwkozac...@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 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/20220209021905.514779-1-jwkozaczuk%40gmail.com.