aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-07 19:54:11 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-05-11 20:45:06 -0400
commit5031296c57024a78ddad4edfc993367dbf4abb98 (patch)
tree7506daf7aabf25a5ec567fcd2e644fe22cd91eca
parentfe83fcc0a14dcf71996de5eb84771b2369ba7abc (diff)
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: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--Documentation/x86/boot.txt59
-rw-r--r--arch/x86/boot/header.S6
-rw-r--r--arch/x86/include/asm/bootparam.h3
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/kernel/setup.c10
-rw-r--r--kernel/sysctl.c8
6 files changed, 76 insertions, 11 deletions
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index cf8dfc70a118..8da3a795083f 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -50,10 +50,9 @@ Protocol 2.08: (Kernel 2.6.26) Added crc32 checksum and ELF format
50Protocol 2.09: (Kernel 2.6.26) Added a field of 64-bit physical 50Protocol 2.09: (Kernel 2.6.26) Added a field of 64-bit physical
51 pointer to single linked list of struct setup_data. 51 pointer to single linked list of struct setup_data.
52 52
53Protocol 2.10: (Kernel 2.6.31) A protocol for relaxed alignment 53Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
54 beyond the kernel_alignment added, new init_size and 54 beyond the kernel_alignment added, new init_size and
55 pref_address fields. 55 pref_address fields. Added extended boot loader IDs.
56
57 56
58**** MEMORY LAYOUT 57**** MEMORY LAYOUT
59 58
@@ -173,7 +172,8 @@ Offset Proto Name Meaning
173021C/4 2.00+ ramdisk_size initrd size (set by boot loader) 172021C/4 2.00+ ramdisk_size initrd size (set by boot loader)
1740220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only 1730220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only
1750224/2 2.01+ heap_end_ptr Free memory after setup end 1740224/2 2.01+ heap_end_ptr Free memory after setup end
1760226/2 N/A pad1 Unused 1750226/1 2.02+(3 ext_loader_ver Extended boot loader version
1760227/1 2.02+(3 ext_loader_type Extended boot loader ID
1770228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line 1770228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line
178022C/4 2.03+ ramdisk_max Highest legal initrd address 178022C/4 2.03+ ramdisk_max Highest legal initrd address
1790230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 1790230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
@@ -197,6 +197,8 @@ Offset Proto Name Meaning
197 field are unusable, which means the size of a bzImage kernel 197 field are unusable, which means the size of a bzImage kernel
198 cannot be determined. 198 cannot be determined.
199 199
200(3) Ignored, but safe to set, for boot protocols 2.02-2.09.
201
200If the "HdrS" (0x53726448) magic number is not found at offset 0x202, 202If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
201the boot protocol version is "old". Loading an old kernel, the 203the boot protocol version is "old". Loading an old kernel, the
202following parameters should be assumed: 204following parameters should be assumed:
@@ -350,18 +352,32 @@ Protocol: 2.00+
350 0xTV here, where T is an identifier for the boot loader and V is 352 0xTV here, where T is an identifier for the boot loader and V is
351 a version number. Otherwise, enter 0xFF here. 353 a version number. Otherwise, enter 0xFF here.
352 354
355 For boot loader IDs above T = 0xD, write T = 0xE to this field and
356 write the extended ID minus 0x10 to the ext_loader_type field.
357 Similarly, the ext_loader_ver field can be used to provide more than
358 four bits for the bootloader version.
359
360 For example, for T = 0x15, V = 0x234, write:
361
362 type_of_loader <- 0xE4
363 ext_loader_type <- 0x05
364 ext_loader_ver <- 0x23
365
353 Assigned boot loader ids: 366 Assigned boot loader ids:
354 0 LILO (0x00 reserved for pre-2.00 bootloader) 367 0 LILO (0x00 reserved for pre-2.00 bootloader)
355 1 Loadlin 368 1 Loadlin
356 2 bootsect-loader (0x20, all other values reserved) 369 2 bootsect-loader (0x20, all other values reserved)
357 3 SYSLINUX 370 3 Syslinux
358 4 EtherBoot 371 4 Etherboot/gPXE
359 5 ELILO 372 5 ELILO
360 7 GRUB 373 7 GRUB
361 8 U-BOOT 374 8 U-Boot
362 9 Xen 375 9 Xen
363 A Gujin 376 A Gujin
364 B Qemu 377 B Qemu
378 C Arcturus Networks uCbootloader
379 E Extended (see ext_loader_type)
380 F Special (0xFF = undefined)
365 381
366 Please contact <hpa@zytor.com> if you need a bootloader ID 382 Please contact <hpa@zytor.com> if you need a bootloader ID
367 value assigned. 383 value assigned.
@@ -460,6 +476,35 @@ Protocol: 2.01+
460 Set this field to the offset (from the beginning of the real-mode 476 Set this field to the offset (from the beginning of the real-mode
461 code) of the end of the setup stack/heap, minus 0x0200. 477 code) of the end of the setup stack/heap, minus 0x0200.
462 478
479Field name: ext_loader_ver
480Type: write (optional)
481Offset/size: 0x226/1
482Protocol: 2.02+
483
484 This field is used as an extension of the version number in the
485 type_of_loader field. The total version number is considered to be
486 (type_of_loader & 0x0f) + (ext_loader_ver << 4).
487
488 The use of this field is boot loader specific. If not written, it
489 is zero.
490
491 Kernels prior to 2.6.31 did not recognize this field, but it is safe
492 to write for protocol version 2.02 or higher.
493
494Field name: ext_loader_type
495Type: write (obligatory if (type_of_loader & 0xf0) == 0xe0)
496Offset/size: 0x227/1
497Protocol: 2.02+
498
499 This field is used as an extension of the type number in
500 type_of_loader field. If the type in type_of_loader is 0xE, then
501 the actual type is (ext_loader_type + 0x10).
502
503 This field is ignored if the type in type_of_loader is not 0xE.
504
505 Kernels prior to 2.6.31 did not recognize this field, but it is safe
506 to write for protocol version 2.02 or higher.
507
463Field name: cmd_line_ptr 508Field name: cmd_line_ptr
464Type: write (obligatory) 509Type: write (obligatory)
465Offset/size: 0x228/4 510Offset/size: 0x228/4
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index a0b426978d55..68c3bfbaff24 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -169,7 +169,11 @@ heap_end_ptr: .word _end+STACK_SIZE-512
169 # end of setup code can be used by setup 169 # end of setup code can be used by setup
170 # for local heap purposes. 170 # for local heap purposes.
171 171
172pad1: .word 0 172ext_loader_ver:
173 .byte 0 # Extended boot loader version
174ext_loader_type:
175 .byte 0 # Extended boot loader type
176
173cmd_line_ptr: .long 0 # (Header version 0x0202 or later) 177cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
174 # If nonzero, a 32-bit pointer 178 # If nonzero, a 32-bit pointer
175 # to the kernel command line. 179 # to the kernel command line.
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 433adaebf9b6..1724e8de317c 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -50,7 +50,8 @@ struct setup_header {
50 __u32 ramdisk_size; 50 __u32 ramdisk_size;
51 __u32 bootsect_kludge; 51 __u32 bootsect_kludge;
52 __u16 heap_end_ptr; 52 __u16 heap_end_ptr;
53 __u16 _pad1; 53 __u8 ext_loader_ver;
54 __u8 ext_loader_type;
54 __u32 cmd_line_ptr; 55 __u32 cmd_line_ptr;
55 __u32 initrd_addr_max; 56 __u32 initrd_addr_max;
56 __u32 kernel_alignment; 57 __u32 kernel_alignment;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index fcf4d92e7e04..6384d25121ca 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -814,6 +814,7 @@ extern unsigned int BIOS_revision;
814 814
815/* Boot loader type from the setup header: */ 815/* Boot loader type from the setup header: */
816extern int bootloader_type; 816extern int bootloader_type;
817extern int bootloader_version;
817 818
818extern char ignore_fpu_irq; 819extern char ignore_fpu_irq;
819 820
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index b4158439bf63..2b093451aec9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -214,8 +214,8 @@ unsigned long mmu_cr4_features;
214unsigned long mmu_cr4_features = X86_CR4_PAE; 214unsigned long mmu_cr4_features = X86_CR4_PAE;
215#endif 215#endif
216 216
217/* Boot loader ID as an integer, for the benefit of proc_dointvec */ 217/* Boot loader ID and version as integers, for the benefit of proc_dointvec */
218int bootloader_type; 218int bootloader_type, bootloader_version;
219 219
220/* 220/*
221 * Setup options 221 * Setup options
@@ -706,6 +706,12 @@ void __init setup_arch(char **cmdline_p)
706#endif 706#endif
707 saved_video_mode = boot_params.hdr.vid_mode; 707 saved_video_mode = boot_params.hdr.vid_mode;
708 bootloader_type = boot_params.hdr.type_of_loader; 708 bootloader_type = boot_params.hdr.type_of_loader;
709 if ((bootloader_type >> 4) == 0xe) {
710 bootloader_type &= 0xf;
711 bootloader_type |= (boot_params.hdr.ext_loader_type+0x10) << 4;
712 }
713 bootloader_version = bootloader_type & 0xf;
714 bootloader_version |= boot_params.hdr.ext_loader_ver << 4;
709 715
710#ifdef CONFIG_BLK_DEV_RAM 716#ifdef CONFIG_BLK_DEV_RAM
711 rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK; 717 rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e3d2c7dd59b9..cf91c9317b26 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -729,6 +729,14 @@ static struct ctl_table kern_table[] = {
729 }, 729 },
730 { 730 {
731 .ctl_name = CTL_UNNUMBERED, 731 .ctl_name = CTL_UNNUMBERED,
732 .procname = "bootloader_version",
733 .data = &bootloader_version,
734 .maxlen = sizeof (int),
735 .mode = 0444,
736 .proc_handler = &proc_dointvec,
737 },
738 {
739 .ctl_name = CTL_UNNUMBERED,
732 .procname = "kstack_depth_to_print", 740 .procname = "kstack_depth_to_print",
733 .data = &kstack_depth_to_print, 741 .data = &kstack_depth_to_print,
734 .maxlen = sizeof(int), 742 .maxlen = sizeof(int),