svn commit: r318019 - in stable/11/sys/boot: common i386/libi386
Roger Pau Monné
royger at FreeBSD.org
Tue May 9 09:53:20 UTC 2017
Author: royger
Date: Tue May 9 09:53:18 2017
New Revision: 318019
URL: https://svnweb.freebsd.org/changeset/base/318019
Log:
MFC r316754: loader/multiboot: fix multiboot loading
Sponsored by: Citrix Systems R&D
Modified:
stable/11/sys/boot/common/bootstrap.h
stable/11/sys/boot/common/module.c
stable/11/sys/boot/i386/libi386/multiboot.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/boot/common/bootstrap.h
==============================================================================
--- stable/11/sys/boot/common/bootstrap.h Tue May 9 09:03:04 2017 (r318018)
+++ stable/11/sys/boot/common/bootstrap.h Tue May 9 09:53:18 2017 (r318019)
@@ -229,6 +229,7 @@ void file_discard(struct preloaded_file
void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
int file_addmodule(struct preloaded_file *fp, char *modname, int version,
struct kernel_module **newmp);
+void file_removemetadata(struct preloaded_file *fp);
/* MI module loaders */
#ifdef __elfN
Modified: stable/11/sys/boot/common/module.c
==============================================================================
--- stable/11/sys/boot/common/module.c Tue May 9 09:03:04 2017 (r318018)
+++ stable/11/sys/boot/common/module.c Tue May 9 09:53:18 2017 (r318019)
@@ -642,6 +642,22 @@ file_findmetadata(struct preloaded_file
return(md);
}
+/*
+ * Remove all metadata from the file.
+ */
+void
+file_removemetadata(struct preloaded_file *fp)
+{
+ struct file_metadata *md, *next;
+
+ for (md = fp->f_metadata; md != NULL; md = next)
+ {
+ next = md->md_next;
+ free(md);
+ }
+ fp->f_metadata = NULL;
+}
+
struct file_metadata *
metadata_next(struct file_metadata *md, int type)
{
Modified: stable/11/sys/boot/i386/libi386/multiboot.c
==============================================================================
--- stable/11/sys/boot/i386/libi386/multiboot.c Tue May 9 09:03:04 2017 (r318018)
+++ stable/11/sys/boot/i386/libi386/multiboot.c Tue May 9 09:53:18 2017 (r318019)
@@ -267,7 +267,39 @@ multiboot_exec(struct preloaded_file *fp
* information is placed at the start of the second module and
* the original modulep value is saved together with the other
* metadata, so we can relocate everything.
+ *
+ * Native layout:
+ * fp->f_addr + fp->f_size
+ * +---------+----------------+------------+
+ * | | | |
+ * | Kernel | Modules | Metadata |
+ * | | | |
+ * +---------+----------------+------------+
+ * fp->f_addr modulep kernend
+ *
+ * Xen layout:
+ *
+ * Initial:
+ * fp->f_addr + fp->f_size
+ * +---------+----------+----------------+------------+
+ * | | | | |
+ * | Kernel | Reserved | Modules | Metadata |
+ * | | | | dry run |
+ * +---------+----------+----------------+------------+
+ * fp->f_addr
+ *
+ * After metadata polacement (ie: final):
+ * fp->f_addr + fp->f_size
+ * +-----------+---------+----------+----------------+
+ * | | | | |
+ * | Kernel | Free | Metadata | Modules |
+ * | | | | |
+ * +-----------+---------+----------+----------------+
+ * fp->f_addr modulep kernend
+ * \__________/ \__________________________/
+ * Multiboot module 0 Multiboot module 1
*/
+
fp = file_findfile(NULL, "elf kernel");
if (fp == NULL) {
printf("No FreeBSD kernel provided, aborting\n");
@@ -275,6 +307,13 @@ multiboot_exec(struct preloaded_file *fp
goto error;
}
+ if (fp->f_metadata != NULL) {
+ printf("FreeBSD kernel already contains metadata, aborting\n");
+ error = EINVAL;
+ goto error;
+ }
+
+
mb_mod = malloc(sizeof(struct multiboot_mod_list) * NUM_MODULES);
if (mb_mod == NULL) {
error = ENOMEM;
@@ -312,6 +351,9 @@ multiboot_exec(struct preloaded_file *fp
goto error;
}
+ /* Clean the metadata added to the kernel in the bi_load64 dry run */
+ file_removemetadata(fp);
+
/*
* This is the position where the second multiboot module
* will be placed.
More information about the svn-src-stable-11
mailing list