Skip to content

Commit aeb9206

Browse files
ardbiesheuvelIngo Molnar
authored and
Ingo Molnar
committed
x86/boot: Derive file size from _edata symbol
Tweak the linker script so that the value of _edata represents the decompressor binary's file size rounded up to the appropriate alignment. This removes the need to calculate it in the build tool, and will make it easier to refer to the file size from the header directly in subsequent changes to the PE header layout. While adding _edata to the sed regex that parses the compressed vmlinux's symbol list, tweak the regex a bit for conciseness. This change has no impact on the resulting bzImage binary when configured with CONFIG_EFI_STUB=y. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 093ab25 commit aeb9206

File tree

4 files changed

+12
-25
lines changed

4 files changed

+12
-25
lines changed

arch/x86/boot/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
8989

9090
SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
9191

92-
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|efi32_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
92+
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_edata\|z_.*\)$$/\#define ZO_\2 0x\1/p'
9393

9494
quiet_cmd_zoffset = ZOFFSET $@
9595
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@

arch/x86/boot/compressed/vmlinux.lds.S

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ SECTIONS
4747
_data = . ;
4848
*(.data)
4949
*(.data.*)
50+
51+
/* Add 4 bytes of extra space for a CRC-32 checksum */
52+
. = ALIGN(. + 4, 0x20);
5053
_edata = . ;
5154
}
5255
. = ALIGN(L1_CACHE_BYTES);

arch/x86/boot/header.S

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */
233233
hdr:
234234
.byte setup_sects - 1
235235
root_flags: .word ROOT_RDONLY
236-
syssize: .long 0 /* Filled in by build.c */
236+
syssize: .long ZO__edata / 16
237237
ram_size: .word 0 /* Obsolete */
238238
vid_mode: .word SVGA_MODE
239239
root_dev: .word 0 /* Default to major/minor 0/0 */

arch/x86/boot/tools/build.c

+7-23
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ u8 buf[SETUP_SECT_MAX*512];
5252

5353
static unsigned long efi_pe_entry;
5454
static unsigned long efi32_pe_entry;
55+
static unsigned long _edata;
5556
static unsigned long _end;
5657

5758
/*----------------------------------------------------------------------*/
@@ -308,6 +309,7 @@ static void parse_zoffset(char *fname)
308309
while (p && *p) {
309310
PARSE_ZOFS(p, efi_pe_entry);
310311
PARSE_ZOFS(p, efi32_pe_entry);
312+
PARSE_ZOFS(p, _edata);
311313
PARSE_ZOFS(p, _end);
312314

313315
p = strchr(p, '\n');
@@ -320,7 +322,6 @@ int main(int argc, char ** argv)
320322
{
321323
unsigned int i, sz, setup_sectors;
322324
int c;
323-
u32 sys_size;
324325
struct stat sb;
325326
FILE *file, *dest;
326327
int fd;
@@ -368,24 +369,14 @@ int main(int argc, char ** argv)
368369
die("Unable to open `%s': %m", argv[2]);
369370
if (fstat(fd, &sb))
370371
die("Unable to stat `%s': %m", argv[2]);
371-
sz = sb.st_size;
372+
if (_edata != sb.st_size)
373+
die("Unexpected file size `%s': %u != %u", argv[2], _edata,
374+
sb.st_size);
375+
sz = _edata - 4;
372376
kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
373377
if (kernel == MAP_FAILED)
374378
die("Unable to mmap '%s': %m", argv[2]);
375-
/* Number of 16-byte paragraphs, including space for a 4-byte CRC */
376-
sys_size = (sz + 15 + 4) / 16;
377-
#ifdef CONFIG_EFI_STUB
378-
/*
379-
* COFF requires minimum 32-byte alignment of sections, and
380-
* adding a signature is problematic without that alignment.
381-
*/
382-
sys_size = (sys_size + 1) & ~1;
383-
#endif
384-
385-
/* Patch the setup code with the appropriate size parameters */
386-
put_unaligned_le32(sys_size, &buf[0x1f4]);
387-
388-
update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
379+
update_pecoff_text(setup_sectors * 512, i + _edata);
389380

390381

391382
crc = partial_crc32(buf, i, crc);
@@ -397,13 +388,6 @@ int main(int argc, char ** argv)
397388
if (fwrite(kernel, 1, sz, dest) != sz)
398389
die("Writing kernel failed");
399390

400-
/* Add padding leaving 4 bytes for the checksum */
401-
while (sz++ < (sys_size*16) - 4) {
402-
crc = partial_crc32_one('\0', crc);
403-
if (fwrite("\0", 1, 1, dest) != 1)
404-
die("Writing padding failed");
405-
}
406-
407391
/* Write the CRC */
408392
put_unaligned_le32(crc, buf);
409393
if (fwrite(buf, 1, 4, dest) != 4)

0 commit comments

Comments
 (0)