OBJS += blk-virtio.o
OBJS += cpuid.o
+OBJS += disk-image.o
OBJS += early_printk.o
OBJS += interrupt.o
OBJS += ioport.o
--- /dev/null
+#include "kvm/disk-image.h"
+
+#include "kvm/util.h"
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define SECTOR_SHIFT 9
+#define SECTOR_SIZE (1UL << SECTOR_SHIFT)
+
+struct disk_image *disk_image__open(const char *filename)
+{
+ struct disk_image *self;
+ struct stat st;
+
+ self = malloc(sizeof *self);
+ if (!self)
+ return NULL;
+
+ self->fd = open(filename, O_RDONLY);
+ if (self->fd < 0)
+ goto failed_free;
+
+ if (fstat(self->fd, &st) < 0)
+ goto failed_close_fd;
+
+ self->size = st.st_size;
+
+ self->mmap = mmap(NULL, self->size, PROT_READ, MAP_PRIVATE, self->fd, 0);
+ if (self->mmap == MAP_FAILED)
+ goto failed_close_fd;
+
+ return self;
+
+failed_close_fd:
+ close(self->fd);
+failed_free:
+ free(self);
+
+ return NULL;
+}
+
+void disk_image__close(struct disk_image *self)
+{
+ if (munmap(self->mmap, self->size) < 0)
+ warning("munmap() failed");
+
+ if (close(self->fd) < 0)
+ warning("close() failed");
+
+ free(self);
+}
+
+int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst)
+{
+ uint64_t offset = sector << SECTOR_SHIFT;
+
+ if (offset + SECTOR_SIZE > self->size)
+ return -1;
+
+ memcpy(dst, self->mmap + offset, SECTOR_SIZE);
+
+ return 0;
+}
--- /dev/null
+#ifndef KVM__DISK_IMAGE_H
+#define KVM__DISK_IMAGE_H
+
+#include <stdint.h>
+
+struct disk_image {
+ void *mmap;
+ int fd;
+ uint64_t size;
+};
+
+struct disk_image *disk_image__open(const char *filename);
+void disk_image__close(struct disk_image *self);
+int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst);
+
+#endif /* KVM__DISK_IMAGE_H */
int vcpu_fd; /* For VCPU ioctls() */
struct kvm_run *kvm_run;
+ struct disk_image *disk_image;
uint64_t ram_size;
void *ram_start;
#include "kvm/early_printk.h"
#include "kvm/blk-virtio.h"
+#include "kvm/disk-image.h"
#include "kvm/util.h"
#include "kvm/pci.h"
fprintf(stderr, " usage: %s "
"[--single-step] [--ioport-debug] "
"[--kvm-dev=<device>] [--mem=<size-in-MiB>] [--params=<kernel-params>] "
- "[--initrd=<initrd>] [--kernel=]<kernel-image>\n",
+ "[--initrd=<initrd>] [--kernel=]<kernel-image> [--image=]<disk-image>\n",
argv[0]);
exit(1);
}
{
const char *kernel_filename = NULL;
const char *initrd_filename = NULL;
+ const char *image_filename = NULL;
const char *kernel_cmdline = NULL;
const char *kvm_dev = "/dev/kvm";
unsigned long ram_size = 64UL << 20;
if (option_matches(argv[i], "--kernel=")) {
kernel_filename = &argv[i][9];
continue;
+ } else if (option_matches(argv[i], "--image=")) {
+ image_filename = &argv[i][8];
+ continue;
} else if (option_matches(argv[i], "--initrd=")) {
initrd_filename = &argv[i][9];
continue;
kvm = kvm__init(kvm_dev, ram_size);
+ if (image_filename) {
+ kvm->disk_image = disk_image__open(image_filename);
+ if (!kvm->disk_image)
+ die("unable to load disk image %s", image_filename);
+ }
+
kvm__setup_cpuid(kvm);
strcpy(real_cmdline, "notsc nolapic nosmp noacpi pci=conf1 earlyprintk=ttyS0,keep ");