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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 H. Peter Anvin
				H. Peter Anvin