diff options
author | jhb <jhb@FreeBSD.org> | 2014-06-12 15:20:59 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2014-06-12 15:20:59 +0000 |
commit | fa121e2a0583ed4d209ed72ba227f186e7b9e0f7 (patch) | |
tree | eae60a05387f74ba5f6cf3252cf8783aba4ddd6b /sys/boot | |
parent | a9824f54c0278b53ff825eeb0a4a4165549e7e41 (diff) | |
download | FreeBSD-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.c | 1 | ||||
-rw-r--r-- | sys/boot/common/load_elf32_obj.c | 1 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/Makefile | 1 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/biossmap.c | 74 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/bootinfo32.c | 18 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/bootinfo64.c | 47 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/elf32_freebsd.c | 36 | ||||
-rw-r--r-- | sys/boot/userboot/userboot/libuserboot.h | 1 |
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); |