Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 May 2017 09:53:18 +0000 (UTC)
From:      =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= <royger@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r318019 - in stable/11/sys/boot: common i386/libi386
Message-ID:  <201705090953.v499rI1t068754@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705090953.v499rI1t068754>