diff options
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/compressed/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 32 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/misc.c | 13 | ||||
-rw-r--r-- | arch/x86/boot/compressed/mkpiggy.c | 9 |
6 files changed, 52 insertions, 16 deletions
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 704f58aa79cd..45abc363dd3e 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
@@ -76,8 +76,10 @@ suffix-$(CONFIG_KERNEL_XZ) := xz | |||
76 | suffix-$(CONFIG_KERNEL_LZO) := lzo | 76 | suffix-$(CONFIG_KERNEL_LZO) := lzo |
77 | suffix-$(CONFIG_KERNEL_LZ4) := lz4 | 77 | suffix-$(CONFIG_KERNEL_LZ4) := lz4 |
78 | 78 | ||
79 | RUN_SIZE = $(shell $(OBJDUMP) -h vmlinux | \ | ||
80 | perl $(srctree)/arch/x86/tools/calc_run_size.pl) | ||
79 | quiet_cmd_mkpiggy = MKPIGGY $@ | 81 | quiet_cmd_mkpiggy = MKPIGGY $@ |
80 | cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false ) | 82 | cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) |
81 | 83 | ||
82 | targets += piggy.S | 84 | targets += piggy.S |
83 | $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE | 85 | $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index de8eebd6f67c..1acf605a646d 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -330,8 +330,10 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) | |||
330 | size = pci->romsize + sizeof(*rom); | 330 | size = pci->romsize + sizeof(*rom); |
331 | 331 | ||
332 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); | 332 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); |
333 | if (status != EFI_SUCCESS) | 333 | if (status != EFI_SUCCESS) { |
334 | efi_printk(sys_table, "Failed to alloc mem for rom\n"); | ||
334 | return status; | 335 | return status; |
336 | } | ||
335 | 337 | ||
336 | memset(rom, 0, sizeof(*rom)); | 338 | memset(rom, 0, sizeof(*rom)); |
337 | 339 | ||
@@ -344,14 +346,18 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) | |||
344 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 346 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
345 | PCI_VENDOR_ID, 1, &(rom->vendor)); | 347 | PCI_VENDOR_ID, 1, &(rom->vendor)); |
346 | 348 | ||
347 | if (status != EFI_SUCCESS) | 349 | if (status != EFI_SUCCESS) { |
350 | efi_printk(sys_table, "Failed to read rom->vendor\n"); | ||
348 | goto free_struct; | 351 | goto free_struct; |
352 | } | ||
349 | 353 | ||
350 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 354 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
351 | PCI_DEVICE_ID, 1, &(rom->devid)); | 355 | PCI_DEVICE_ID, 1, &(rom->devid)); |
352 | 356 | ||
353 | if (status != EFI_SUCCESS) | 357 | if (status != EFI_SUCCESS) { |
358 | efi_printk(sys_table, "Failed to read rom->devid\n"); | ||
354 | goto free_struct; | 359 | goto free_struct; |
360 | } | ||
355 | 361 | ||
356 | status = efi_early->call(pci->get_location, pci, &(rom->segment), | 362 | status = efi_early->call(pci->get_location, pci, &(rom->segment), |
357 | &(rom->bus), &(rom->device), &(rom->function)); | 363 | &(rom->bus), &(rom->device), &(rom->function)); |
@@ -432,8 +438,10 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) | |||
432 | size = pci->romsize + sizeof(*rom); | 438 | size = pci->romsize + sizeof(*rom); |
433 | 439 | ||
434 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); | 440 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); |
435 | if (status != EFI_SUCCESS) | 441 | if (status != EFI_SUCCESS) { |
442 | efi_printk(sys_table, "Failed to alloc mem for rom\n"); | ||
436 | return status; | 443 | return status; |
444 | } | ||
437 | 445 | ||
438 | rom->data.type = SETUP_PCI; | 446 | rom->data.type = SETUP_PCI; |
439 | rom->data.len = size - sizeof(struct setup_data); | 447 | rom->data.len = size - sizeof(struct setup_data); |
@@ -444,14 +452,18 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) | |||
444 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 452 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
445 | PCI_VENDOR_ID, 1, &(rom->vendor)); | 453 | PCI_VENDOR_ID, 1, &(rom->vendor)); |
446 | 454 | ||
447 | if (status != EFI_SUCCESS) | 455 | if (status != EFI_SUCCESS) { |
456 | efi_printk(sys_table, "Failed to read rom->vendor\n"); | ||
448 | goto free_struct; | 457 | goto free_struct; |
458 | } | ||
449 | 459 | ||
450 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 460 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
451 | PCI_DEVICE_ID, 1, &(rom->devid)); | 461 | PCI_DEVICE_ID, 1, &(rom->devid)); |
452 | 462 | ||
453 | if (status != EFI_SUCCESS) | 463 | if (status != EFI_SUCCESS) { |
464 | efi_printk(sys_table, "Failed to read rom->devid\n"); | ||
454 | goto free_struct; | 465 | goto free_struct; |
466 | } | ||
455 | 467 | ||
456 | status = efi_early->call(pci->get_location, pci, &(rom->segment), | 468 | status = efi_early->call(pci->get_location, pci, &(rom->segment), |
457 | &(rom->bus), &(rom->device), &(rom->function)); | 469 | &(rom->bus), &(rom->device), &(rom->function)); |
@@ -538,8 +550,10 @@ static void setup_efi_pci(struct boot_params *params) | |||
538 | EFI_LOADER_DATA, | 550 | EFI_LOADER_DATA, |
539 | size, (void **)&pci_handle); | 551 | size, (void **)&pci_handle); |
540 | 552 | ||
541 | if (status != EFI_SUCCESS) | 553 | if (status != EFI_SUCCESS) { |
554 | efi_printk(sys_table, "Failed to alloc mem for pci_handle\n"); | ||
542 | return; | 555 | return; |
556 | } | ||
543 | 557 | ||
544 | status = efi_call_early(locate_handle, | 558 | status = efi_call_early(locate_handle, |
545 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, | 559 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, |
@@ -1105,6 +1119,10 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1105 | 1119 | ||
1106 | memset(sdt, 0, sizeof(*sdt)); | 1120 | memset(sdt, 0, sizeof(*sdt)); |
1107 | 1121 | ||
1122 | status = efi_parse_options(cmdline_ptr); | ||
1123 | if (status != EFI_SUCCESS) | ||
1124 | goto fail2; | ||
1125 | |||
1108 | status = handle_cmdline_files(sys_table, image, | 1126 | status = handle_cmdline_files(sys_table, image, |
1109 | (char *)(unsigned long)hdr->cmd_line_ptr, | 1127 | (char *)(unsigned long)hdr->cmd_line_ptr, |
1110 | "initrd=", hdr->initrd_addr_max, | 1128 | "initrd=", hdr->initrd_addr_max, |
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index cbed1407a5cd..1d7fbbcc196d 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -207,7 +207,8 @@ relocated: | |||
207 | * Do the decompression, and jump to the new kernel.. | 207 | * Do the decompression, and jump to the new kernel.. |
208 | */ | 208 | */ |
209 | /* push arguments for decompress_kernel: */ | 209 | /* push arguments for decompress_kernel: */ |
210 | pushl $z_output_len /* decompressed length */ | 210 | pushl $z_run_size /* size of kernel with .bss and .brk */ |
211 | pushl $z_output_len /* decompressed length, end of relocs */ | ||
211 | leal z_extract_offset_negative(%ebx), %ebp | 212 | leal z_extract_offset_negative(%ebx), %ebp |
212 | pushl %ebp /* output address */ | 213 | pushl %ebp /* output address */ |
213 | pushl $z_input_len /* input_len */ | 214 | pushl $z_input_len /* input_len */ |
@@ -217,7 +218,7 @@ relocated: | |||
217 | pushl %eax /* heap area */ | 218 | pushl %eax /* heap area */ |
218 | pushl %esi /* real mode pointer */ | 219 | pushl %esi /* real mode pointer */ |
219 | call decompress_kernel /* returns kernel location in %eax */ | 220 | call decompress_kernel /* returns kernel location in %eax */ |
220 | addl $24, %esp | 221 | addl $28, %esp |
221 | 222 | ||
222 | /* | 223 | /* |
223 | * Jump to the decompressed kernel. | 224 | * Jump to the decompressed kernel. |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 2884e0c3e8a5..6b1766c6c082 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -402,13 +402,16 @@ relocated: | |||
402 | * Do the decompression, and jump to the new kernel.. | 402 | * Do the decompression, and jump to the new kernel.. |
403 | */ | 403 | */ |
404 | pushq %rsi /* Save the real mode argument */ | 404 | pushq %rsi /* Save the real mode argument */ |
405 | movq $z_run_size, %r9 /* size of kernel with .bss and .brk */ | ||
406 | pushq %r9 | ||
405 | movq %rsi, %rdi /* real mode address */ | 407 | movq %rsi, %rdi /* real mode address */ |
406 | leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ | 408 | leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ |
407 | leaq input_data(%rip), %rdx /* input_data */ | 409 | leaq input_data(%rip), %rdx /* input_data */ |
408 | movl $z_input_len, %ecx /* input_len */ | 410 | movl $z_input_len, %ecx /* input_len */ |
409 | movq %rbp, %r8 /* output target address */ | 411 | movq %rbp, %r8 /* output target address */ |
410 | movq $z_output_len, %r9 /* decompressed length */ | 412 | movq $z_output_len, %r9 /* decompressed length, end of relocs */ |
411 | call decompress_kernel /* returns kernel location in %rax */ | 413 | call decompress_kernel /* returns kernel location in %rax */ |
414 | popq %r9 | ||
412 | popq %rsi | 415 | popq %rsi |
413 | 416 | ||
414 | /* | 417 | /* |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 57ab74df7eea..30dd59a9f0b4 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -358,7 +358,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
358 | unsigned char *input_data, | 358 | unsigned char *input_data, |
359 | unsigned long input_len, | 359 | unsigned long input_len, |
360 | unsigned char *output, | 360 | unsigned char *output, |
361 | unsigned long output_len) | 361 | unsigned long output_len, |
362 | unsigned long run_size) | ||
362 | { | 363 | { |
363 | real_mode = rmode; | 364 | real_mode = rmode; |
364 | 365 | ||
@@ -381,8 +382,14 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
381 | free_mem_ptr = heap; /* Heap */ | 382 | free_mem_ptr = heap; /* Heap */ |
382 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; | 383 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; |
383 | 384 | ||
384 | output = choose_kernel_location(input_data, input_len, | 385 | /* |
385 | output, output_len); | 386 | * The memory hole needed for the kernel is the larger of either |
387 | * the entire decompressed kernel plus relocation table, or the | ||
388 | * entire decompressed kernel plus .bss and .brk sections. | ||
389 | */ | ||
390 | output = choose_kernel_location(input_data, input_len, output, | ||
391 | output_len > run_size ? output_len | ||
392 | : run_size); | ||
386 | 393 | ||
387 | /* Validate memory location choices. */ | 394 | /* Validate memory location choices. */ |
388 | if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1)) | 395 | if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1)) |
diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c index b669ab65bf6c..d8222f213182 100644 --- a/arch/x86/boot/compressed/mkpiggy.c +++ b/arch/x86/boot/compressed/mkpiggy.c | |||
@@ -36,11 +36,13 @@ int main(int argc, char *argv[]) | |||
36 | uint32_t olen; | 36 | uint32_t olen; |
37 | long ilen; | 37 | long ilen; |
38 | unsigned long offs; | 38 | unsigned long offs; |
39 | unsigned long run_size; | ||
39 | FILE *f = NULL; | 40 | FILE *f = NULL; |
40 | int retval = 1; | 41 | int retval = 1; |
41 | 42 | ||
42 | if (argc < 2) { | 43 | if (argc < 3) { |
43 | fprintf(stderr, "Usage: %s compressed_file\n", argv[0]); | 44 | fprintf(stderr, "Usage: %s compressed_file run_size\n", |
45 | argv[0]); | ||
44 | goto bail; | 46 | goto bail; |
45 | } | 47 | } |
46 | 48 | ||
@@ -74,6 +76,7 @@ int main(int argc, char *argv[]) | |||
74 | offs += olen >> 12; /* Add 8 bytes for each 32K block */ | 76 | offs += olen >> 12; /* Add 8 bytes for each 32K block */ |
75 | offs += 64*1024 + 128; /* Add 64K + 128 bytes slack */ | 77 | offs += 64*1024 + 128; /* Add 64K + 128 bytes slack */ |
76 | offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ | 78 | offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ |
79 | run_size = atoi(argv[2]); | ||
77 | 80 | ||
78 | printf(".section \".rodata..compressed\",\"a\",@progbits\n"); | 81 | printf(".section \".rodata..compressed\",\"a\",@progbits\n"); |
79 | printf(".globl z_input_len\n"); | 82 | printf(".globl z_input_len\n"); |
@@ -85,6 +88,8 @@ int main(int argc, char *argv[]) | |||
85 | /* z_extract_offset_negative allows simplification of head_32.S */ | 88 | /* z_extract_offset_negative allows simplification of head_32.S */ |
86 | printf(".globl z_extract_offset_negative\n"); | 89 | printf(".globl z_extract_offset_negative\n"); |
87 | printf("z_extract_offset_negative = -0x%lx\n", offs); | 90 | printf("z_extract_offset_negative = -0x%lx\n", offs); |
91 | printf(".globl z_run_size\n"); | ||
92 | printf("z_run_size = %lu\n", run_size); | ||
88 | 93 | ||
89 | printf(".globl input_data, input_data_end\n"); | 94 | printf(".globl input_data, input_data_end\n"); |
90 | printf("input_data:\n"); | 95 | printf("input_data:\n"); |