基于 armhf-qemu 的 ARMv7 linux-5.6 qemu-KVM 代码分析 0 基于ARM32-KVM的little-qemu虚拟机和ARM32裸机代码

little-qemu & test.S

不能用(太庞大) qemu 来探究 qemu 与 kvm 的交互,而是我们要是实现一个小的qemu(little-qemu),并实现一个小的虚拟机程序(test.S)来探究

  • little-qemu
参考
	https://www.cnblogs.com/Bozh/p/5753379.html
	https://www.cnblogs.com/pengdonglin137/p/14083316.html
	http://soulxu.github.io/blog/2014/08/11/use-kvm-api-write-emulator/
实际代码:
https://github.com/lisider/kvm_arm32_simple_vm_demo/tree/arm32
  • test.S
https://github.com/lisider/kvm_arm32_simple_vm_demo/tree/arm32
  • 如何调试
涉及到 
little-qemu(运行在L2) ,L2(ARMv7-ubuntu-16.04) 上运行 arm-gdb
test.S(运行在L3)
linux-5.6-kvm(运行在L1) ,L1(x86_64-ubuntu-20.04) 上运行 arm-gdb
7个ioctl的流程分析
代码参考 https://github.com/lisider/kvm_arm32_simple_vm_demo/tree/arm32
vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0);
	---陷入内核 kvm_dev_ioctl
		case KVM_CREATE_VM: kvm_dev_ioctl_create_vm(arg);
			kvm_create_vm
				kvm_arch_alloc_vm
					kzalloc(sizeof(struct kvm), GFP_KERNEL);
				kvm_eventfd_init
				kvm_arch_init_vm
				hardware_enable_all
				kvm_init_mmu_notifier
				kvm_arch_post_init_vm
				preempt_notifier_inc
			kvm_coalesced_mmio_init
			r = get_unused_fd_flags(O_CLOEXEC);
			file = anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
			kvm_create_vm_debugfs
			kvm_uevent_notify_change(KVM_EVENT_CREATE_VM, kvm);
			fd_install(r, file);
		
vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
	---陷入内核 kvm_vm_ioctl
		case KVM_CREATE_VCPU:kvm_vm_ioctl_create_vcpu(kvm, arg);
			kvm_arch_vcpu_precreate(kvm, id);
			vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
			page = alloc_page(GFP_KERNEL | __GFP_ZERO);
			vcpu->run = page_address(page);
			kvm_vcpu_init(vcpu, kvm, id);
			kvm_arch_vcpu_create(vcpu);
				kvm_timer_vcpu_init
				kvm_pmu_vcpu_init
				kvm_arm_reset_debug_ptr
				kvm_arm_pvtime_vcpu_init
				kvm_vgic_vcpu_init
				create_hyp_mappings(vcpu, vcpu + 1, PAGE_HYP);
			kvm_create_vcpu_debugfs
			r = create_vcpu_fd(vcpu)
				anon_inode_getfd(name, &kvm_vcpu_fops, vcpu, O_RDWR | O_CLOEXEC);
			kvm->vcpus[vcpu->vcpu_idx] = vcpu;
			kvm_arch_vcpu_postcreate(vcpu);
				NULL
			return r;
ioctl(kvm_fd, KVM_GET_VCPU_MMAP_SIZE, NULL);
	---陷入内核kvm_dev_ioctl
		case KVM_GET_VCPU_MMAP_SIZE:
			r = PAGE_SIZE;
			#ifdef CONFIG_KVM_MMIO
			r += PAGE_SIZE;
			#endif
ioctl(vm_fd, KVM_SET_USER_MEMORY_REGION, &mem);
	---陷入内核kvm_vm_ioctl
		case KVM_SET_USER_MEMORY_REGION:
			copy_from_user(&kvm_userspace_mem, argp,sizeof(kvm_userspace_mem));
			kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem)
				kvm_set_memory_region(kvm, mem)
					__kvm_set_memory_region(kvm, mem);
						kvm_arch_create_memslot
						slots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL_ACCOUNT);
						memcpy(slots, __kvm_memslots(kvm, as_id), sizeof(struct kvm_memslots));
						update_memslots(slots, &new, change);
						old_memslots = install_new_memslots(kvm, as_id, slots);
						kvm_arch_commit_memory_region(kvm, mem, &old, &new, change);
						
ioctl(vcpu_fd, KVM_ARM_VCPU_INIT, &init);
	---陷入内核kvm_vcpu_ioctl
		default:kvm_arch_vcpu_ioctl
			case KVM_ARM_VCPU_INIT:
				copy_from_user
				kvm_arch_vcpu_ioctl_vcpu_init
					kvm_vcpu_set_target
						kvm_reset_vcpu
							case KVM_ARM_TARGET_CORTEX_A15:
								reset_regs = &cortexa_regs_reset;
								vcpu->arch.midr = read_cpuid_id();
							memcpy(&vcpu->arch.ctxt.gp_regs, reset_regs, sizeof(vcpu->arch.ctxt.gp_regs));
							kvm_reset_coprocs
							kvm_timer_vcpu_reset(vcpu)
						
ioctl(vcpu_fd, KVM_SET_ONE_REG, &reg);
	---陷入内核kvm_vcpu_ioctl
		default:kvm_arch_vcpu_ioctl
			case KVM_SET_ONE_REG:
				copy_from_user
				kvm_arm_set_reg
					set_core_reg
						((u32 *)regs)[off] = val;


ioctl(vcpu_fd, KVM_RUN, NULL);
	---陷入内核kvm_vcpu_ioctl
		case KVM_RUN:
			kvm_arch_vcpu_run_pid_change
			kvm_arch_vcpu_ioctl_run
				kvm_vcpu_first_run_init
				vcpu->arch.has_run_once = true;
				vcpu_load(vcpu);
				kvm_sigset_activate(vcpu);
				while (ret > 0) {
					/**************************************************************
					* Enter the guest
					* /
					kvm_call_hyp_ret(__kvm_vcpu_run_nvhe, vcpu);
				}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值