aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-02-20 08:20:59 -0500
committerH. Peter Anvin <hpa@zytor.com>2012-06-01 12:11:26 -0400
commit9fa7dedad3d30345c843bd82db02c4d6169e5f61 (patch)
tree8f7563d8e33e7faf4def6f58a44de664e0f106bc /arch
parent30dc0d0fe5d08396dbdaa2d70972149131340960 (diff)
x86, efi; Add EFI boot stub console support
We need a way of printing useful messages to the user, for example when we fail to open an initrd file, instead of just hanging the machine without giving the user any indication of what went wrong. So sprinkle some error messages throughout the EFI boot stub code to make it easier for users to diagnose/report problems. Reported-by: Keshav P R <the.ridikulus.rat@gmail.com> Cc: Matthew Garrett <mjg@redhat.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com> Link: http://lkml.kernel.org/r/1331907517-3985-3-git-send-email-matt@console-pimps.org Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/boot/compressed/eboot.c85
-rw-r--r--arch/x86/boot/compressed/eboot.h6
2 files changed, 75 insertions, 16 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 52a4e667b258..4e85f5f85837 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -16,6 +16,26 @@
16 16
17static efi_system_table_t *sys_table; 17static efi_system_table_t *sys_table;
18 18
19static void efi_printk(char *str)
20{
21 char *s8;
22
23 for (s8 = str; *s8; s8++) {
24 struct efi_simple_text_output_protocol *out;
25 efi_char16_t ch[2] = { 0 };
26
27 ch[0] = *s8;
28 out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
29
30 if (*s8 == '\n') {
31 efi_char16_t nl[2] = { '\r', 0 };
32 efi_call_phys2(out->output_string, out, nl);
33 }
34
35 efi_call_phys2(out->output_string, out, ch);
36 }
37}
38
19static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size, 39static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size,
20 unsigned long *desc_size) 40 unsigned long *desc_size)
21{ 41{
@@ -531,8 +551,10 @@ static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
531 EFI_LOADER_DATA, 551 EFI_LOADER_DATA,
532 nr_initrds * sizeof(*initrds), 552 nr_initrds * sizeof(*initrds),
533 &initrds); 553 &initrds);
534 if (status != EFI_SUCCESS) 554 if (status != EFI_SUCCESS) {
555 efi_printk("Failed to alloc mem for initrds\n");
535 goto fail; 556 goto fail;
557 }
536 558
537 str = (char *)(unsigned long)hdr->cmd_line_ptr; 559 str = (char *)(unsigned long)hdr->cmd_line_ptr;
538 for (i = 0; i < nr_initrds; i++) { 560 for (i = 0; i < nr_initrds; i++) {
@@ -575,32 +597,42 @@ static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
575 597
576 status = efi_call_phys3(boottime->handle_protocol, 598 status = efi_call_phys3(boottime->handle_protocol,
577 image->device_handle, &fs_proto, &io); 599 image->device_handle, &fs_proto, &io);
578 if (status != EFI_SUCCESS) 600 if (status != EFI_SUCCESS) {
601 efi_printk("Failed to handle fs_proto\n");
579 goto free_initrds; 602 goto free_initrds;
603 }
580 604
581 status = efi_call_phys2(io->open_volume, io, &fh); 605 status = efi_call_phys2(io->open_volume, io, &fh);
582 if (status != EFI_SUCCESS) 606 if (status != EFI_SUCCESS) {
607 efi_printk("Failed to open volume\n");
583 goto free_initrds; 608 goto free_initrds;
609 }
584 } 610 }
585 611
586 status = efi_call_phys5(fh->open, fh, &h, filename_16, 612 status = efi_call_phys5(fh->open, fh, &h, filename_16,
587 EFI_FILE_MODE_READ, (u64)0); 613 EFI_FILE_MODE_READ, (u64)0);
588 if (status != EFI_SUCCESS) 614 if (status != EFI_SUCCESS) {
615 efi_printk("Failed to open initrd file\n");
589 goto close_handles; 616 goto close_handles;
617 }
590 618
591 initrd->handle = h; 619 initrd->handle = h;
592 620
593 info_sz = 0; 621 info_sz = 0;
594 status = efi_call_phys4(h->get_info, h, &info_guid, 622 status = efi_call_phys4(h->get_info, h, &info_guid,
595 &info_sz, NULL); 623 &info_sz, NULL);
596 if (status != EFI_BUFFER_TOO_SMALL) 624 if (status != EFI_BUFFER_TOO_SMALL) {
625 efi_printk("Failed to get initrd info size\n");
597 goto close_handles; 626 goto close_handles;
627 }
598 628
599grow: 629grow:
600 status = efi_call_phys3(sys_table->boottime->allocate_pool, 630 status = efi_call_phys3(sys_table->boottime->allocate_pool,
601 EFI_LOADER_DATA, info_sz, &info); 631 EFI_LOADER_DATA, info_sz, &info);
602 if (status != EFI_SUCCESS) 632 if (status != EFI_SUCCESS) {
633 efi_printk("Failed to alloc mem for initrd info\n");
603 goto close_handles; 634 goto close_handles;
635 }
604 636
605 status = efi_call_phys4(h->get_info, h, &info_guid, 637 status = efi_call_phys4(h->get_info, h, &info_guid,
606 &info_sz, info); 638 &info_sz, info);
@@ -612,8 +644,10 @@ grow:
612 file_sz = info->file_size; 644 file_sz = info->file_size;
613 efi_call_phys1(sys_table->boottime->free_pool, info); 645 efi_call_phys1(sys_table->boottime->free_pool, info);
614 646
615 if (status != EFI_SUCCESS) 647 if (status != EFI_SUCCESS) {
648 efi_printk("Failed to get initrd info\n");
616 goto close_handles; 649 goto close_handles;
650 }
617 651
618 initrd->size = file_sz; 652 initrd->size = file_sz;
619 initrd_total += file_sz; 653 initrd_total += file_sz;
@@ -629,11 +663,14 @@ grow:
629 */ 663 */
630 status = high_alloc(initrd_total, 0x1000, 664 status = high_alloc(initrd_total, 0x1000,
631 &initrd_addr, hdr->initrd_addr_max); 665 &initrd_addr, hdr->initrd_addr_max);
632 if (status != EFI_SUCCESS) 666 if (status != EFI_SUCCESS) {
667 efi_printk("Failed to alloc highmem for initrds\n");
633 goto close_handles; 668 goto close_handles;
669 }
634 670
635 /* We've run out of free low memory. */ 671 /* We've run out of free low memory. */
636 if (initrd_addr > hdr->initrd_addr_max) { 672 if (initrd_addr > hdr->initrd_addr_max) {
673 efi_printk("We've run out of free low memory\n");
637 status = EFI_INVALID_PARAMETER; 674 status = EFI_INVALID_PARAMETER;
638 goto free_initrd_total; 675 goto free_initrd_total;
639 } 676 }
@@ -652,8 +689,10 @@ grow:
652 status = efi_call_phys3(fh->read, 689 status = efi_call_phys3(fh->read,
653 initrds[j].handle, 690 initrds[j].handle,
654 &chunksize, addr); 691 &chunksize, addr);
655 if (status != EFI_SUCCESS) 692 if (status != EFI_SUCCESS) {
693 efi_printk("Failed to read initrd\n");
656 goto free_initrd_total; 694 goto free_initrd_total;
695 }
657 addr += chunksize; 696 addr += chunksize;
658 size -= chunksize; 697 size -= chunksize;
659 } 698 }
@@ -732,8 +771,10 @@ static efi_status_t make_boot_params(struct boot_params *boot_params,
732 options_size++; /* NUL termination */ 771 options_size++; /* NUL termination */
733 772
734 status = low_alloc(options_size, 1, &cmdline); 773 status = low_alloc(options_size, 1, &cmdline);
735 if (status != EFI_SUCCESS) 774 if (status != EFI_SUCCESS) {
775 efi_printk("Failed to alloc mem for cmdline\n");
736 goto fail; 776 goto fail;
777 }
737 778
738 s1 = (u8 *)(unsigned long)cmdline; 779 s1 = (u8 *)(unsigned long)cmdline;
739 s2 = (u16 *)options; 780 s2 = (u16 *)options;
@@ -895,12 +936,16 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table)
895 936
896 status = efi_call_phys3(sys_table->boottime->handle_protocol, 937 status = efi_call_phys3(sys_table->boottime->handle_protocol,
897 handle, &proto, (void *)&image); 938 handle, &proto, (void *)&image);
898 if (status != EFI_SUCCESS) 939 if (status != EFI_SUCCESS) {
940 efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
899 goto fail; 941 goto fail;
942 }
900 943
901 status = low_alloc(0x4000, 1, (unsigned long *)&boot_params); 944 status = low_alloc(0x4000, 1, (unsigned long *)&boot_params);
902 if (status != EFI_SUCCESS) 945 if (status != EFI_SUCCESS) {
946 efi_printk("Failed to alloc lowmem for boot params\n");
903 goto fail; 947 goto fail;
948 }
904 949
905 memset(boot_params, 0x0, 0x4000); 950 memset(boot_params, 0x0, 0x4000);
906 951
@@ -933,8 +978,10 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table)
933 if (status != EFI_SUCCESS) { 978 if (status != EFI_SUCCESS) {
934 status = low_alloc(hdr->init_size, hdr->kernel_alignment, 979 status = low_alloc(hdr->init_size, hdr->kernel_alignment,
935 &start); 980 &start);
936 if (status != EFI_SUCCESS) 981 if (status != EFI_SUCCESS) {
982 efi_printk("Failed to alloc mem for kernel\n");
937 goto fail; 983 goto fail;
984 }
938 } 985 }
939 986
940 hdr->code32_start = (__u32)start; 987 hdr->code32_start = (__u32)start;
@@ -945,19 +992,25 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table)
945 status = efi_call_phys3(sys_table->boottime->allocate_pool, 992 status = efi_call_phys3(sys_table->boottime->allocate_pool,
946 EFI_LOADER_DATA, sizeof(*gdt), 993 EFI_LOADER_DATA, sizeof(*gdt),
947 (void **)&gdt); 994 (void **)&gdt);
948 if (status != EFI_SUCCESS) 995 if (status != EFI_SUCCESS) {
996 efi_printk("Failed to alloc mem for gdt structure\n");
949 goto fail; 997 goto fail;
998 }
950 999
951 gdt->size = 0x800; 1000 gdt->size = 0x800;
952 status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address); 1001 status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address);
953 if (status != EFI_SUCCESS) 1002 if (status != EFI_SUCCESS) {
1003 efi_printk("Failed to alloc mem for gdt\n");
954 goto fail; 1004 goto fail;
1005 }
955 1006
956 status = efi_call_phys3(sys_table->boottime->allocate_pool, 1007 status = efi_call_phys3(sys_table->boottime->allocate_pool,
957 EFI_LOADER_DATA, sizeof(*idt), 1008 EFI_LOADER_DATA, sizeof(*idt),
958 (void **)&idt); 1009 (void **)&idt);
959 if (status != EFI_SUCCESS) 1010 if (status != EFI_SUCCESS) {
1011 efi_printk("Failed to alloc mem for idt structure\n");
960 goto fail; 1012 goto fail;
1013 }
961 1014
962 idt->size = 0; 1015 idt->size = 0;
963 idt->address = 0; 1016 idt->address = 0;
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index 39251663e65b..3b6e15627c55 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -58,4 +58,10 @@ struct efi_uga_draw_protocol {
58 void *blt; 58 void *blt;
59}; 59};
60 60
61struct efi_simple_text_output_protocol {
62 void *reset;
63 void *output_string;
64 void *test_string;
65};
66
61#endif /* BOOT_COMPRESSED_EBOOT_H */ 67#endif /* BOOT_COMPRESSED_EBOOT_H */