xref: /kvmtool/x86/boot.c (revision 5ad8db5edcb2bed4bef6924c286d7575c4cae72e)
1*5ad8db5eSPekka Enberg #include "kvm/kvm.h"
2*5ad8db5eSPekka Enberg 
3*5ad8db5eSPekka Enberg #include "kvm/util.h"
4*5ad8db5eSPekka Enberg 
5*5ad8db5eSPekka Enberg #include <sys/types.h>
6*5ad8db5eSPekka Enberg #include <sys/stat.h>
7*5ad8db5eSPekka Enberg #include <stdbool.h>
8*5ad8db5eSPekka Enberg #include <fcntl.h>
9*5ad8db5eSPekka Enberg 
10*5ad8db5eSPekka Enberg #define BIOS_SELECTOR	0xf000
11*5ad8db5eSPekka Enberg #define BIOS_IP		0xfff0
12*5ad8db5eSPekka Enberg #define BIOS_SP		0x8000
13*5ad8db5eSPekka Enberg 
14*5ad8db5eSPekka Enberg bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
15*5ad8db5eSPekka Enberg {
16*5ad8db5eSPekka Enberg 	struct stat st;
17*5ad8db5eSPekka Enberg 	void *p;
18*5ad8db5eSPekka Enberg 	int fd;
19*5ad8db5eSPekka Enberg 	int nr;
20*5ad8db5eSPekka Enberg 
21*5ad8db5eSPekka Enberg 	fd = open(firmware_filename, O_RDONLY);
22*5ad8db5eSPekka Enberg 	if (fd < 0)
23*5ad8db5eSPekka Enberg 		return false;
24*5ad8db5eSPekka Enberg 
25*5ad8db5eSPekka Enberg 	if (fstat(fd, &st))
26*5ad8db5eSPekka Enberg 		return false;
27*5ad8db5eSPekka Enberg 
28*5ad8db5eSPekka Enberg 	if (st.st_size > MB_BIOS_SIZE)
29*5ad8db5eSPekka Enberg 		die("firmware image %s is too big to fit in memory (%lu KB).\n", firmware_filename, st.st_size / 1024);
30*5ad8db5eSPekka Enberg 
31*5ad8db5eSPekka Enberg 	p = guest_flat_to_host(kvm, MB_BIOS_BEGIN);
32*5ad8db5eSPekka Enberg 
33*5ad8db5eSPekka Enberg 	while ((nr = read(fd, p, st.st_size)) > 0)
34*5ad8db5eSPekka Enberg 		p += nr;
35*5ad8db5eSPekka Enberg 
36*5ad8db5eSPekka Enberg 	kvm->boot_selector	= BIOS_SELECTOR;
37*5ad8db5eSPekka Enberg 	kvm->boot_ip		= BIOS_IP;
38*5ad8db5eSPekka Enberg 	kvm->boot_sp		= BIOS_SP;
39*5ad8db5eSPekka Enberg 
40*5ad8db5eSPekka Enberg 	return true;
41*5ad8db5eSPekka Enberg }
42