Commit 37ba7ab5 authored by H. Peter Anvin's avatar H. Peter Anvin

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: default avatarH. Peter Anvin <hpa@zytor.com>
parent 99aa4559
...@@ -69,8 +69,11 @@ ENTRY(startup_32) ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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 ...@@ -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 ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment