|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.