summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-06-12 15:20:59 +0000
committerjhb <jhb@FreeBSD.org>2014-06-12 15:20:59 +0000
commitfa121e2a0583ed4d209ed72ba227f186e7b9e0f7 (patch)
treeeae60a05387f74ba5f6cf3252cf8783aba4ddd6b /sys/boot
parenta9824f54c0278b53ff825eeb0a4a4165549e7e41 (diff)
downloadFreeBSD-src-fa121e2a0583ed4d209ed72ba227f186e7b9e0f7.zip
FreeBSD-src-fa121e2a0583ed4d209ed72ba227f186e7b9e0f7.tar.gz
MFC 261504:
Add support for FreeBSD/i386 guests under bhyve.
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/common/load_elf32.c1
-rw-r--r--sys/boot/common/load_elf32_obj.c1
-rw-r--r--sys/boot/userboot/userboot/Makefile1
-rw-r--r--sys/boot/userboot/userboot/biossmap.c74
-rw-r--r--sys/boot/userboot/userboot/bootinfo32.c18
-rw-r--r--sys/boot/userboot/userboot/bootinfo64.c47
-rw-r--r--sys/boot/userboot/userboot/elf32_freebsd.c36
-rw-r--r--sys/boot/userboot/userboot/libuserboot.h1
8 files changed, 111 insertions, 68 deletions
diff --git a/sys/boot/common/load_elf32.c b/sys/boot/common/load_elf32.c
index 1de5dc1..0c9f460 100644
--- a/sys/boot/common/load_elf32.c
+++ b/sys/boot/common/load_elf32.c
@@ -2,5 +2,6 @@
__FBSDID("$FreeBSD$");
#define __ELF_WORD_SIZE 32
+#define _MACHINE_ELF_WANT_32BIT
#include "load_elf.c"
diff --git a/sys/boot/common/load_elf32_obj.c b/sys/boot/common/load_elf32_obj.c
index fed25ef..94b0896 100644
--- a/sys/boot/common/load_elf32_obj.c
+++ b/sys/boot/common/load_elf32_obj.c
@@ -2,5 +2,6 @@
__FBSDID("$FreeBSD$");
#define __ELF_WORD_SIZE 32
+#define _MACHINE_ELF_WANT_32BIT
#include "load_elf_obj.c"
diff --git a/sys/boot/userboot/userboot/Makefile b/sys/boot/userboot/userboot/Makefile
index 1df1f30..076b4b2 100644
--- a/sys/boot/userboot/userboot/Makefile
+++ b/sys/boot/userboot/userboot/Makefile
@@ -11,6 +11,7 @@ STRIP=
LIBDIR= /boot
SRCS= autoload.c
+SRCS+= biossmap.c
SRCS+= bootinfo.c
SRCS+= bootinfo32.c
SRCS+= bootinfo64.c
diff --git a/sys/boot/userboot/userboot/biossmap.c b/sys/boot/userboot/userboot/biossmap.c
new file mode 100644
index 0000000..9e556be
--- /dev/null
+++ b/sys/boot/userboot/userboot/biossmap.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <machine/pc/bios.h>
+#include <machine/metadata.h>
+
+#include "bootstrap.h"
+#include "libuserboot.h"
+
+#define GB (1024UL * 1024 * 1024)
+
+void
+bios_addsmapdata(struct preloaded_file *kfp)
+{
+ uint64_t lowmem, highmem;
+ int smapnum, len;
+ struct bios_smap smap[3], *sm;
+
+ CALLBACK(getmem, &lowmem, &highmem);
+
+ sm = &smap[0];
+
+ sm->base = 0; /* base memory */
+ sm->length = 640 * 1024;
+ sm->type = SMAP_TYPE_MEMORY;
+ sm++;
+
+ sm->base = 0x100000; /* extended memory */
+ sm->length = lowmem - 0x100000;
+ sm->type = SMAP_TYPE_MEMORY;
+ sm++;
+
+ smapnum = 2;
+
+ if (highmem != 0) {
+ sm->base = 4 * GB;
+ sm->length = highmem;
+ sm->type = SMAP_TYPE_MEMORY;
+ smapnum++;
+ }
+
+ len = smapnum * sizeof(struct bios_smap);
+ file_addmetadata(kfp, MODINFOMD_SMAP, len, &smap[0]);
+}
diff --git a/sys/boot/userboot/userboot/bootinfo32.c b/sys/boot/userboot/userboot/bootinfo32.c
index 4e6447a..6498461 100644
--- a/sys/boot/userboot/userboot/bootinfo32.c
+++ b/sys/boot/userboot/userboot/bootinfo32.c
@@ -66,7 +66,7 @@ static struct bootinfo bi;
COPY32(strlen(s) + 1, a, c); \
if (c) \
CALLBACK(copyin, s, a, strlen(s) + 1); \
- a += roundup(strlen(s) + 1, sizeof(u_long));\
+ a += roundup(strlen(s) + 1, sizeof(uint32_t));\
}
#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
@@ -78,7 +78,7 @@ static struct bootinfo bi;
COPY32(sizeof(s), a, c); \
if (c) \
CALLBACK(copyin, &s, a, sizeof(s)); \
- a += roundup(sizeof(s), sizeof(u_long)); \
+ a += roundup(sizeof(s), sizeof(uint32_t)); \
}
#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
@@ -89,7 +89,7 @@ static struct bootinfo bi;
COPY32(mm->md_size, a, c); \
if (c) \
CALLBACK(copyin, mm->md_data, a, mm->md_size); \
- a += roundup(mm->md_size, sizeof(u_long));\
+ a += roundup(mm->md_size, sizeof(uint32_t));\
}
#define MOD_END(a, c) { \
@@ -146,6 +146,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t
int bootdevnr, howto;
char *kernelname;
const char *kernelpath;
+ uint64_t lowmem, highmem;
howto = bi_getboothowto(args);
@@ -198,9 +199,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
-#if 0
bios_addsmapdata(kfp);
-#endif
/* Figure out the size and location of the metadata */
*modulep = addr;
@@ -237,11 +236,10 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t
bi.bi_bios_geom[i] = bd_getbigeom(i);
#endif
bi.bi_size = sizeof(bi);
+ CALLBACK(getmem, &lowmem, &highmem);
bi.bi_memsizes_valid = 1;
-#if 0
- bi.bi_basemem = bios_basemem / 1024;
- bi.bi_extmem = bios_extmem / 1024;
-#endif
+ bi.bi_basemem = 640;
+ bi.bi_extmem = (lowmem - 0x100000) / 1024;
bi.bi_envp = envp;
bi.bi_modulep = *modulep;
bi.bi_kernend = kernend;
@@ -251,7 +249,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t
/*
* Copy the legacy bootinfo and kernel name to the guest at 0x2000
*/
- bi.bi_kernelname = (char *) (0x2000 + sizeof(bi));
+ bi.bi_kernelname = 0x2000 + sizeof(bi);
CALLBACK(copyin, &bi, 0x2000, sizeof(bi));
CALLBACK(copyin, kernelname, 0x2000 + sizeof(bi), strlen(kernelname) + 1);
diff --git a/sys/boot/userboot/userboot/bootinfo64.c b/sys/boot/userboot/userboot/bootinfo64.c
index fc7c14d..10ff133 100644
--- a/sys/boot/userboot/userboot/bootinfo64.c
+++ b/sys/boot/userboot/userboot/bootinfo64.c
@@ -169,53 +169,6 @@ bi_checkcpu(void)
#endif
}
-struct smap {
- uint64_t base;
- uint64_t length;
- uint32_t type;
-} __packed;
-
-/* From FreeBSD <machine/pc/bios.h> */
-#define SMAP_TYPE_MEMORY 1
-
-#define GB (1024UL * 1024 * 1024)
-
-#define MODINFOMD_SMAP 0x1001
-
-static void
-bios_addsmapdata(struct preloaded_file *kfp)
-{
- uint64_t lowmem, highmem;
- int smapnum, len;
- struct smap smap[3], *sm;
-
- CALLBACK(getmem, &lowmem, &highmem);
-
- sm = &smap[0];
-
- sm->base = 0; /* base memory */
- sm->length = 640 * 1024;
- sm->type = SMAP_TYPE_MEMORY;
- sm++;
-
- sm->base = 0x100000; /* extended memory */
- sm->length = lowmem - 0x100000;
- sm->type = SMAP_TYPE_MEMORY;
- sm++;
-
- smapnum = 2;
-
- if (highmem != 0) {
- sm->base = 4 * GB;
- sm->length = highmem;
- sm->type = SMAP_TYPE_MEMORY;
- smapnum++;
- }
-
- len = smapnum * sizeof (struct smap);
- file_addmetadata(kfp, MODINFOMD_SMAP, len, &smap[0]);
-}
-
/*
* Load the information expected by an amd64 kernel.
*
diff --git a/sys/boot/userboot/userboot/elf32_freebsd.c b/sys/boot/userboot/userboot/elf32_freebsd.c
index bb5b693..d8ccc33 100644
--- a/sys/boot/userboot/userboot/elf32_freebsd.c
+++ b/sys/boot/userboot/userboot/elf32_freebsd.c
@@ -45,6 +45,9 @@ static int elf32_obj_exec(struct preloaded_file *amp);
struct file_format i386_elf = { elf32_loadfile, elf32_exec };
struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec };
+#define GUEST_STACK 0x1000 /* Initial stack base */
+#define GUEST_GDT 0x3000 /* Address of initial GDT */
+
/*
* There is an ELF kernel and one or more ELF modules loaded.
* We wish to start executing the kernel image, so make such
@@ -57,7 +60,7 @@ elf32_exec(struct preloaded_file *fp)
Elf_Ehdr *ehdr;
vm_offset_t entry, bootinfop, modulep, kernend;
int boothowto, err, bootdev;
- uint32_t stack[1024];
+ uint32_t stack[1024], *sp;
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
@@ -78,16 +81,27 @@ elf32_exec(struct preloaded_file *fp)
/*
* Build a scratch stack at physical 0x1000
*/
- stack[0] = boothowto;
- stack[1] = bootdev;
- stack[2] = 0;
- stack[3] = 0;
- stack[4] = 0;
- stack[5] = bootinfop;
- stack[6] = modulep;
- stack[7] = kernend;
- CALLBACK(copyin, stack, 0x1000, sizeof(stack));
- CALLBACK(setreg, 4, 0x1000);
+ memset(stack, 0, sizeof(stack));
+ sp = (uint32_t *)((char *)stack + sizeof(stack));
+ *--sp = kernend;
+ *--sp = modulep;
+ *--sp = bootinfop;
+ *--sp = 0;
+ *--sp = 0;
+ *--sp = 0;
+ *--sp = bootdev;
+ *--sp = boothowto;
+
+ /*
+ * Fake return address to mimic "new" boot blocks. For more
+ * details see recover_bootinfo in locore.S.
+ */
+ *--sp = 0xbeefface;
+ CALLBACK(copyin, stack, GUEST_STACK, sizeof(stack));
+ CALLBACK(setreg, 4, (char *)sp - (char *)stack + GUEST_STACK);
+
+ CALLBACK(setgdt, GUEST_GDT, 8 * 4 - 1);
+
CALLBACK(exec, entry);
panic("exec returned");
diff --git a/sys/boot/userboot/userboot/libuserboot.h b/sys/boot/userboot/userboot/libuserboot.h
index d795188..e2048d5 100644
--- a/sys/boot/userboot/userboot/libuserboot.h
+++ b/sys/boot/userboot/userboot/libuserboot.h
@@ -65,3 +65,4 @@ vm_offset_t bi_copyenv(vm_offset_t addr);
int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip,
vm_offset_t *modulep, vm_offset_t *kernend);
int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernend);
+void bios_addsmapdata(struct preloaded_file *kfp);
OpenPOWER on IntegriCloud