svn commit: r263976 - in projects/arm64/sys: arm64/arm64 arm64/include boot/arm64/efi
Andrew Turner
andrew at FreeBSD.org
Mon Mar 31 19:50:42 UTC 2014
Author: andrew
Date: Mon Mar 31 19:50:40 2014
New Revision: 263976
URL: http://svnweb.freebsd.org/changeset/base/263976
Log:
Pass module data to the kernel and have the memory map passed though it.
Added:
projects/arm64/sys/arm64/include/metadata.h (contents, props changed)
projects/arm64/sys/boot/arm64/efi/bootinfo.c (contents, props changed)
Modified:
projects/arm64/sys/arm64/arm64/machdep.c
projects/arm64/sys/boot/arm64/efi/Makefile
projects/arm64/sys/boot/arm64/efi/exec.c
Modified: projects/arm64/sys/arm64/arm64/machdep.c
==============================================================================
--- projects/arm64/sys/arm64/arm64/machdep.c Mon Mar 31 19:37:39 2014 (r263975)
+++ projects/arm64/sys/arm64/arm64/machdep.c Mon Mar 31 19:50:40 2014 (r263976)
@@ -32,18 +32,22 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cpu.h>
+#include <sys/efi.h>
#include <sys/imgact.h>
+#include <sys/linker.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
+#include <sys/reboot.h>
#include <sys/signalvar.h>
#include <sys/sysproto.h>
#include <sys/ucontext.h>
-#include <machine/bootinfo.h>
#include <machine/cpu.h>
+#include <machine/metadata.h>
#include <machine/pcb.h>
#include <machine/reg.h>
+#include <machine/vmparam.h>
struct pcpu __pcpu[MAXCPU];
struct pcpu *pcpup = &__pcpu[0];
@@ -53,6 +57,8 @@ vm_paddr_t phys_avail[10];
int cold = 1;
long realmem = 0;
+#define PHYSMAP_SIZE (2 * (VM_PHYSSEG_MAX - 1))
+
void
bzero(void *buf, size_t len)
{
@@ -254,7 +260,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi,
panic("sendsig");
}
-void initarm(struct bootinfo *);
+void initarm(vm_offset_t);
#ifdef EARLY_PRINTF
static void
@@ -277,32 +283,195 @@ typedef struct {
uint64_t attr;
} EFI_MEMORY_DESCRIPTOR;
+static int
+add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
+ int *physmap_idxp)
+{
+ int i, insert_idx, physmap_idx;
+
+ physmap_idx = *physmap_idxp;
+
+ if (length == 0)
+ return (1);
+
+ /*
+ * Find insertion point while checking for overlap. Start off by
+ * assuming the new entry will be added to the end.
+ */
+ insert_idx = physmap_idx + 2;
+ for (i = 0; i <= physmap_idx; i += 2) {
+ if (base < physmap[i + 1]) {
+ if (base + length <= physmap[i]) {
+ insert_idx = i;
+ break;
+ }
+ if (boothowto & RB_VERBOSE)
+ printf(
+ "Overlapping memory regions, ignoring second region\n");
+ return (1);
+ }
+ }
+
+ /* See if we can prepend to the next entry. */
+ if (insert_idx <= physmap_idx && base + length == physmap[insert_idx]) {
+ physmap[insert_idx] = base;
+ return (1);
+ }
+
+ /* See if we can append to the previous entry. */
+ if (insert_idx > 0 && base == physmap[insert_idx - 1]) {
+ physmap[insert_idx - 1] += length;
+ return (1);
+ }
+
+ physmap_idx += 2;
+ *physmap_idxp = physmap_idx;
+ if (physmap_idx == PHYSMAP_SIZE) {
+ printf(
+ "Too many segments in the physical address map, giving up\n");
+ return (0);
+ }
+
+ /*
+ * Move the last 'N' entries down to make room for the new
+ * entry if needed.
+ */
+ for (i = physmap_idx; i > insert_idx; i -= 2) {
+ physmap[i] = physmap[i - 2];
+ physmap[i + 1] = physmap[i - 1];
+ }
+
+ /* Insert the new entry. */
+ physmap[insert_idx] = base;
+ physmap[insert_idx + 1] = base + length;
+ return (1);
+}
+
+#define efi_next_descriptor(ptr, size) \
+ ((struct efi_md *)(((uint8_t *) ptr) + size))
+
+static void
+add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap,
+ int *physmap_idx)
+{
+ struct efi_md *map, *p;
+ const char *type;
+ size_t efisz;
+ int ndesc, i;
+
+ static const char *types[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode"
+ };
+
+ /*
+ * Memory map data provided by UEFI via the GetMemoryMap
+ * Boot Services API.
+ */
+ efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+ map = (struct efi_md *)((uint8_t *)efihdr + efisz);
+
+ if (efihdr->descriptor_size == 0)
+ return;
+ ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+ if (boothowto & RB_VERBOSE)
+ printf("%23s %12s %12s %8s %4s\n",
+ "Type", "Physical", "Virtual", "#Pages", "Attr");
+
+ for (i = 0, p = map; i < ndesc; i++,
+ p = efi_next_descriptor(p, efihdr->descriptor_size)) {
+ if (boothowto & RB_VERBOSE) {
+ if (p->md_type <= EFI_MD_TYPE_PALCODE)
+ type = types[p->md_type];
+ else
+ type = "<INVALID>";
+ printf("%23s %012llx %12p %08llx ", type, p->md_phys,
+ p->md_virt, p->md_pages);
+ if (p->md_attr & EFI_MD_ATTR_UC)
+ printf("UC ");
+ if (p->md_attr & EFI_MD_ATTR_WC)
+ printf("WC ");
+ if (p->md_attr & EFI_MD_ATTR_WT)
+ printf("WT ");
+ if (p->md_attr & EFI_MD_ATTR_WB)
+ printf("WB ");
+ if (p->md_attr & EFI_MD_ATTR_UCE)
+ printf("UCE ");
+ if (p->md_attr & EFI_MD_ATTR_WP)
+ printf("WP ");
+ if (p->md_attr & EFI_MD_ATTR_RP)
+ printf("RP ");
+ if (p->md_attr & EFI_MD_ATTR_XP)
+ printf("XP ");
+ if (p->md_attr & EFI_MD_ATTR_RT)
+ printf("RUNTIME");
+ printf("\n");
+ }
+
+ switch (p->md_type) {
+ case EFI_MD_TYPE_CODE:
+ case EFI_MD_TYPE_DATA:
+ case EFI_MD_TYPE_BS_CODE:
+ case EFI_MD_TYPE_BS_DATA:
+ case EFI_MD_TYPE_FREE:
+ /*
+ * We're allowed to use any entry with these types.
+ */
+ break;
+ default:
+ continue;
+ }
+
+ if (!add_physmap_entry(p->md_phys, (p->md_pages * PAGE_SIZE),
+ physmap, physmap_idx))
+ break;
+ }
+}
void
-initarm(struct bootinfo *bi)
+initarm(vm_offset_t modulep)
{
- EFI_MEMORY_DESCRIPTOR *desc;
- const char str[] = "FreeBSD\r\n";
- volatile uint32_t *uart;
+ vm_paddr_t physmap[PHYSMAP_SIZE];
+ struct efi_map_header *efihdr;
+ int physmap_idx;
+ caddr_t kmdp;
+ vm_paddr_t mem_len;
int i;
- uart = (uint32_t*)0x1c090000;
- for (i = 0; i < sizeof(str); i++) {
- *uart = str[i];
- }
-
- printf("In initarm on arm64 %p\n", bi);
- printf("%llx\n", bi->bi_memmap);
- printf("%llx\n", bi->bi_memmap_size);
- printf("%llx\n", bi->bi_memdesc_size);
- printf("%llx\n", bi->bi_memdesc_version);
-
- desc = (void *)bi->bi_memmap;
- for (i = 0; i < bi->bi_memmap_size / bi->bi_memdesc_size; i++) {
- printf("%x %llx %llx %llx %llx\n", desc->type,
- desc->phys_start, desc->virt_start, desc->num_pages,
- desc->attr);
+ printf("In initarm on arm64 %llx\n", modulep);
- desc = (void *)((uint8_t *)desc + bi->bi_memdesc_size);
+ /* Find the kernel address */
+ preload_metadata = (caddr_t)(uintptr_t)(modulep);
+ kmdp = preload_search_by_type("elf kernel");
+ if (kmdp == NULL)
+ kmdp = preload_search_by_type("elf64 kernel");
+
+ /* Load the physical memory ranges */
+ physmap_idx = 0;
+ efihdr = (struct efi_map_header *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_EFI_MAP);
+ add_efi_map_entries(efihdr, physmap, &physmap_idx);
+
+ /* Print the memory map */
+ mem_len = 0;
+ for (i = 0; i <= physmap_idx; i += 2) {
+ mem_len += physmap[i + 1] - physmap[i];
+ printf("%llx - %llx\n", physmap[i], physmap[i + 1]);
}
+ printf("Total = %llx\n", mem_len);
+
+ printf("End initarm\n");
}
Added: projects/arm64/sys/arm64/include/metadata.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/arm64/sys/arm64/include/metadata.h Mon Mar 31 19:50:40 2014 (r263976)
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2014 Andrew Turner <andrew at 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_METADATA_H_
+#define _MACHINE_METADATA_H_
+
+#define MODINFOMD_EFI_MAP 0x1001
+
+struct efi_map_header {
+ size_t memory_size;
+ size_t descriptor_size;
+ uint32_t descriptor_version;
+};
+
+#endif /* !_MACHINE_METADATA_H_ */
Modified: projects/arm64/sys/boot/arm64/efi/Makefile
==============================================================================
--- projects/arm64/sys/boot/arm64/efi/Makefile Mon Mar 31 19:37:39 2014 (r263975)
+++ projects/arm64/sys/boot/arm64/efi/Makefile Mon Mar 31 19:50:40 2014 (r263976)
@@ -11,7 +11,7 @@ INTERNALPROG=
# architecture-specific loader code
SRCS= start.S main.c conf.c vers.c reloc.c autoload.c
-SRCS+= copy.c devicename.c exec.c
+SRCS+= copy.c devicename.c exec.c bootinfo.c
CFLAGS+= -fno-builtin
CFLAGS+= -I${.CURDIR}
Added: projects/arm64/sys/boot/arm64/efi/bootinfo.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/arm64/sys/boot/arm64/efi/bootinfo.c Mon Mar 31 19:50:40 2014 (r263976)
@@ -0,0 +1,235 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith at freebsd.org>
+ * Copyright (c) 2004, 2006 Marcel Moolenaar
+ * 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 <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "libarm64.h"
+
+UINTN arm64_efi_mapkey;
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a, c) { \
+ uint32_t x = (v); \
+ if (c) \
+ arm64_efi_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c); \
+ if (c) \
+ arm64_efi_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_int64_t)); \
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ arm64_efi_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_int64_t)); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c); \
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ arm64_efi_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_int64_t)); \
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+static vm_offset_t
+bi_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ int c;
+ u_int64_t v;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ v = fp->f_addr;
+ MOD_ADDR(addr, v, c);
+ v = fp->f_size;
+ MOD_SIZE(addr, v, c);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md, c);
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+static int
+bi_load_efi_data(struct preloaded_file *kfp)
+{
+ EFI_MEMORY_DESCRIPTOR *mm;
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_STATUS status;
+ size_t efisz;
+ UINTN mmsz, pages, sz;
+ UINT32 mmver;
+ struct efi_map_header *efihdr;
+
+ efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+
+ /*
+ * Allocate enough pages to hold the bootinfo block and the memory
+ * map EFI will return to us. The memory map has an unknown size,
+ * so we have to determine that first. Note that the AllocatePages
+ * call can itself modify the memory map, so we have to take that
+ * into account as well. The changes to the memory map are caused
+ * by splitting a range of free memory into two (AFAICT), so that
+ * one is marked as being loader data.
+ */
+ sz = 0;
+ BS->GetMemoryMap(&sz, NULL, &arm64_efi_mapkey, &mmsz, &mmver);
+ sz += mmsz;
+ sz = (sz + 0xf) & ~0xf;
+ pages = EFI_SIZE_TO_PAGES(sz + efisz);
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
+ &addr);
+ if (EFI_ERROR(status)) {
+ printf("%s: AllocatePages() returned 0x%lx\n", __func__,
+ (long)status);
+ return (ENOMEM);
+ }
+
+ /*
+ * Read the memory map and stash it after bootinfo. Align the
+ * memory map on a 16-byte boundary (the bootinfo block is page
+ * aligned).
+ */
+ efihdr = (struct efi_map_header *)addr;
+ mm = (void *)((uint8_t *)efihdr + efisz);
+ sz = (EFI_PAGE_SIZE * pages) - efisz;
+ status = BS->GetMemoryMap(&sz, mm, &arm64_efi_mapkey, &mmsz, &mmver);
+ if (EFI_ERROR(status)) {
+ printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+
+ efihdr->memory_size = sz;
+ efihdr->descriptor_size = mmsz;
+ efihdr->descriptor_version = mmver;
+
+ file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, efihdr);
+
+ return (0);
+}
+
+/*
+ * Load the information expected by an arm64 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+ struct preloaded_file *xp, *kfp;
+ uint64_t kernend;
+ vm_offset_t addr, size;
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf64 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+
+ bi_load_efi_data(kfp);
+
+ /* Figure out the size and location of the metadata */
+ *modulep = addr;
+ size = bi_copymodules(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* copy module list and metadata */
+ (void)bi_copymodules(addr);
+
+ return (0);
+}
+
Modified: projects/arm64/sys/boot/arm64/efi/exec.c
==============================================================================
--- projects/arm64/sys/boot/arm64/efi/exec.c Mon Mar 31 19:37:39 2014 (r263975)
+++ projects/arm64/sys/boot/arm64/efi/exec.c Mon Mar 31 19:50:40 2014 (r263976)
@@ -40,11 +40,14 @@ __FBSDID("$FreeBSD$");
#include <efilib.h>
#include "libarm64.h"
-#include <machine/bootinfo.h>
+
+extern UINTN arm64_efi_mapkey;
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
+int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+
static struct file_format arm64_elf = {
elf64_loadfile,
elf64_exec
@@ -58,74 +61,27 @@ struct file_format *file_formats[] = {
static int
elf64_exec(struct preloaded_file *fp)
{
+ vm_offset_t modulep, kernendp;
struct file_metadata *md;
- struct bootinfo *bi;
EFI_STATUS status;
- EFI_MEMORY_DESCRIPTOR *memmap;
EFI_PHYSICAL_ADDRESS addr;
- UINTN descsz, memmapsz, mapkey, pages;
- UINT32 descver;
Elf_Ehdr *ehdr;
- void (*entry)(void *);
+ int err;
+ void (*entry)(vm_offset_t);
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE);
ehdr = (Elf_Ehdr *)&(md->md_data);
-
entry = arm64_efi_translate(ehdr->e_entry);
- memmapsz = 0;
- status = BS->GetMemoryMap(&memmapsz, NULL, &mapkey, &descsz, &descver);
- if (EFI_ERROR(status) && status != EFI_BUFFER_TOO_SMALL) {
- printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
- (long)status);
- return (EINVAL);
- }
-
- memmapsz = roundup2(memmapsz, 16);
- pages = EFI_SIZE_TO_PAGES(memmapsz + sizeof(*bi));
- status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
- &addr);
- if (EFI_ERROR(status)) {
- free(memmap);
- printf("%s: AllocatePages() returned 0x%lx\n", __func__,
- (long)status);
- return (ENOMEM);
- }
-
- memmap = (void *)(addr + sizeof(*bi));
- status = BS->GetMemoryMap(&memmapsz, memmap, &mapkey, &descsz,
- &descver);
- if (EFI_ERROR(status)) {
- free(memmap);
- printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
- (long)status);
- return (EINVAL);
- }
-
- bi = (void *)addr;
+ err = bi_load(fp->f_args, &modulep, &kernendp);
+ if (err != 0)
+ return (err);
- bi->bi_magic = BOOTINFO_MAGIC;
- bi->bi_version = BOOTINFO_VERSION;
-
- bi->bi_memmap = (uint64_t)memmap;
- bi->bi_memmap_size = memmapsz;
- bi->bi_memdesc_size = descsz;
- bi->bi_memdesc_version = descver;
-
-#if 0
- /* Find a location for the bootinfo after the last module */
- addr = 0;
- for (md = file_findfile(NULL, NULL); md != NULL; md = md->f_next) {
- if (addr < (md->f_addr + md->f_size))
- addr = md->f_addr + md->f_size;
- }
- addr = roundup2(addr, 16);
- arm64_copyin(&bi, addr, sizeof(bi));
-#endif
+ printf("%llx %llx\n", modulep, kernendp);
- status = BS->ExitBootServices(IH, mapkey);
+ status = BS->ExitBootServices(IH, arm64_efi_mapkey);
if (EFI_ERROR(status)) {
printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
(long)status);
@@ -133,7 +89,7 @@ elf64_exec(struct preloaded_file *fp)
}
/* TODO: Pass the required metadata to the kernel */
- (*entry)(bi);
+ (*entry)(modulep);
panic("exec returned");
}
More information about the svn-src-projects
mailing list