~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/openbios/libopenbios/elf_info.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}