]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/OvmfXenElfHeaderGenerator.c
OvmfPkg/CloudHv: Replace legacy 8254 PIT with local APIC timer
[mirror_edk2.git] / OvmfPkg / OvmfXenElfHeaderGenerator.c
1 /** @file
2 This program generates a hex array to be manually coppied into
3 OvmfXen.fdf.
4
5 The purpose is for the flash device image to be recognize as an ELF.
6
7 Copyright (c) 2019, Citrix Systems, Inc.
8
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10 **/
11
12 #include "elf.h"
13 #include "stdio.h"
14 #include "stddef.h"
15
16 void
17 print_hdr (
18 void *s,
19 size_t size
20 )
21 {
22 char *c = s;
23
24 while (size--) {
25 printf ("0x%02hhx, ", *(c++));
26 }
27 }
28
29 /* Format for the XEN_ELFNOTE_PHYS32_ENTRY program segment */
30 #define XEN_ELFNOTE_PHYS32_ENTRY 18
31 typedef struct {
32 uint32_t name_size;
33 uint32_t desc_size;
34 uint32_t type;
35 char name[4];
36 uint32_t desc;
37 } xen_elfnote_phys32_entry;
38
39 int
40 main (
41 void
42 )
43 {
44 /* FW_SIZE */
45 size_t ovmf_blob_size = 0x00200000;
46 /* Load OVMF at 1MB when running as PVH guest */
47 uint32_t ovmf_base_address = 0x00100000;
48 /* Xen PVH entry point */
49 uint32_t ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
50 size_t offset_into_file = 0;
51
52 /* ELF file header */
53 Elf32_Ehdr hdr = {
54 .e_ident = ELFMAG,
55 .e_type = ET_EXEC,
56 .e_machine = EM_386,
57 .e_version = EV_CURRENT,
58 .e_entry = ovmfxen_pvh_entry_point,
59 .e_flags = R_386_NONE,
60 .e_ehsize = sizeof (hdr),
61 .e_phentsize = sizeof (Elf32_Phdr),
62 };
63
64 offset_into_file += sizeof (hdr);
65
66 hdr.e_ident[EI_CLASS] = ELFCLASS32;
67 hdr.e_ident[EI_DATA] = ELFDATA2LSB;
68 hdr.e_ident[EI_VERSION] = EV_CURRENT;
69 hdr.e_ident[EI_OSABI] = ELFOSABI_LINUX;
70 /* Placing program headers just after hdr */
71 hdr.e_phoff = sizeof (hdr);
72
73 /* program header */
74 Elf32_Phdr phdr_load = {
75 .p_type = PT_LOAD,
76 .p_offset = 0, /* load everything */
77 .p_paddr = ovmf_base_address,
78 .p_filesz = ovmf_blob_size,
79 .p_memsz = ovmf_blob_size,
80 .p_flags = PF_X | PF_W | PF_R,
81 .p_align = 0,
82 };
83
84 phdr_load.p_vaddr = phdr_load.p_paddr;
85 hdr.e_phnum += 1;
86 offset_into_file += sizeof (phdr_load);
87
88 /* Xen ELF Note. */
89
90 xen_elfnote_phys32_entry xen_elf_note = {
91 .type = XEN_ELFNOTE_PHYS32_ENTRY,
92 .name = "Xen",
93 .desc = ovmfxen_pvh_entry_point,
94 .name_size =
95 offsetof (xen_elfnote_phys32_entry, desc) -
96 offsetof (xen_elfnote_phys32_entry, name),
97 .desc_size =
98 sizeof (xen_elfnote_phys32_entry) -
99 offsetof (xen_elfnote_phys32_entry, desc),
100 };
101 Elf32_Phdr phdr_note = {
102 .p_type = PT_NOTE,
103 .p_filesz = sizeof (xen_elf_note),
104 .p_memsz = sizeof (xen_elf_note),
105 .p_flags = PF_R,
106 .p_align = 0,
107 };
108
109 hdr.e_phnum += 1;
110 offset_into_file += sizeof (phdr_note);
111 phdr_note.p_offset = offset_into_file;
112 phdr_note.p_paddr = ovmf_base_address + phdr_note.p_offset;
113 phdr_note.p_vaddr = phdr_note.p_paddr;
114
115 /*
116 * print elf header
117 */
118
119 size_t i;
120 size_t hdr_size = sizeof (hdr);
121 size_t entry_off = offsetof (typeof(hdr), e_entry);
122
123 printf ("# ELF file header\n");
124 print_hdr (&hdr, entry_off);
125 printf ("\n");
126 print_hdr (&hdr.e_entry, sizeof (hdr.e_entry));
127 printf (" # hdr.e_entry\n");
128 print_hdr (&hdr.e_entry + 1, hdr_size - entry_off - sizeof (hdr.e_entry));
129
130 printf ("\n\n# ELF Program segment headers\n");
131 printf ("# - Load segment\n");
132 for (i = 0; i < sizeof (phdr_load); i += 4) {
133 print_hdr (((char *)&phdr_load) + i, 4);
134 printf ("\n");
135 }
136
137 printf ("# - ELFNOTE segment\n");
138 for (i = 0; i < sizeof (phdr_note); i += 4) {
139 print_hdr (((char *)&phdr_note) + i, 4);
140 printf ("\n");
141 }
142
143 printf ("\n# XEN_ELFNOTE_PHYS32_ENTRY\n");
144 for (i = 0; i < sizeof (xen_elf_note); i += 4) {
145 print_hdr (((char *)&xen_elf_note) + i, 4);
146 printf ("\n");
147 }
148
149 return 0;
150 }