aboutsummaryrefslogtreecommitdiff
path: root/sys/i386
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2022-09-16 15:09:26 +0000
committerWarner Losh <imp@FreeBSD.org>2022-09-16 15:18:57 +0000
commit4134f677eb39ace176de2967c6ed449d6dfff732 (patch)
treebc21939ec24a2900e255964e3a97676ac97ec1c3 /sys/i386
parent59b1d074280d6b060cca6f502a2b33933614cce0 (diff)
downloadsrc-4134f677eb39ace176de2967c6ed449d6dfff732.tar.gz
src-4134f677eb39ace176de2967c6ed449d6dfff732.zip
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
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/genassym.c1
-rw-r--r--sys/i386/i386/locore.s34
-rw-r--r--sys/i386/include/bootinfo.h15
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