#include "kvm/kvm.h"
+#include "kvm/boot-protocol.h"
+#include "kvm/e820.h"
#include "kvm/interrupt.h"
#include "kvm/util.h"
interrupt_table__set(&kvm->interrupt_table, &intr_desc, handler->irq);
}
+/**
+ * e820_setup - setup some simple E820 memory map
+ * @kvm - guest system descriptor
+ */
+static void e820_setup(struct kvm *kvm)
+{
+ struct e820_entry *mem_map;
+ unsigned char *size;
+ unsigned int i = 0;
+
+ size = guest_flat_to_host(kvm, E820_MAP_SIZE);
+ mem_map = guest_flat_to_host(kvm, E820_MAP_START);
+
+ *size = E820_MEM_AREAS;
+
+ mem_map[i++] = (struct e820_entry) {
+ .addr = REAL_MODE_IVT_BEGIN,
+ .size = EBDA_START - REAL_MODE_IVT_BEGIN,
+ .type = E820_MEM_USABLE,
+ };
+ mem_map[i++] = (struct e820_entry) {
+ .addr = EBDA_START,
+ .size = VGA_RAM_BEGIN - EBDA_START,
+ .type = E820_MEM_RESERVED,
+ };
+ mem_map[i++] = (struct e820_entry) {
+ .addr = MB_BIOS_BEGIN,
+ .size = MB_BIOS_END - MB_BIOS_BEGIN,
+ .type = E820_MEM_RESERVED,
+ };
+ mem_map[i++] = (struct e820_entry) {
+ .addr = BZ_KERNEL_START,
+ .size = kvm->ram_size - BZ_KERNEL_START,
+ .type = E820_MEM_USABLE,
+ };
+
+ BUILD_BUG_ON(i > E820_MEM_AREAS);
+}
+
+/**
+ * setup_bios - inject BIOS into guest memory
+ * @kvm - guest system descriptor
+ */
void setup_bios(struct kvm *kvm)
{
unsigned long address = MB_BIOS_BEGIN;
p = guest_flat_to_host(kvm, MB_BIOS_BEGIN);
memcpy(p, bios_rom, bios_rom_size);
+ /* E820 memory map must be present */
+ e820_setup(kvm);
+
/*
* Setup a *fake* real mode vector table, it has only
* one real hadler which does just iret
--- /dev/null
+/*
+ * Linux boot protocol specifics
+ */
+
+#ifndef BOOT_PROTOCOL_H_
+#define BOOT_PROTOCOL_H_
+
+/*
+ * The protected mode kernel part of a modern bzImage is loaded
+ * at 1 MB by default.
+ */
+#define BZ_DEFAULT_SETUP_SECTS 4
+#define BZ_KERNEL_START 0x100000UL
+#define INITRD_START 0x1000000UL
+
+#endif /* BOOT_PROTOCOL_H_ */
#define E820_MEM_USABLE 1
#define E820_MEM_RESERVED 2
+#define E820_MEM_AREAS 4
+
struct e820_entry {
uint64_t addr; /* start of memory segment */
uint64_t size; /* size of memory segment */
bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
const char *initrd_filename, const char *kernel_cmdline);
void kvm__reset_vcpu(struct kvm *self);
-void kvm__setup_mem(struct kvm *self);
+void kvm__setup_bios(struct kvm *self);
void kvm__start_timer(struct kvm *self);
void kvm__run(struct kvm *self);
void kvm__irq_line(struct kvm *self, int irq, int level);
extern void info(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
#define DIE_IF(cnd) \
do { \
if (cnd) \
#include "kvm/cpufeature.h"
#include "kvm/interrupt.h"
-#include "kvm/e820.h"
+#include "kvm/boot-protocol.h"
#include "kvm/util.h"
#include <linux/kvm.h>
return true;
}
-/*
- * The protected mode kernel part of a modern bzImage is loaded at 1 MB by
- * default.
- */
-#define BZ_KERNEL_START 0x100000UL
-#define INITRD_START 0x1000000UL
-#define BZ_DEFAULT_SETUP_SECTS 4
static const char *BZIMAGE_MAGIC = "HdrS";
static bool load_bzimage(struct kvm *self, int fd_kernel,
kvm__setup_msrs(self);
}
-void kvm__setup_mem(struct kvm *self)
+/**
+ * kvm__setup_bios - inject BIOS into guest system memory
+ * @self - guest system descriptor
+ *
+ * This function is a main routine where we poke guest memory
+ * and install BIOS there.
+ */
+void kvm__setup_bios(struct kvm *self)
{
- struct e820_entry *mem_map;
- unsigned char *size;
-
- size = guest_flat_to_host(self, E820_MAP_SIZE);
- mem_map = guest_flat_to_host(self, E820_MAP_START);
+ /* standart minimal configuration */
+ setup_bios(self);
- *size = 4;
-
- mem_map[0] = (struct e820_entry) {
- .addr = REAL_MODE_IVT_BEGIN,
- .size = EBDA_START - REAL_MODE_IVT_BEGIN,
- .type = E820_MEM_USABLE,
- };
- mem_map[1] = (struct e820_entry) {
- .addr = EBDA_START,
- .size = VGA_RAM_BEGIN - EBDA_START,
- .type = E820_MEM_RESERVED,
- };
- mem_map[2] = (struct e820_entry) {
- .addr = MB_BIOS_BEGIN,
- .size = MB_BIOS_END - MB_BIOS_BEGIN,
- .type = E820_MEM_RESERVED,
- };
- mem_map[3] = (struct e820_entry) {
- .addr = BZ_KERNEL_START,
- .size = self->ram_size - BZ_KERNEL_START,
- .type = E820_MEM_USABLE,
- };
+ /* FIXME: SMP, ACPI and friends here */
}
#define TIMER_INTERVAL_NS 1000000 /* 1 msec */
kvm__reset_vcpu(kvm);
- setup_bios(kvm);
-
- kvm__setup_mem(kvm);
+ kvm__setup_bios(kvm);
if (single_step)
kvm__enable_singlestep(kvm);