mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	x86, boot: make kernel_alignment adjustable; new bzImage fields
Make the kernel_alignment field adjustable; this allows us to set it to a large value (intended to be 16 MB to avoid ZONE_DMA contention, memory holes and other weirdness) while a smart bootloader can still force a loading at a lesser alignment if absolutely necessary. Also export pref_address (preferred loading address, corresponding to the link-time address) and init_size, the total amount of linear memory the kernel will require during initialization. [ Impact: allows better kernel placement, gives bootloader more info ] Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
		
							parent
							
								
									99aa45595f
								
							
						
					
					
						commit
						37ba7ab5e3
					
				
					 6 changed files with 45 additions and 8 deletions
				
			
		| 
						 | 
					@ -69,8 +69,11 @@ ENTRY(startup_32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_RELOCATABLE
 | 
					#ifdef CONFIG_RELOCATABLE
 | 
				
			||||||
	movl	%ebp, %ebx
 | 
						movl	%ebp, %ebx
 | 
				
			||||||
	addl    $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
 | 
						movl	BP_kernel_alignment(%esi), %eax
 | 
				
			||||||
	andl    $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
 | 
						decl	%eax
 | 
				
			||||||
 | 
						addl    %eax, %ebx
 | 
				
			||||||
 | 
						notl	%eax
 | 
				
			||||||
 | 
						andl    %eax, %ebx
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	movl	$LOAD_PHYSICAL_ADDR, %ebx
 | 
						movl	$LOAD_PHYSICAL_ADDR, %ebx
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,8 +84,11 @@ ENTRY(startup_32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_RELOCATABLE
 | 
					#ifdef CONFIG_RELOCATABLE
 | 
				
			||||||
	movl	%ebp, %ebx
 | 
						movl	%ebp, %ebx
 | 
				
			||||||
	addl	$(PMD_PAGE_SIZE -1), %ebx
 | 
						movl	BP_kernel_alignment(%esi), %eax
 | 
				
			||||||
	andl	$PMD_PAGE_MASK, %ebx
 | 
						decl	%eax
 | 
				
			||||||
 | 
						addl	%eax, %ebx
 | 
				
			||||||
 | 
						notl	%eax
 | 
				
			||||||
 | 
						andl	%eax, %ebx
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	movl	$LOAD_PHYSICAL_ADDR, %ebx
 | 
						movl	$LOAD_PHYSICAL_ADDR, %ebx
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -224,8 +227,11 @@ ENTRY(startup_64)
 | 
				
			||||||
	/* Start with the delta to where the kernel will run at. */
 | 
						/* Start with the delta to where the kernel will run at. */
 | 
				
			||||||
#ifdef CONFIG_RELOCATABLE
 | 
					#ifdef CONFIG_RELOCATABLE
 | 
				
			||||||
	leaq	startup_32(%rip) /* - $startup_32 */, %rbp
 | 
						leaq	startup_32(%rip) /* - $startup_32 */, %rbp
 | 
				
			||||||
	addq	$(PMD_PAGE_SIZE - 1), %rbp
 | 
						movl	BP_kernel_alignment(%rsi), %eax
 | 
				
			||||||
	andq	$PMD_PAGE_MASK, %rbp
 | 
						decl	%eax
 | 
				
			||||||
 | 
						addq	%rax, %rbp
 | 
				
			||||||
 | 
						notq	%rax
 | 
				
			||||||
 | 
						andq	%rax, %rbp
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	movq	$LOAD_PHYSICAL_ADDR, %rbp
 | 
						movq	$LOAD_PHYSICAL_ADDR, %rbp
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,7 +116,7 @@ _start:
 | 
				
			||||||
	# Part 2 of the header, from the old setup.S
 | 
						# Part 2 of the header, from the old setup.S
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		.ascii	"HdrS"		# header signature
 | 
							.ascii	"HdrS"		# header signature
 | 
				
			||||||
		.word	0x0209		# header version number (>= 0x0105)
 | 
							.word	0x020a		# header version number (>= 0x0105)
 | 
				
			||||||
					# or else old loadlin-1.5 will fail)
 | 
										# or else old loadlin-1.5 will fail)
 | 
				
			||||||
		.globl realmode_swtch
 | 
							.globl realmode_swtch
 | 
				
			||||||
realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
 | 
					realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
 | 
				
			||||||
| 
						 | 
					@ -201,7 +201,7 @@ relocatable_kernel:    .byte 1
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
relocatable_kernel:    .byte 0
 | 
					relocatable_kernel:    .byte 0
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
pad2:			.byte 0
 | 
					min_alignment:		.byte MIN_KERNEL_ALIGN_LG2	# minimum alignment
 | 
				
			||||||
pad3:			.word 0
 | 
					pad3:			.word 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
 | 
					cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
 | 
				
			||||||
| 
						 | 
					@ -220,6 +220,17 @@ setup_data:		.quad 0			# 64-bit physical pointer to
 | 
				
			||||||
						# single linked list of
 | 
											# single linked list of
 | 
				
			||||||
						# struct setup_data
 | 
											# struct setup_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pref_address:		.quad LOAD_PHYSICAL_ADDR	# preferred load addr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ZO_INIT_SIZE	(ZO__end - ZO_startup_32 + ZO_extract_offset)
 | 
				
			||||||
 | 
					#define VO_INIT_SIZE	(VO__end - VO__text)
 | 
				
			||||||
 | 
					#if ZO_INIT_SIZE > VO_INIT_SIZE
 | 
				
			||||||
 | 
					#define INIT_SIZE ZO_INIT_SIZE
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define INIT_SIZE VO_INIT_SIZE
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					init_size:		.long INIT_SIZE		# kernel initialization size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# End of setup header #####################################################
 | 
					# End of setup header #####################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.section ".inittext", "ax"
 | 
						.section ".inittext", "ax"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,11 +8,26 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __KERNEL__
 | 
					#ifdef __KERNEL__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <asm/page_types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Physical address where kernel should be loaded. */
 | 
					/* Physical address where kernel should be loaded. */
 | 
				
			||||||
#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
 | 
					#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
 | 
				
			||||||
				+ (CONFIG_PHYSICAL_ALIGN - 1)) \
 | 
									+ (CONFIG_PHYSICAL_ALIGN - 1)) \
 | 
				
			||||||
				& ~(CONFIG_PHYSICAL_ALIGN - 1))
 | 
									& ~(CONFIG_PHYSICAL_ALIGN - 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Minimum kernel alignment, as a power of two */
 | 
				
			||||||
 | 
					#ifdef CONFIG_x86_64
 | 
				
			||||||
 | 
					#define MIN_KERNEL_ALIGN_LG2	PMD_SHIFT
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define MIN_KERNEL_ALIGN_LG2	(PAGE_SHIFT+1)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define MIN_KERNEL_ALIGN	(_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN-1)) || \
 | 
				
			||||||
 | 
						(CONFIG_PHYSICAL_ALIGN < (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2))
 | 
				
			||||||
 | 
					#error "Invalid value for CONFIG_PHYSICAL_ALIGN"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_KERNEL_BZIP2
 | 
					#ifdef CONFIG_KERNEL_BZIP2
 | 
				
			||||||
#define BOOT_HEAP_SIZE             0x400000
 | 
					#define BOOT_HEAP_SIZE             0x400000
 | 
				
			||||||
#else /* !CONFIG_KERNEL_BZIP2 */
 | 
					#else /* !CONFIG_KERNEL_BZIP2 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -146,4 +146,5 @@ void foo(void)
 | 
				
			||||||
	OFFSET(BP_loadflags, boot_params, hdr.loadflags);
 | 
						OFFSET(BP_loadflags, boot_params, hdr.loadflags);
 | 
				
			||||||
	OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
 | 
						OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
 | 
				
			||||||
	OFFSET(BP_version, boot_params, hdr.version);
 | 
						OFFSET(BP_version, boot_params, hdr.version);
 | 
				
			||||||
 | 
						OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,6 +125,7 @@ int main(void)
 | 
				
			||||||
	OFFSET(BP_loadflags, boot_params, hdr.loadflags);
 | 
						OFFSET(BP_loadflags, boot_params, hdr.loadflags);
 | 
				
			||||||
	OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
 | 
						OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
 | 
				
			||||||
	OFFSET(BP_version, boot_params, hdr.version);
 | 
						OFFSET(BP_version, boot_params, hdr.version);
 | 
				
			||||||
 | 
						OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BLANK();
 | 
						BLANK();
 | 
				
			||||||
	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
 | 
						DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue