ppc64: Don't set Kp bit on SLB
[openbios.git] / libopenbios / elf_info.c
blobf7febef9d77de9fdbf8004169de777f1c5e3c21d
1 /* Support for ELF Boot Proposal as a boot image */
2 #include "config.h"
3 #include "arch/common/elf_boot.h"
4 #include "libopenbios/sys_info.h"
5 #include "asm/io.h"
6 #include "libopenbios/ipchecksum.h"
7 #include "openbios-version.h"
8 #define printf printk
9 #define debug printk
11 /* ELF image notes provide information to the loader who boots us */
13 /* This compiles and generates correct PT_NOTE segment for me.
14 * If it doesn't, use assembly version below. */
16 struct elf_image_note {
17 Elf_Nhdr hdr0;
18 char name0[sizeof(ELF_NOTE_BOOT)];
19 char prog_name[sizeof(PROGRAM_NAME)];
21 Elf_Nhdr hdr1;
22 char name1[sizeof(ELF_NOTE_BOOT)];
23 char version[sizeof(OPENBIOS_VERSION_STR)];
25 Elf_Nhdr hdr2;
26 char name2[sizeof(ELF_NOTE_BOOT)];
27 unsigned short checksum;
30 const struct elf_image_note elf_image_notes
31 __attribute__ ((section (".note.ELFBoot"))) =
33 .hdr0 = {
34 .n_namesz = sizeof(ELF_NOTE_BOOT),
35 .n_descsz = sizeof(PROGRAM_NAME),
36 .n_type = EIN_PROGRAM_NAME,
38 .name0 = ELF_NOTE_BOOT,
39 .prog_name = PROGRAM_NAME,
41 .hdr1 = {
42 .n_namesz = sizeof(ELF_NOTE_BOOT),
43 .n_descsz = sizeof(OPENBIOS_VERSION_STR),
44 .n_type = EIN_PROGRAM_VERSION,
46 .name1 = ELF_NOTE_BOOT,
47 .version = OPENBIOS_VERSION_STR,
49 .hdr2 = {
50 .n_namesz = sizeof(ELF_NOTE_BOOT),
51 .n_descsz = sizeof(unsigned short),
52 .n_type = EIN_PROGRAM_CHECKSUM,
54 .name2 = ELF_NOTE_BOOT,
55 .checksum = 0, /* to be computed by external tool */
58 /* This is refered by other files */
59 const char *program_name = elf_image_notes.prog_name;
60 const char *program_version = elf_image_notes.version;
62 #if 0
64 /* This tells the linker to make a PT_NOTE segment.
65 * If the section is named just ".note", it will be
66 * mixed up with useless .version notes generated by GCC.
68 .section ".note.ELFBoot", "a"
70 .align 4
71 .int 2f - 1f
72 .int 4f - 3f
73 .int EIN_PROGRAM_NAME
74 1: .asciz "ELFBoot"
75 2: .align 4
76 3: .asciz PROGRAM_NAME
79 .align 4
80 .int 2f - 1f
81 .int 4f - 3f
82 .int EIN_PROGRAM_VERSION
83 1: .asciz "ELFBoot"
84 2: .align 4
85 3: .asciz OPENBIOS_VERSION_STR
88 .align 4
89 .int 2f - 1f
90 .int 4f - 3f
91 .int EIN_PROGRAM_CHECKSUM
92 1: .asciz "ELFBoot"
93 2: .align 4
94 3: .short 0
96 #endif
98 /* Collect information from the ELF bootloader
99 * Note that we have to copy them to our own memory,
100 * otherwise they might be overwritten afterward. */
101 void collect_elfboot_info(struct sys_info *info)
103 Elf_Bhdr *hdr = NULL;
104 char *addr, *end;
105 Elf_Nhdr *nhdr;
106 char *desc;
108 if (info->boot_type == ELF_BHDR_MAGIC)
109 hdr = phys_to_virt(info->boot_data);
110 else
111 hdr = phys_to_virt(info->boot_arg);
113 if (hdr->b_signature != ELF_BHDR_MAGIC)
114 return;
116 if (ipchksum(hdr, hdr->b_size) != 0) {
117 printf("Broken ELF boot notes\n");
118 return;
121 addr = (char *) (hdr + 1);
122 end = addr + hdr->b_size;
123 while (addr < end) {
124 nhdr = (Elf_Nhdr *) addr;
125 addr += sizeof(Elf_Nhdr);
126 addr += (nhdr->n_namesz + 3) & ~3;
127 desc = addr;
128 addr += (nhdr->n_descsz + 3) & ~3;
130 if (nhdr->n_namesz == 0) {
131 /* Standard notes */
132 switch (nhdr->n_type) {
133 case EBN_FIRMWARE_TYPE:
134 info->firmware = strdup(desc);
135 break;
136 case EBN_BOOTLOADER_NAME:
137 debug("Bootloader: %s\n", desc);
138 break;
139 case EBN_BOOTLOADER_VERSION:
140 debug("Version: %s\n", desc);
141 break;
142 case EBN_COMMAND_LINE:
143 info->command_line = strdup(desc);
144 break;
145 case EBN_LOADED_IMAGE:
146 debug("Image name: %s\n", desc);
147 break;