Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/stand efiboot: Kernel modules are loaded in pr...



details:   https://anonhg.NetBSD.org/src/rev/5c63860d0ac7
branches:  trunk
changeset: 822300:5c63860d0ac7
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Sun Mar 12 05:33:48 2017 +0000

description:
efiboot: Kernel modules are loaded in pre-allocated memory.

diffstat:

 sys/arch/i386/stand/efiboot/boot.c |   35 ++++++-
 sys/arch/i386/stand/lib/exec.c     |  157 ++++++++++++++++++++++++------------
 sys/arch/i386/stand/lib/libi386.h  |    3 +-
 3 files changed, 133 insertions(+), 62 deletions(-)

diffs (truncated from 371 to 300 lines):

diff -r 5730da1ce310 -r 5c63860d0ac7 sys/arch/i386/stand/efiboot/boot.c
--- a/sys/arch/i386/stand/efiboot/boot.c        Sun Mar 12 04:19:29 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/boot.c        Sun Mar 12 05:33:48 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: boot.c,v 1.3 2017/03/03 09:29:57 nonaka Exp $  */
+/*     $NetBSD: boot.c,v 1.4 2017/03/12 05:33:48 nonaka Exp $  */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -31,10 +31,9 @@
 #include <sys/bootblock.h>
 #include <sys/boot_flag.h>
 
-#include <lib/libsa/bootcfg.h>
-
-#include <bootmod.h>
-#include <bootmenu.h>
+#include "bootcfg.h"
+#include "bootmod.h"
+#include "bootmenu.h"
 #include "devopen.h"
 
 int errno;
@@ -207,16 +206,40 @@
 static void
 bootit(const char *filename, int howto)
 {
+       EFI_STATUS status;
+       EFI_PHYSICAL_ADDRESS bouncebuf;
+       UINTN npages;
+       u_long allocsz;
 
        if (howto & AB_VERBOSE)
                printf("booting %s (howto 0x%x)\n", sprint_bootsel(filename),
                    howto);
 
-       if (exec_netbsd(filename, 0, howto, 0, efi_cleanup) < 0)
+       if (count_netbsd(filename, &allocsz) < 0) {
+               printf("boot: %s: %s\n", sprint_bootsel(filename),
+                      strerror(errno));
+               return;
+       }
+
+       bouncebuf = EFI_ALLOCATE_MAX_ADDRESS;
+       npages = EFI_SIZE_TO_PAGES(allocsz);
+       status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress,
+           EfiLoaderData, npages, &bouncebuf);
+       if (EFI_ERROR(status)) {
+               printf("boot: %s: %s\n", sprint_bootsel(filename),
+                      strerror(ENOMEM));
+               return;
+       }
+
+       efi_loadaddr = bouncebuf;
+       if (exec_netbsd(filename, bouncebuf, howto, 0, efi_cleanup) < 0)
                printf("boot: %s: %s\n", sprint_bootsel(filename),
                       strerror(errno));
        else
                printf("boot returned\n");
+
+       (void) uefi_call_wrapper(BS->FreePages, 2, bouncebuf, npages);
+       efi_loadaddr = 0;
 }
 
 void
diff -r 5730da1ce310 -r 5c63860d0ac7 sys/arch/i386/stand/lib/exec.c
--- a/sys/arch/i386/stand/lib/exec.c    Sun Mar 12 04:19:29 2017 +0000
+++ b/sys/arch/i386/stand/lib/exec.c    Sun Mar 12 05:33:48 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec.c,v 1.66 2017/02/23 12:14:53 nonaka Exp $  */
+/*     $NetBSD: exec.c,v 1.67 2017/03/12 05:33:48 nonaka Exp $  */
 
 /*
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -151,6 +151,11 @@
 
 static void    userconf_init(void);
 
+static void    extract_device(const char *, char *, size_t);
+static void    module_base_path(char *, size_t);
+static int     module_open(boot_module_t *, int, const char *, const char *,
+                   bool);
+
 void
 framebuffer_configure(struct btinfo_framebuffer *fb)
 {
@@ -196,6 +201,10 @@
        while (*name == ' ' || *name == '\t')
                ++name;
 
+       for (bm = boot_modules; bm != NULL; bm = bm->bm_next)
+               if (bm->bm_type == type && strcmp(bm->bm_path, name) == 0)
+                       return;
+
        bm = alloc(sizeof(boot_module_t));
        len = strlen(name) + 1;
        str = alloc(len);
@@ -299,30 +308,6 @@
                        return ENOMEM;
        }
 #endif
-#ifdef EFIBOOT
-       {
-               EFI_STATUS status;
-               EFI_PHYSICAL_ADDRESS addr;
-               UINTN kernsize;
-
-               marks[MARK_START] = loadaddr;
-               if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1)
-                       return EIO;
-               close(fd);
-
-               /* Allocate temporary arena. */
-               addr = EFI_ALLOCATE_MAX_ADDRESS;
-               kernsize = marks[MARK_END] - loadaddr;
-               kernsize = EFI_SIZE_TO_PAGES(kernsize);
-               status = uefi_call_wrapper(BS->AllocatePages, 4,
-                   AllocateMaxAddress, EfiLoaderData, kernsize, &addr);
-               if (EFI_ERROR(status))
-                       return ENOMEM;
-               efi_loadaddr = loadaddr = addr;
-
-               memset(marks, 0, sizeof(marks[0]) * MARK_MAX);
-       }
-#endif
        marks[MARK_START] = loadaddr;
        if ((fd = loadfile(file, marks,
            LOAD_KERNEL & ~(floppy ? LOAD_BACKWARDS : 0))) == -1)
@@ -360,15 +345,6 @@
                ppbcopy(loadaddr, origaddr, marks[MARK_END]);
        }
 #endif
-#ifdef EFIBOOT
-       marks[MARK_START] -= loadaddr;
-       marks[MARK_ENTRY] -= loadaddr;
-       marks[MARK_DATA] -= loadaddr;
-       /* MARK_NSYM */
-       marks[MARK_SYM] -= loadaddr;
-       marks[MARK_END] -= loadaddr;
-       /* Copy the kernel to original load address later. */
-#endif
        marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) &
            (-sizeof(int));
        image_end = marks[MARK_END];
@@ -410,6 +386,15 @@
                errno = error;
                goto out;
        }
+#ifdef EFIBOOT
+       /* adjust to the real load address */
+       marks[MARK_START] -= efi_loadaddr;
+       marks[MARK_ENTRY] -= efi_loadaddr;
+       marks[MARK_DATA] -= efi_loadaddr;
+       /* MARK_NSYM */
+       marks[MARK_SYM] -= efi_loadaddr;
+       marks[MARK_END] -= efi_loadaddr;
+#endif
 
        boot_argv[0] = boothowto;
        boot_argv[1] = 0;
@@ -422,6 +407,14 @@
        if (boot_modules_enabled) {
                module_init(file);
                if (btinfo_modulelist) {
+#ifdef EFIBOOT
+                       /* convert module loaded address to paddr */
+                       struct bi_modulelist_entry *bim;
+                       bim = (void *)(btinfo_modulelist + 1);
+                       for (i = 0; i < btinfo_modulelist->num; i++, bim++)
+                               bim->base -= efi_loadaddr;
+                       btinfo_modulelist->endpa -= efi_loadaddr;
+#endif
                        BI_ADD(btinfo_modulelist, BTINFO_MODULELIST,
                            btinfo_modulelist_size);
                }
@@ -459,7 +452,7 @@
        }
 
        efi_kernel_start = marks[MARK_START];
-       efi_kernel_size = marks[MARK_END] - efi_kernel_start;
+       efi_kernel_size = image_end - efi_loadaddr - efi_kernel_start;
 #endif
        startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
            x86_trunc_page(basemem * 1024));
@@ -471,6 +464,53 @@
        return -1;
 }
 
+int
+count_netbsd(const char *file, u_long *rsz)
+{
+       u_long marks[MARK_MAX];
+       char kdev[64];
+       char base_path[64];
+       struct stat st;
+       boot_module_t *bm;
+       u_long sz;
+       int err, fd;
+
+       memset(marks, 0, sizeof(marks));
+       if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1)
+               return -1;
+       close(fd);
+       marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) &
+           (-sizeof(int));
+       sz = marks[MARK_END];
+
+       /* The modules must be allocated after the kernel */
+       if (boot_modules_enabled) {
+               extract_device(file, kdev, sizeof(kdev));
+               module_base_path(base_path, sizeof(base_path));
+
+               /* If the root fs type is unusual, load its module. */
+               if (fsmod != NULL)
+                       module_add(__UNCONST(fsmod));
+
+               for (bm = boot_modules; bm; bm = bm->bm_next) {
+                       fd = module_open(bm, 0, kdev, base_path, false);
+                       if (fd == -1)
+                               continue;
+                       sz = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+                       err = fstat(fd, &st);
+                       if (err == -1 || st.st_size == -1) {
+                               close(fd);
+                               continue;
+                       }
+                       sz += st.st_size;
+                       close(fd);
+               }
+       }
+
+       *rsz = sz;
+       return 0;
+}
+
 static void
 extract_device(const char *path, char *buf, size_t buflen)
 {
@@ -486,7 +526,7 @@
 }
 
 static const char *
-module_path(boot_module_t *bm, const char *kdev)
+module_path(boot_module_t *bm, const char *kdev, const char *base_path)
 {
        static char buf[256];
        char name_buf[256], dev_buf[64];
@@ -510,7 +550,7 @@
                        p++;
                        extract_device(name, dev_buf, sizeof(dev_buf));
                        snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
-                           dev_buf, module_base, p, p);
+                           dev_buf, base_path, p, p);
                }
        } else {
                /* device not specified; load from kernel device if known */
@@ -518,20 +558,21 @@
                        snprintf(buf, sizeof(buf), "%s%s", kdev, name);
                else
                        snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
-                           kdev, module_base, name, name);
+                           kdev, base_path, name, name);
        }
 
        return buf;
 }
 
 static int
-module_open(boot_module_t *bm, int mode, const char *kdev, bool doload)
+module_open(boot_module_t *bm, int mode, const char *kdev,
+    const char *base_path, bool doload)
 {
        int fd;
        const char *path;
 
        /* check the expanded path first */
-       path = module_path(bm, kdev);
+       path = module_path(bm, kdev, base_path);
        fd = open(path, mode);
        if (fd != -1) {
                if ((howto & AB_SILENT) == 0 && doload)
@@ -552,19 +593,9 @@
 }
 
 static void
-module_init(const char *kernel_path)
+module_base_path(char *buf, size_t bufsize)
 {
-       struct bi_modulelist_entry *bi;
-       struct stat st;
        const char *machine;
-       char kdev[64];
-       char *buf;
-       boot_module_t *bm;
-       ssize_t len;
-       off_t off;
-       int err, fd, nfail = 0;
-
-       extract_device(kernel_path, kdev, sizeof(kdev));
 



Home | Main Index | Thread Index | Old Index