Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5031296c authored by H. Peter Anvin's avatar H. Peter Anvin
Browse files

x86: add extension fields for bootloader type and version



A long ago, in days of yore, it all began with a god named Thor.
There were vikings and boats and some plans for a Linux kernel
header.  Unfortunately, a single 8-bit field was used for bootloader
type and version.  This has generally worked without *too* much pain,
but we're getting close to flat running out of ID fields.

Add extension fields for both type and version.  The type will be
extended if it the old field is 0xE; the version is a simple MSB
extension.

Keep /proc/sys/kernel/bootloader_type containing
(type << 4) + (ver & 0xf) for backwards compatiblity, but also add
/proc/sys/kernel/bootloader_version which contains the full version
number.

[ Impact: new feature to support more bootloaders ]

Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
parent fe83fcc0
Loading
Loading
Loading
Loading
+52 −7
Original line number Diff line number Diff line
@@ -50,10 +50,9 @@ Protocol 2.08: (Kernel 2.6.26) Added crc32 checksum and ELF format
Protocol 2.09:	(Kernel 2.6.26) Added a field of 64-bit physical
		pointer to single linked list of struct	setup_data.

Protocol 2.10:	(Kernel 2.6.31) A protocol for relaxed alignment
Protocol 2.10:	(Kernel 2.6.31) Added a protocol for relaxed alignment
		beyond the kernel_alignment added, new init_size and
		pref_address fields.

		pref_address fields.  Added extended boot loader IDs.

**** MEMORY LAYOUT

@@ -173,7 +172,8 @@ Offset Proto Name Meaning
021C/4	2.00+	ramdisk_size	initrd size (set by boot loader)
0220/4	2.00+	bootsect_kludge	DO NOT USE - for bootsect.S use only
0224/2	2.01+	heap_end_ptr	Free memory after setup end
0226/2	N/A	pad1		Unused
0226/1	2.02+(3 ext_loader_ver	Extended boot loader version
0227/1	2.02+(3	ext_loader_type	Extended boot loader ID
0228/4	2.02+	cmd_line_ptr	32-bit pointer to the kernel command line
022C/4	2.03+	ramdisk_max	Highest legal initrd address
0230/4	2.05+	kernel_alignment Physical addr alignment required for kernel
@@ -197,6 +197,8 @@ Offset Proto Name Meaning
    field are unusable, which means the size of a bzImage kernel
    cannot be determined.

(3) Ignored, but safe to set, for boot protocols 2.02-2.09.

If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
the boot protocol version is "old".  Loading an old kernel, the
following parameters should be assumed:
@@ -350,18 +352,32 @@ Protocol: 2.00+
  0xTV here, where T is an identifier for the boot loader and V is
  a version number.  Otherwise, enter 0xFF here.

  For boot loader IDs above T = 0xD, write T = 0xE to this field and
  write the extended ID minus 0x10 to the ext_loader_type field.
  Similarly, the ext_loader_ver field can be used to provide more than
  four bits for the bootloader version.

  For example, for T = 0x15, V = 0x234, write:

  type_of_loader  <- 0xE4
  ext_loader_type <- 0x05
  ext_loader_ver  <- 0x23

  Assigned boot loader ids:
	0  LILO			(0x00 reserved for pre-2.00 bootloader)
	1  Loadlin
	2  bootsect-loader	(0x20, all other values reserved)
	3  SYSLINUX
	4  EtherBoot
	3  Syslinux
	4  Etherboot/gPXE
	5  ELILO
	7  GRUB
	8  U-BOOT
	8  U-Boot
	9  Xen
	A  Gujin
	B  Qemu
	C  Arcturus Networks uCbootloader
	E  Extended		(see ext_loader_type)
	F  Special		(0xFF = undefined)

  Please contact <hpa@zytor.com> if you need a bootloader ID
  value assigned.
@@ -460,6 +476,35 @@ Protocol: 2.01+
  Set this field to the offset (from the beginning of the real-mode
  code) of the end of the setup stack/heap, minus 0x0200.

Field name:	ext_loader_ver
Type:		write (optional)
Offset/size:	0x226/1
Protocol:	2.02+

  This field is used as an extension of the version number in the
  type_of_loader field.  The total version number is considered to be
  (type_of_loader & 0x0f) + (ext_loader_ver << 4).

  The use of this field is boot loader specific.  If not written, it
  is zero.

  Kernels prior to 2.6.31 did not recognize this field, but it is safe
  to write for protocol version 2.02 or higher.

Field name:	ext_loader_type
Type:		write (obligatory if (type_of_loader & 0xf0) == 0xe0)
Offset/size:	0x227/1
Protocol:	2.02+

  This field is used as an extension of the type number in
  type_of_loader field.  If the type in type_of_loader is 0xE, then
  the actual type is (ext_loader_type + 0x10).

  This field is ignored if the type in type_of_loader is not 0xE.

  Kernels prior to 2.6.31 did not recognize this field, but it is safe
  to write for protocol version 2.02 or higher.

Field name:	cmd_line_ptr
Type:		write (obligatory)
Offset/size:	0x228/4
+5 −1
Original line number Diff line number Diff line
@@ -169,7 +169,11 @@ heap_end_ptr: .word _end+STACK_SIZE-512
					# end of setup code can be used by setup
					# for local heap purposes.

pad1:		.word	0
ext_loader_ver:
		.byte	0		# Extended boot loader version
ext_loader_type:
		.byte	0		# Extended boot loader type

cmd_line_ptr:	.long	0		# (Header version 0x0202 or later)
					# If nonzero, a 32-bit pointer
					# to the kernel command line.
+2 −1
Original line number Diff line number Diff line
@@ -50,7 +50,8 @@ struct setup_header {
	__u32	ramdisk_size;
	__u32	bootsect_kludge;
	__u16	heap_end_ptr;
	__u16	_pad1;
	__u8	ext_loader_ver;
	__u8	ext_loader_type;
	__u32	cmd_line_ptr;
	__u32	initrd_addr_max;
	__u32	kernel_alignment;
+1 −0
Original line number Diff line number Diff line
@@ -814,6 +814,7 @@ extern unsigned int BIOS_revision;

/* Boot loader type from the setup header: */
extern int			bootloader_type;
extern int			bootloader_version;

extern char			ignore_fpu_irq;

+8 −2
Original line number Diff line number Diff line
@@ -214,8 +214,8 @@ unsigned long mmu_cr4_features;
unsigned long mmu_cr4_features = X86_CR4_PAE;
#endif

/* Boot loader ID as an integer, for the benefit of proc_dointvec */
int bootloader_type;
/* Boot loader ID and version as integers, for the benefit of proc_dointvec */
int bootloader_type, bootloader_version;

/*
 * Setup options
@@ -706,6 +706,12 @@ void __init setup_arch(char **cmdline_p)
#endif
	saved_video_mode = boot_params.hdr.vid_mode;
	bootloader_type = boot_params.hdr.type_of_loader;
	if ((bootloader_type >> 4) == 0xe) {
		bootloader_type &= 0xf;
		bootloader_type |= (boot_params.hdr.ext_loader_type+0x10) << 4;
	}
	bootloader_version  = bootloader_type & 0xf;
	bootloader_version |= boot_params.hdr.ext_loader_ver << 4;

#ifdef CONFIG_BLK_DEV_RAM
	rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK;
Loading