diff options
author | royger <royger@FreeBSD.org> | 2017-05-09 09:53:18 +0000 |
---|---|---|
committer | royger <royger@FreeBSD.org> | 2017-05-09 09:53:18 +0000 |
commit | f20a7aeef0f6912c9d47d5ceb488ff7b745c5369 (patch) | |
tree | c81475e713b208d6570fe587744b6141305847c8 /sys/boot/i386 | |
parent | e776c54686e61cb89b170e3ec621f197edd73050 (diff) | |
download | FreeBSD-src-f20a7aeef0f6912c9d47d5ceb488ff7b745c5369.zip FreeBSD-src-f20a7aeef0f6912c9d47d5ceb488ff7b745c5369.tar.gz |
MFC r316754: loader/multiboot: fix multiboot loading
Sponsored by: Citrix Systems R&D
Diffstat (limited to 'sys/boot/i386')
-rw-r--r-- | sys/boot/i386/libi386/multiboot.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/sys/boot/i386/libi386/multiboot.c b/sys/boot/i386/libi386/multiboot.c index 00e36f2..9aac640 100644 --- a/sys/boot/i386/libi386/multiboot.c +++ b/sys/boot/i386/libi386/multiboot.c @@ -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. |