23 |
#include <fcntl.h> |
#include <fcntl.h> |
24 |
#include <getopt.h> |
#include <getopt.h> |
25 |
#include <stdlib.h> |
#include <stdlib.h> |
26 |
|
#include <string.h> |
27 |
#include <grub/elf.h> |
#include <grub/elf.h> |
28 |
#include <grub/util/misc.h> |
#include <grub/util/misc.h> |
29 |
#include <grub/util/resolve.h> |
#include <grub/util/resolve.h> |
33 |
#define ALIGN_UP(addr, align) ((long)((char *)addr + align - 1) & ~(align - 1)) |
#define ALIGN_UP(addr, align) ((long)((char *)addr + align - 1) & ~(align - 1)) |
34 |
|
|
35 |
static char *kernel_path = "grubof"; |
static char *kernel_path = "grubof"; |
|
static char *note_path = "note"; |
|
36 |
|
|
37 |
|
#define GRUB_IEEE1275_NOTE_NAME "PowerPC" |
38 |
|
#define GRUB_IEEE1275_NOTE_TYPE 0x1275 |
39 |
|
|
40 |
|
/* These structures are defined according to the CHRP binding to IEEE1275, |
41 |
|
"Client Program Format" section. */ |
42 |
|
|
43 |
|
struct grub_ieee1275_note_hdr |
44 |
|
{ |
45 |
|
grub_uint32_t namesz; |
46 |
|
grub_uint32_t descsz; |
47 |
|
grub_uint32_t type; |
48 |
|
char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; |
49 |
|
}; |
50 |
|
|
51 |
|
struct grub_ieee1275_note_desc |
52 |
|
{ |
53 |
|
grub_uint32_t real_mode; |
54 |
|
grub_uint32_t real_base; |
55 |
|
grub_uint32_t real_size; |
56 |
|
grub_uint32_t virt_base; |
57 |
|
grub_uint32_t virt_size; |
58 |
|
grub_uint32_t load_base; |
59 |
|
}; |
60 |
|
|
61 |
|
struct grub_ieee1275_note |
62 |
|
{ |
63 |
|
struct grub_ieee1275_note_hdr header; |
64 |
|
struct grub_ieee1275_note_desc descriptor; |
65 |
|
}; |
66 |
|
|
67 |
void |
void |
68 |
load_note (Elf32_Phdr *phdr, const char *dir, FILE *out) |
load_note (Elf32_Phdr *phdr, FILE *out) |
69 |
{ |
{ |
70 |
char *note_img; |
struct grub_ieee1275_note note; |
71 |
char *path; |
int note_size = sizeof (struct grub_ieee1275_note); |
|
int note_size; |
|
72 |
|
|
73 |
grub_util_info ("adding CHRP NOTE segment"); |
grub_util_info ("adding CHRP NOTE segment"); |
74 |
|
|
75 |
path = grub_util_get_path (dir, note_path); |
note.header.namesz = grub_cpu_to_be32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); |
76 |
note_size = grub_util_get_image_size (path); |
note.header.descsz = grub_cpu_to_be32 (note_size); |
77 |
note_img = xmalloc (note_size); |
note.header.type = grub_cpu_to_be32 (GRUB_IEEE1275_NOTE_TYPE); |
78 |
grub_util_load_image (path, note_img); |
strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME); |
79 |
free (path); |
note.descriptor.real_mode = grub_cpu_to_be32 (0xffffffff); |
80 |
|
note.descriptor.real_base = grub_cpu_to_be32 (0x00c00000); |
81 |
|
note.descriptor.real_size = grub_cpu_to_be32 (0xffffffff); |
82 |
|
note.descriptor.virt_base = grub_cpu_to_be32 (0xffffffff); |
83 |
|
note.descriptor.virt_size = grub_cpu_to_be32 (0xffffffff); |
84 |
|
note.descriptor.load_base = grub_cpu_to_be32 (0x00004000); |
85 |
|
|
86 |
/* Write the note data to the new segment. */ |
/* Write the note data to the new segment. */ |
87 |
grub_util_write_image_at (note_img, note_size, phdr->p_offset, out); |
grub_util_write_image_at (¬e, note_size, phdr->p_offset, out); |
88 |
|
|
89 |
/* Fill in the rest of the segment header. */ |
/* Fill in the rest of the segment header. */ |
90 |
phdr->p_type = PT_NOTE; |
phdr->p_type = PT_NOTE; |
150 |
phdr->p_type = PT_LOAD; |
phdr->p_type = PT_LOAD; |
151 |
phdr->p_flags = PF_R | PF_W | PF_X; |
phdr->p_flags = PF_R | PF_W | PF_X; |
152 |
phdr->p_align = sizeof (long); |
phdr->p_align = sizeof (long); |
153 |
phdr->p_vaddr = MODULE_BASE; |
phdr->p_vaddr = GRUB_IEEE1275_MODULE_BASE; |
154 |
phdr->p_paddr = MODULE_BASE; |
phdr->p_paddr = GRUB_IEEE1275_MODULE_BASE; |
155 |
phdr->p_filesz = total_module_size; |
phdr->p_filesz = total_module_size; |
156 |
phdr->p_memsz = total_module_size; |
phdr->p_memsz = total_module_size; |
157 |
} |
} |
216 |
/* Fill in p_offset so the callees know where to write. */ |
/* Fill in p_offset so the callees know where to write. */ |
217 |
phdr->p_offset = ALIGN_UP (grub_util_get_fp_size (out), sizeof (long)); |
phdr->p_offset = ALIGN_UP (grub_util_get_fp_size (out), sizeof (long)); |
218 |
|
|
219 |
load_note (phdr, dir, out); |
load_note (phdr, out); |
220 |
} |
} |
221 |
|
|
222 |
/* Don't bother preserving the section headers. */ |
/* Don't bother preserving the section headers. */ |