qemu虚拟机的实时时钟从哪里来

本文深入探讨了虚拟机中实时钟(RTC)的模拟过程,特别是在QEMU-KVM环境下如何通过模拟RTC设备来记录虚拟机启动时间。文章详细介绍了rtc_realizefn函数如何初始化RTC设备,rtc_set_date_from_host函数如何从宿主机获取时间并写入设备数据结构,以及memory_region_init_io如何为RTC设备分配内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于物理机而言时间是实时时钟(rtc)+启动后时间(boot up time)的和。rtc一般是存在于cmos存储中,它是一个类似于flash的东西,掉电不失,可读写的存储空。rtc存储在里面,每次机器启动的时候读一次就知道机器刚刚启动时的时间了。

对于虚机要想知道启动时的时间就需要vmm提供类似于rtc的东西。也就是模拟rtc设备。对于qemu-kvm虚拟机,如果使用legacy模式,qemu就负责模拟rtc。不过新的替代方案是kvm-clock,这一篇我们只讲使用rtc模式的情况。

qemu模拟rtc是非常容易的事情,只需创建一个rtc的数据结构,再给它一块内存用来读写,初始时间就从主机上获取。看代码:

static void rtc_realizefn(DeviceState *dev, Error **errp)
{
    ISADevice *isadev = ISA_DEVICE(dev);
    RTCState *s = MC146818_RTC(dev);
    int base = 0x70;
...
    rtc_set_date_from_host(isadev);
...
memory_region_init_io(&s->io, OBJECT(s), &cmos_ops, s, "rtc", 2);
...
}

rtc_readlizefn负责实现rtc初始化,rtc_set_date_from_host 负责获取时间并写入设备数据结构。最后memory_region_init_io负责给初始化好的rtc设备分配内存,以后这块内存就作为rtc设备的主体使用了。

static void rtc_set_date_from_host(ISADevice *dev)
{
    RTCState *s = MC146818_RTC(dev);
    struct tm tm;

    qemu_get_timedate(&tm, 0);

    s->base_rtc = mktimegm(&tm);
    s->last_update = qemu_clock_get_ns(rtc_clock);
    s->offset = 0;

    /* set the CMOS date */
    rtc_set_cmos(s, &tm);
}

RTCState就是rtc的数据结构。

int64_t qemu_clock_get_ns(QEMUClockType type)
{
    int64_t now, last;
    QEMUClock *clock = qemu_clock_ptr(type);

    switch (type) {
    case QEMU_CLOCK_REALTIME:
        return get_clock();
    default:
    case QEMU_CLOCK_VIRTUAL:
    case QEMU_CLOCK_VIRTUAL_EXT:
        if (use_icount) {
            return cpu_get_icount();
        } else {
            return cpu_get_clock();
        }
    case QEMU_CLOCK_HOST:
        now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime());
        last = clock->last;
        clock->last = now;
        if (now < last || now > (last + get_max_clock_jump())) {
            notifier_list_notify(&clock->reset_notifiers, &now);
        }
        return now;
...
}

最终qemu调用gettimeofday来获取主机时间。这就是rtc模拟的主要流程。

 

 

### 使用QEMU设置ARM架构虚拟机 #### 准备环境 为了在QEMU中安装和运行ARM架构的虚拟机,需先确保已正确安装QEMU软件包。对于Linux发行版而言,通常可以通过包管理器来完成此操作;而在Windows环境下,则建议前往官方页面获取最新版本并按照指引完成部署[^1]。 #### 获取操作系统镜像 接着要准备适合于ARM平台的操作系统映像文件,这可以是从官方网站下载得到的标准ISO光盘映像或者是预构建好的硬盘驱动器(.img)格式文件。例如Ubuntu Server LTS版本或其他专为ARM设计的操作系统如Kylin OS等[^2]。 #### 配置启动参数 当一切就绪之后,可通过命令行指定一系列选项来定义新创建的虚拟硬件特性: ```bash qemu-system-aarch64 \ -m 4G \ # 设置内存大小为4GB -cpu cortex-a72 \ # 指定CPU型号为Cortex-A72 -smp cores=4 \ # 设定核心数量为四个物理核芯 -M virt \ # 使用virt机器类型 -bios /path/to/QEMU_EFI.fd \ # 加载UEFI固件(如果适用的话) -device virtio-net-pci,netdev=net0 \ netdev user,id=net0 \ # 添加网络适配器连接至宿主机 -drive file=/path/to/image.img,format=qcow2 \ # 映射磁盘图像作为根分区 -cdrom /path/to/install.iso \ # 如果正在安装OS则附加安装介质 ``` 上述脚本展示了如何利用`qemu-system-aarch64`指令建立一个具有特定属性(比如内存量、处理器种类及时钟频率)的基础框架,并挂接必要的外围组件以便顺利引导进入所选的操作系统环境中去[^3]。 #### 启动与维护 一旦完成了初始配置过程,在未来每次重新激活该实例之前只需简单调用相似结构化的语句即可快速恢复先前的工作状态。值得注意的是,针对某些特殊需求可能还需要额外调整其他高级设定项,具体取决于实际应用场景的要求[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值