zoukankan      html  css  js  c++  java
  • 【firecracker】时钟与中断

    转载  吴斌的博客 » 【firecracker】时钟与中断

    firecracker虚拟机的时钟与中断系统完全是由KVM模块和硬件实现的,这里仅简要说明其原理,更深入的分析需要结合KVM代码和内核代码进行。

    时钟系统原理

      时钟系统包含时间源和时钟事件源两部分:

    • 时间源类似生活中的手表,系统通过它可以获知时间,其本质为一个递增的计数器,计数器数值代表当前时间;firecracker中的时钟源有KVM_CLOCK和TSC两种,默认使用KVM_CLOCK;
    • 时种 事件源类似生活中的闹钟,系统通过它可以获得时间到期通知事件,其本质为一个递减的计数器,且当计数器清零时会产生中断通知;firecracker中的时间事件源有PIT和LAPIC_TIMER两种,系统启动过程中使用PIT,一旦系统启动完成后会切换到LAPIC_TIMER。

    中断系统原理

      X86系统在单核时代是通过两片级联的8259A芯片实现可编程中断控制器,其原理如下图所示。KVM内核也实现了对8259A的模拟,SMP系统在启动初期是采用8259A作为中断控制器。

     到了SMP多核时代,X86系统采用LAPIC+IOAPIC作为中断控制器系统:每个CPU核都有一个LAPIC,作为本地中断控制器;主板上有一个或多个IOAPIC,外设通过IOAPIC广播中断消息给LAPIC,并由各个LAPIC判断是否需要接收并处理该中断消息,如下图蓝色线条所示。SMP在启动过程中通过MP_Table获知了系统中断控制器信息,之后便可以由8259A切换到LAPIC+IOAPIC。

     虽然中断控制器是由KVM模块实现的,但是外设是由用户态VMM程序模拟的,因此KVM模块需要给用户态程序提供触发中断的系统调用接口,即irqfd。它的大致用法如下:

    // initializing irqfd for irq(0)
    let device_fd = EventFd::new().unwrap();     // 创建一个新的EventFd句柄
    Vm.register_irqfd(device_fd.as_raw_fd(), 0); // 通知KVM模块将该句柄与irq进行关联,这里以0号irq(即时钟中断)为例
    // trigger interrupt for irq(0)
    device_fd.wirte(1);                          // 通过写EventFd句柄触发一次0号中断,KVM内核会将0号中断通过IOAPIC
                                                 // 路由到对应的LAPIC,并向vCPU注入中断

    时钟与中断初始化流程setup_interrupt_controller

    firecracker/vmm/src/lib.rs:
    
    struct Vmm {
       …
    }
    
    impl Vmm {
        fn setup_interrupt_controller(&mut self) -> std::result::Result<(), StartMicrovmError> {
            self.vm                                                                     
                .setup_irqchip()                                                         
                .map_err(StartMicrovmError::ConfigureVm)                                
        }
    }
    
    
    firecracker/vmm/src/vstate.rs:
    
    struct Vm {
        …
    }
    
    impl Vm {
        pub fn setup_irqchip(&self) -> Result<()> {                                    
            self.fd.create_irq_chip().map_err(Error::VmSetup)?;      // 通知KVM内核模块创建8259A及IOPAIC+LAPIC中断控制器              
            let mut pit_config = kvm_pit_config::default();     
    
            pit_config.flags = KVM_PIT_SPEAKER_DUMMY;                                   
            self.fd.create_pit2(pit_config).map_err(Error::VmSetup)  // 通知KVM创建PIT时钟事件源                  
        }
    }
  • 相关阅读:
    HDU4714+三分
    HDU1465+递推
    HDU1437+模拟
    HDU1796+容斥原理
    HDU1432+几何
    Linux---Ls命令 初级实现
    HDU1411+四面体的体积
    HDU1412
    HDU1431+简单题
    请定义一个交通工具(Vehicle)的类,其中有: 属性:速度(speed),体积(size)等等
  • 原文地址:https://www.cnblogs.com/dream397/p/13723024.html
Copyright © 2011-2022 走看看