Skip to content

Commit 8eace5b

Browse files
ardbiesheuvelingomolnar
authored andcommitted
x86/boot: Omit compression buffer from PE/COFF image memory footprint
Now that the EFI stub decompresses the kernel and hands over to the decompressed image directly, there is no longer a need to provide a decompression buffer as part of the .BSS allocation of the PE/COFF image. It also means the PE/COFF image can be loaded anywhere in memory, and setting the preferred image base is unnecessary. So drop the handling of this from the header and from the build tool. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20230912090051.4014114-22-ardb@google.com
1 parent 768171d commit 8eace5b

File tree

2 files changed

+8
-48
lines changed

2 files changed

+8
-48
lines changed

arch/x86/boot/header.S

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,10 @@ optional_header:
9090
#endif
9191

9292
extra_header_fields:
93-
# PE specification requires ImageBase to be 64k aligned
94-
.set image_base, (LOAD_PHYSICAL_ADDR + 0xffff) & ~0xffff
9593
#ifdef CONFIG_X86_32
96-
.long image_base # ImageBase
94+
.long 0 # ImageBase
9795
#else
98-
.quad image_base # ImageBase
96+
.quad 0 # ImageBase
9997
#endif
10098
.long 0x20 # SectionAlignment
10199
.long 0x20 # FileAlignment

arch/x86/boot/tools/build.c

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ static unsigned long efi_pe_entry;
6565
static unsigned long efi32_pe_entry;
6666
static unsigned long kernel_info;
6767
static unsigned long startup_64;
68-
static unsigned long _ehead;
6968
static unsigned long _end;
7069

7170
/*----------------------------------------------------------------------*/
@@ -229,35 +228,22 @@ static void update_pecoff_setup_and_reloc(unsigned int size)
229228
#endif
230229
}
231230

232-
static void update_pecoff_text(unsigned int text_start, unsigned int file_sz,
233-
unsigned int init_sz)
231+
static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
234232
{
235233
unsigned int pe_header;
236234
unsigned int text_sz = file_sz - text_start;
237-
unsigned int bss_sz = init_sz - file_sz;
235+
unsigned int bss_sz = _end - text_sz;
238236

239237
pe_header = get_unaligned_le32(&buf[0x3c]);
240238

241-
/*
242-
* The PE/COFF loader may load the image at an address which is
243-
* misaligned with respect to the kernel_alignment field in the setup
244-
* header.
245-
*
246-
* In order to avoid relocating the kernel to correct the misalignment,
247-
* add slack to allow the buffer to be aligned within the declared size
248-
* of the image.
249-
*/
250-
bss_sz += CONFIG_PHYSICAL_ALIGN;
251-
init_sz += CONFIG_PHYSICAL_ALIGN;
252-
253239
/*
254240
* Size of code: Subtract the size of the first sector (512 bytes)
255241
* which includes the header.
256242
*/
257243
put_unaligned_le32(file_sz - 512 + bss_sz, &buf[pe_header + 0x1c]);
258244

259245
/* Size of image */
260-
put_unaligned_le32(init_sz, &buf[pe_header + 0x50]);
246+
put_unaligned_le32(file_sz + bss_sz, &buf[pe_header + 0x50]);
261247

262248
/*
263249
* Address of entry point for PE/COFF executable
@@ -308,8 +294,7 @@ static void efi_stub_entry_update(void)
308294

309295
static inline void update_pecoff_setup_and_reloc(unsigned int size) {}
310296
static inline void update_pecoff_text(unsigned int text_start,
311-
unsigned int file_sz,
312-
unsigned int init_sz) {}
297+
unsigned int file_sz) {}
313298
static inline void efi_stub_defaults(void) {}
314299
static inline void efi_stub_entry_update(void) {}
315300

@@ -360,7 +345,6 @@ static void parse_zoffset(char *fname)
360345
PARSE_ZOFS(p, efi32_pe_entry);
361346
PARSE_ZOFS(p, kernel_info);
362347
PARSE_ZOFS(p, startup_64);
363-
PARSE_ZOFS(p, _ehead);
364348
PARSE_ZOFS(p, _end);
365349

366350
p = strchr(p, '\n');
@@ -371,7 +355,7 @@ static void parse_zoffset(char *fname)
371355

372356
int main(int argc, char ** argv)
373357
{
374-
unsigned int i, sz, setup_sectors, init_sz;
358+
unsigned int i, sz, setup_sectors;
375359
int c;
376360
u32 sys_size;
377361
struct stat sb;
@@ -442,31 +426,9 @@ int main(int argc, char ** argv)
442426
buf[0x1f1] = setup_sectors-1;
443427
put_unaligned_le32(sys_size, &buf[0x1f4]);
444428

445-
init_sz = get_unaligned_le32(&buf[0x260]);
446-
#ifdef CONFIG_EFI_STUB
447-
/*
448-
* The decompression buffer will start at ImageBase. When relocating
449-
* the compressed kernel to its end, we must ensure that the head
450-
* section does not get overwritten. The head section occupies
451-
* [i, i + _ehead), and the destination is [init_sz - _end, init_sz).
452-
*
453-
* At present these should never overlap, because 'i' is at most 32k
454-
* because of SETUP_SECT_MAX, '_ehead' is less than 1k, and the
455-
* calculation of INIT_SIZE in boot/header.S ensures that
456-
* 'init_sz - _end' is at least 64k.
457-
*
458-
* For future-proofing, increase init_sz if necessary.
459-
*/
460-
461-
if (init_sz - _end < i + _ehead) {
462-
init_sz = (i + _ehead + _end + 4095) & ~4095;
463-
put_unaligned_le32(init_sz, &buf[0x260]);
464-
}
465-
#endif
466-
update_pecoff_text(setup_sectors * 512, i + (sys_size * 16), init_sz);
429+
update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
467430

468431
efi_stub_entry_update();
469-
470432
/* Update kernel_info offset. */
471433
put_unaligned_le32(kernel_info, &buf[0x268]);
472434

0 commit comments

Comments
 (0)