diff --git a/Makefile b/Makefile
index 121d8acf5be6fffaf7081a93fa1375f0188a436c..ad8a97f29e1a2deb7e8a09a12c345c9ca1e03cc5 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,10 @@ check: export image ?= tests
 check: all
 	./scripts/test.py
 
+osv.vmdk osv.vdi:
+	$(MAKE) -r -C $(dir $(submake)) $@
+.PHONY: osv.vmdk osv.vdi
+
 # "tags" is the default output file of ctags, "TAGS" is that of etags
 tags TAGS:
 	rm -f -- "$@"
diff --git a/build.mk b/build.mk
index 42ac6899fec3d3802ab7012201b2c172719e7576..50402f0a3093c9a9e3360bae5df1e4f10a12e073 100644
--- a/build.mk
+++ b/build.mk
@@ -735,6 +735,12 @@ usr.img: bare.img $(out)/usr.manifest $(out)/cmdline
 		glibcbase=$(glibcbase) -D miscbase=$(miscbase)
 	$(call quiet, $(src)/scripts/imgedit.py setargs $@ "$(shell cat $(out)/cmdline)", IMGEDIT $@)
 
+osv.vmdk osv.vdi:
+	$(call quiet, echo Creating $@ as $(subst osv.,,$@))
+	$(call quiet, qemu-img convert -O $(subst osv.,,$@) usr.img $@)
+	$(call quiet, $(src)/scripts/imgedit.py setargs $@ "--vga $(shell cat $(out)/cmdline)", IMGEDIT $@)
+.PHONY: osv.vmdk osv.vdi
+
 $(jni): INCLUDES += -I /usr/lib/jvm/java/include -I /usr/lib/jvm/java/include/linux/
 
 bootfs.bin: scripts/mkbootfs.py $(java-targets) $(out)/bootfs.manifest $(tests) $(java_tests) $(tools) \