xref: /kvmtool/x86/boot.c (revision 42ac24f9e8b502767c1882b7ddbe57e4ec9f03fd)
15ad8db5eSPekka Enberg #include "kvm/kvm.h"
25ad8db5eSPekka Enberg 
35ad8db5eSPekka Enberg #include "kvm/util.h"
45ad8db5eSPekka Enberg 
55ad8db5eSPekka Enberg #include <sys/types.h>
65ad8db5eSPekka Enberg #include <sys/stat.h>
75ad8db5eSPekka Enberg #include <stdbool.h>
85ad8db5eSPekka Enberg #include <fcntl.h>
95ad8db5eSPekka Enberg 
105ad8db5eSPekka Enberg #define BIOS_SELECTOR	0xf000
115ad8db5eSPekka Enberg #define BIOS_IP		0xfff0
125ad8db5eSPekka Enberg #define BIOS_SP		0x8000
135ad8db5eSPekka Enberg 
kvm__load_firmware(struct kvm * kvm,const char * firmware_filename)145ad8db5eSPekka Enberg bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
155ad8db5eSPekka Enberg {
165ad8db5eSPekka Enberg 	struct stat st;
175ad8db5eSPekka Enberg 	void *p;
185ad8db5eSPekka Enberg 	int fd;
195ad8db5eSPekka Enberg 	int nr;
205ad8db5eSPekka Enberg 
215ad8db5eSPekka Enberg 	fd = open(firmware_filename, O_RDONLY);
225ad8db5eSPekka Enberg 	if (fd < 0)
235ad8db5eSPekka Enberg 		return false;
245ad8db5eSPekka Enberg 
255ad8db5eSPekka Enberg 	if (fstat(fd, &st))
265ad8db5eSPekka Enberg 		return false;
275ad8db5eSPekka Enberg 
2822f50b6cSCyrill Gorcunov 	if (st.st_size > MB_FIRMWARE_BIOS_SIZE)
29d4f57aa4SJean-Philippe Menil 		die("firmware image %s is too big to fit in memory (%Lu KB).\n", firmware_filename, (u64)(st.st_size / 1024));
305ad8db5eSPekka Enberg 
3122f50b6cSCyrill Gorcunov 	p = guest_flat_to_host(kvm, MB_FIRMWARE_BIOS_BEGIN);
325ad8db5eSPekka Enberg 
335ad8db5eSPekka Enberg 	while ((nr = read(fd, p, st.st_size)) > 0)
345ad8db5eSPekka Enberg 		p += nr;
355ad8db5eSPekka Enberg 
36*42ac24f9SSasha Levin 	kvm->arch.boot_selector	= BIOS_SELECTOR;
37*42ac24f9SSasha Levin 	kvm->arch.boot_ip	= BIOS_IP;
38*42ac24f9SSasha Levin 	kvm->arch.boot_sp	= BIOS_SP;
395ad8db5eSPekka Enberg 
405ad8db5eSPekka Enberg 	return true;
415ad8db5eSPekka Enberg }
42