mirror of
				https://github.com/projectacrn/acrn-hypervisor.git
				synced 2025-10-31 09:23:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			136 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. _modularity:
 | |
| 
 | |
| ACRN Hypervisor: Modular Design
 | |
| ###############################
 | |
| 
 | |
| Overview
 | |
| ********
 | |
| 
 | |
| ACRN highly emphasizes modular design, which is the separation of
 | |
| functionality into modules that define a concise set of interfaces. The goals
 | |
| of modular design include:
 | |
| 
 | |
| * **Understandability** A modular design is easier to understand due to
 | |
|   encapsulation.
 | |
| * **Testability** Modules can be integrated and tested in the reverse order of
 | |
|   dependencies among them. Modular integration tests help improve the coverage
 | |
|   of tests and identify corner cases that are hard to trigger when testing the
 | |
|   hypervisor as a whole.
 | |
| * **Configurability** Modular design makes it easy to configure certain
 | |
|   functionalities in or out. This is crucial in safety-critical scenarios,
 | |
|   because absence of irrelevant code is required in both MISRA-C and
 | |
|   functional safety standards.
 | |
| * **Meet functional safety requirements** Functional safety standards
 | |
|   explicitly require a hierarchical structure of modules in software
 | |
|   architectural design. This applies to any safety integrity level defined in
 | |
|   [IEC_61508-3]_ and [ISO_26262-6]_.
 | |
| 
 | |
| Principles
 | |
| **********
 | |
| 
 | |
| * Each source file belongs to one module only. One module may consist of one
 | |
|   or multiple source files, though. A source file can be a C source, a C
 | |
|   header, or an assembly file.
 | |
| * Each module has well-defined interfaces, including the exported functions
 | |
|   and global variables. Functions and variables that are not interfaces are
 | |
|   static and used inside the module only.
 | |
| * Dependencies among the modules should be acyclic. Any cyclic dependency must
 | |
|   be deviated explicitly.
 | |
| * The complexity of a module should be limited.
 | |
| 
 | |
| Minimizing Cyclic Dependencies
 | |
| ==============================
 | |
| 
 | |
| Cyclic dependencies are mostly avoided through careful definition of module
 | |
| boundaries. The following methods can be used when a cyclic dependency cannot
 | |
| be resolved by design:
 | |
| 
 | |
| * **Use callbacks** Callback registration and invocation help to reverse
 | |
|   dependencies between modules and break cyclic dependencies. However,
 | |
|   callbacks must be used with care due to their dynamic behavior. Send
 | |
|   proposals or patches to the
 | |
|   `acrn-dev mailing list <https://lists.projectacrn.org/g/acrn-dev>`_ for
 | |
|   discussing whether specific callbacks are appropriate.
 | |
| * **Making the cyclic dependency an exception** A specific cyclic dependency
 | |
|   can be regarded as an exception if it is well justified and a workaround is
 | |
|   available to break the cyclic dependency for integration testing.
 | |
| 
 | |
| Measuring Complexity
 | |
| ====================
 | |
| 
 | |
| ACRN uses the number of functions and the cyclomatic complexity [CC]_ of each
 | |
| function to measure the complexity of a module. Concrete criteria on
 | |
| complexity will be determined during the process of enhancing the modularity
 | |
| of the hypervisor. The current recommendation is to limit the cyclomatic
 | |
| complexity of a function to under 20.
 | |
| 
 | |
| Architecture
 | |
| ************
 | |
| 
 | |
| The following figure shows the high-level components of ACRN hypervisor:
 | |
| 
 | |
| .. figure:: images/modularity-architecture.png
 | |
|    :align: center
 | |
|    :name: modularity-architecture
 | |
| 
 | |
|    Layered Architecture of ACRN Hypervisor
 | |
| 
 | |
| The components are listed as follows.
 | |
| 
 | |
| * **Boot** This component carries out the most basic hardware initialization
 | |
|   to enable the execution of C code.
 | |
| * **Library** This component consists of subroutines that require no explicit
 | |
|   initialization. Examples include standard memory and string manipulation
 | |
|   functions like strncpy, atomic operations, and bitmap operations. This
 | |
|   component is independent from and widely used in the other components.
 | |
| * **Hardware Management and Utilities** This component abstracts hardware
 | |
|   resources and provide services such as timers and physical interrupt handler
 | |
|   registration to the upper layers.
 | |
| * **Virtual CPU** This component implements CPU, memory, and interrupt
 | |
|   virtualization. The vCPU loop module in this component handles VM exit
 | |
|   events by calling the proper handler in the other components. Hypercalls are
 | |
|   implemented as a special type of VM exit event. This component is also able
 | |
|   to inject upcall interrupts to the Service VM.
 | |
| * **Device Emulation** This component implements devices that are emulated in
 | |
|   the hypervisor itself, such as the virtual programmable interrupt
 | |
|   controllers including vPIC, vLAPIC, and vIOAPIC.
 | |
| * **Passthrough Management** This component manages devices that are passed
 | |
|   through to specific VMs.
 | |
| * **Extended Device Emulation** This component implements an I/O request
 | |
|   mechanism that enables the hypervisor to forward I/O accesses from a User
 | |
|   VM to the Service VM for emulation.
 | |
| * **VM Management** This component manages the creation, deletion, and other
 | |
|   lifecycle operations of VMs.
 | |
| * **Hypervisor Initialization** This component invokes the initialization
 | |
|   subroutines in the other components to bring up the hypervisor and start
 | |
|   the Service VM in sharing mode or all the VMs in partitioning mode.
 | |
| 
 | |
| ACRN hypervisor adopts a layered design where higher layers can invoke the
 | |
| interfaces of lower layers but not vice versa. The only exception is the
 | |
| invocation of initialization routine in the **Boot** component, illustrated as
 | |
| the arrow from bottom to top on the left side of figure
 | |
| :numref:`modularity-architecture`. This exception is made due to the following
 | |
| reasons.
 | |
| 
 | |
| * **Boot** enables the execution of C code and thus has to be the lowest layer
 | |
|   in the architecture.
 | |
| * **Hypervisor Initialization** contains the hypervisor initialization
 | |
|   function that calls the initialization functions of each layer. Thus this
 | |
|   component is the highest layer to minimize reverse dependencies.
 | |
| * **Boot** shall invoke the hypervisor initialization routine after bringing
 | |
|   up the hardware. This inevitably causes a reverse dependency from **Boot**
 | |
|   to **Hypervisor Initialization**.
 | |
| 
 | |
| To enable integration testing of a layer in the middle (e.g. **Virtual CPU**),
 | |
| **Boot** will invoke a customized function that invokes only the
 | |
| initialization functions of that layer as well as the layers below.
 | |
| 
 | |
| References
 | |
| **********
 | |
| 
 | |
| .. [IEC_61508-3] IEC 61508-3:2010, Functional safety of electrical/electronic/programmable electronic safety-related systems - Part 3: Software requirements
 | |
| 
 | |
| .. [ISO_26262-6] ISO 26262-6:2011, Road vehicles - Functional safety - Part 6: Product development at the software level
 | |
| 
 | |
| .. [CC] Cyclomatic complexity - Wikipedia, https://en.wikipedia.org/wiki/Cyclomatic_complexity
 |