Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / libopenbios / elf_info.c
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
10
11 /* ELF image notes provide information to the loader who boots us */
12
13 /* This compiles and generates correct PT_NOTE segment for me.
14  * If it doesn't, use assembly version below. */
15
16 struct elf_image_note {
17     Elf_Nhdr hdr0;
18     char name0[sizeof(ELF_NOTE_BOOT)];
19     char prog_name[sizeof(PROGRAM_NAME)];
20
21     Elf_Nhdr hdr1;
22     char name1[sizeof(ELF_NOTE_BOOT)];
23     char version[sizeof(OPENBIOS_VERSION_STR)];
24
25     Elf_Nhdr hdr2;
26     char name2[sizeof(ELF_NOTE_BOOT)];
27     unsigned short checksum;
28 };
29
30 const struct elf_image_note elf_image_notes
31         __attribute__ ((section (".note.ELFBoot"))) =
32 {
33     .hdr0 = {
34         .n_namesz = sizeof(ELF_NOTE_BOOT),
35         .n_descsz = sizeof(PROGRAM_NAME),
36         .n_type = EIN_PROGRAM_NAME,
37     },
38     .name0 = ELF_NOTE_BOOT,
39     .prog_name = PROGRAM_NAME,
40
41     .hdr1 = {
42         .n_namesz = sizeof(ELF_NOTE_BOOT),
43         .n_descsz = sizeof(OPENBIOS_VERSION_STR),
44         .n_type = EIN_PROGRAM_VERSION,
45     },
46     .name1 = ELF_NOTE_BOOT,
47     .version = OPENBIOS_VERSION_STR,
48
49     .hdr2 = {
50         .n_namesz = sizeof(ELF_NOTE_BOOT),
51         .n_descsz = sizeof(unsigned short),
52         .n_type = EIN_PROGRAM_CHECKSUM,
53     },
54     .name2 = ELF_NOTE_BOOT,
55     .checksum = 0, /* to be computed by external tool */
56 };
57
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;
61
62 #if 0
63
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.
67          */
68         .section ".note.ELFBoot", "a"
69
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
77 4:
78
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
86 4:
87
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
95 4:
96 #endif
97
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)
102 {
103     Elf_Bhdr *hdr = NULL;
104     char *addr, *end;
105     Elf_Nhdr *nhdr;
106     char *desc;
107
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);
112
113     if (hdr->b_signature != ELF_BHDR_MAGIC)
114         return;
115
116     if (ipchksum(hdr, hdr->b_size) != 0) {
117         printf("Broken ELF boot notes\n");
118         return;
119     }
120
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;
129
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;
148             }
149         }
150     }
151 }