Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Sep 2022 15:54:02 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4134f677eb39 - main - i386: Make boot loader smaller by reducing size of bootinfo
Message-ID:  <202209161554.28GFs2cd086584@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=4134f677eb39ace176de2967c6ed449d6dfff732

commit 4134f677eb39ace176de2967c6ed449d6dfff732
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-09-16 15:09:26 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2022-09-16 15:18:57 +0000

    i386: Make boot loader smaller by reducing size of bootinfo
    
    We don't need the 56 bytes at the end of bootinfo, and never had.  Don't
    copy them from old boot loaders, and don't provide them with new boot
    loaders.
    
    Add comments about what versions of FreeBSD 'old' means in various
    contexts. Add note that old disk loader (from 1.x/2.x) is doomed to
    failure because it doesn't provide metadata that we now require to boot,
    and has been since approximately FreeBSD 7.x. Retain all this
    information to explain why we have 4 arguments that are always 0, even
    though it's ancient history.
    
    This saves 56 bytes in the boot loader.
    
    Sponsored by:           Netflix
    Reviewed by:            phk, rgrimes, kib
    Differential Revision:  https://reviews.freebsd.org/D36550
---
 sys/i386/i386/genassym.c    |  1 -
 sys/i386/i386/locore.s      | 34 ++++++++++++++++------------------
 sys/i386/include/bootinfo.h | 15 +++------------
 3 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index a0520646dc25..c5cf653bbb9e 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -183,7 +183,6 @@ ASSYM(BOOTINFO_SIZE, sizeof(struct bootinfo));
 ASSYM(BI_VERSION, offsetof(struct bootinfo, bi_version));
 ASSYM(BI_KERNELNAME, offsetof(struct bootinfo, bi_kernelname));
 ASSYM(BI_NFS_DISKLESS, offsetof(struct bootinfo, bi_nfs_diskless));
-ASSYM(BI_ENDCOMMON, offsetof(struct bootinfo, bi_endcommon));
 ASSYM(NFSDISKLESS_SIZE, sizeof(struct nfs_diskless));
 ASSYM(BI_SIZE, offsetof(struct bootinfo, bi_size));
 ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab));
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 6dffc4f97fdd..6b0e397d05be 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -178,6 +178,9 @@ recover_bootinfo:
 	 *	 and always passed in as 0]
 	 *	[esym is also known as total in the boot code, and
 	 *	 was never properly supported by the FreeBSD boot code]
+	 *	This code from 1.x/2.x doesn't supply now-required metadata and
+	 *	likely will fail (we test for it to avoid dereferencing stack
+	 *	garbage here).
 	 *
 	 * Old diskless netboot code:
 	 *	(*btext)(0,0,0,0,&nfsdiskless,0,0,0);
@@ -195,9 +198,11 @@ recover_bootinfo:
 	 */
 
 	/*
-	 * The old style disk boot blocks fake a frame on the stack and
-	 * did an lret to get here.  The frame on the stack has a return
-	 * address of 0.
+	 * The old style disk boot blocks fake a frame on the stack and did an
+	 * lret to get here.  The frame on the stack has a return address of 0.
+	 * This style of boot (from 1.x / 2.x) almost certainly won't work,
+	 * since the kernel has required metadata since about 7.x or so and none
+	 * are present.
 	 */
 	cmpl	$0,4(%ebp)
 	je	olddiskboot
@@ -212,9 +217,9 @@ recover_bootinfo:
 	je	newboot
 
 	/*
-	 * Seems we have been loaded by the old diskless boot code, we
-	 * don't stand a chance of running as the diskless structure
-	 * changed considerably between the two, so just halt.
+	 * Seems we have been loaded by the old 1.x/2.x diskless boot code, we
+	 * don't stand a chance of running as the diskless structure changed
+	 * considerably between the two, so just halt.
 	 */
 	 hlt
 
@@ -228,6 +233,8 @@ newboot:
 	movl	BI_VERSION(%ebx),%eax
 	cmpl	$1,%eax			/* We only understand version 1 */
 	je	1f
+	testl   $RB_BOOTINFO,8(%ebp)    /* bi_size (and bootinfo) valid? */
+	jne	1f
 	movl	$1,%eax			/* Return status */
 	leave
 	/*
@@ -258,21 +265,12 @@ newboot:
 2:
 	/*
 	 * Determine the size of the boot loader's copy of the bootinfo
-	 * struct.  This is impossible to do properly because old versions
-	 * of the struct don't contain a size field and there are 2 old
-	 * versions with the same version number.
-	 */
-	movl	$BI_ENDCOMMON,%ecx	/* prepare for sizeless version */
-	testl	$RB_BOOTINFO,8(%ebp)	/* bi_size (and bootinfo) valid? */
-	je	got_bi_size		/* no, sizeless version */
-	movl	BI_SIZE(%ebx),%ecx
-got_bi_size:
-
-	/*
-	 * Copy the common part of the bootinfo struct
+	 * struct. Copy min(our size, loader's size) into our bootinfo.
+	 * Incompatible with really old boot loaders from FreeBSD 1.x and 2.0.
 	 */
 	movl	%ebx,%esi
 	movl	$bootinfo,%edi
+	movl	BI_SIZE(%ebx),%ecx
 	cmpl	$BOOTINFO_SIZE,%ecx
 	jbe	got_common_bi_size
 	movl	$BOOTINFO_SIZE,%ecx
diff --git a/sys/i386/include/bootinfo.h b/sys/i386/include/bootinfo.h
index 5b9473ddcaba..8e50ae71d5e8 100644
--- a/sys/i386/include/bootinfo.h
+++ b/sys/i386/include/bootinfo.h
@@ -44,15 +44,13 @@
 
 /*
  * A zero bootinfo field often means that there is no info available.
- * Flags are used to indicate the validity of fields where zero is a
- * normal value.
+ * Assumes booting with a boot loader from FreeBSD 2.1 or newer and
+ * that bi_size is always valid when bi_version == 1.
  */
 struct bootinfo {
-	u_int32_t	bi_version;
+	u_int32_t	bi_version;		/* Must be 1 */
 	u_int32_t	bi_kernelname;		/* represents a char * */
 	u_int32_t	bi_nfs_diskless;	/* struct nfs_diskless * */
-				/* End of fields that are always present. */
-#define	bi_endcommon	_was_bi_n_bios_used
 	u_int32_t	_was_bi_n_bios_used;
 	u_int32_t	_was_bi_bios_geom[_WAS_N_BIOS_GEOM];
 	u_int32_t	bi_size;
@@ -67,13 +65,6 @@ struct bootinfo {
 	u_int32_t	bi_kernend;		/* end of kernel space */
 	u_int32_t	bi_envp;		/* environment */
 	u_int32_t	bi_modulep;		/* preloaded modules */
-	uint32_t	_was_bi_memdesc_version;/* EFI memory desc version */
-	uint64_t	_was_bi_memdesc_size;	/* sizeof EFI memory desc */
-	uint64_t	_was_bi_memmap;		/* pa of EFI memory map */
-	uint64_t	_was_bi_memmap_size;	/* size of EFI memory map */
-	uint64_t	_was_bi_hcdp;		/* DIG64 HCDP table */
-	uint64_t	_was_bi_fpswa;		/* FPSWA interface */
-	uint64_t	_was_bi_systab;		/* pa of EFI system table */
 };
 
 #ifdef _KERNEL



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