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
@ -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…
x
Reference in New Issue
Block a user