@@ -50,6 +50,8 @@ typedef unsigned int u32;
50
50
u8 buf [SETUP_SECT_MAX * 512 ];
51
51
int is_big_kernel ;
52
52
53
+ #define PECOFF_RELOC_RESERVE 0x20
54
+
53
55
/*----------------------------------------------------------------------*/
54
56
55
57
static const u32 crctab32 [] = {
@@ -133,11 +135,103 @@ static void usage(void)
133
135
die ("Usage: build setup system [> image]" );
134
136
}
135
137
136
- int main (int argc , char * * argv )
137
- {
138
138
#ifdef CONFIG_EFI_STUB
139
- unsigned int file_sz , pe_header ;
139
+
140
+ static void update_pecoff_section_header (char * section_name , u32 offset , u32 size )
141
+ {
142
+ unsigned int pe_header ;
143
+ unsigned short num_sections ;
144
+ u8 * section ;
145
+
146
+ pe_header = get_unaligned_le32 (& buf [0x3c ]);
147
+ num_sections = get_unaligned_le16 (& buf [pe_header + 6 ]);
148
+
149
+ #ifdef CONFIG_X86_32
150
+ section = & buf [pe_header + 0xa8 ];
151
+ #else
152
+ section = & buf [pe_header + 0xb8 ];
140
153
#endif
154
+
155
+ while (num_sections > 0 ) {
156
+ if (strncmp ((char * )section , section_name , 8 ) == 0 ) {
157
+ /* section header size field */
158
+ put_unaligned_le32 (size , section + 0x8 );
159
+
160
+ /* section header vma field */
161
+ put_unaligned_le32 (offset , section + 0xc );
162
+
163
+ /* section header 'size of initialised data' field */
164
+ put_unaligned_le32 (size , section + 0x10 );
165
+
166
+ /* section header 'file offset' field */
167
+ put_unaligned_le32 (offset , section + 0x14 );
168
+
169
+ break ;
170
+ }
171
+ section += 0x28 ;
172
+ num_sections -- ;
173
+ }
174
+ }
175
+
176
+ static void update_pecoff_setup_and_reloc (unsigned int size )
177
+ {
178
+ u32 setup_offset = 0x200 ;
179
+ u32 reloc_offset = size - PECOFF_RELOC_RESERVE ;
180
+ u32 setup_size = reloc_offset - setup_offset ;
181
+
182
+ update_pecoff_section_header (".setup" , setup_offset , setup_size );
183
+ update_pecoff_section_header (".reloc" , reloc_offset , PECOFF_RELOC_RESERVE );
184
+
185
+ /*
186
+ * Modify .reloc section contents with a single entry. The
187
+ * relocation is applied to offset 10 of the relocation section.
188
+ */
189
+ put_unaligned_le32 (reloc_offset + 10 , & buf [reloc_offset ]);
190
+ put_unaligned_le32 (10 , & buf [reloc_offset + 4 ]);
191
+ }
192
+
193
+ static void update_pecoff_text (unsigned int text_start , unsigned int file_sz )
194
+ {
195
+ unsigned int pe_header ;
196
+ unsigned int text_sz = file_sz - text_start ;
197
+
198
+ pe_header = get_unaligned_le32 (& buf [0x3c ]);
199
+
200
+ /* Size of image */
201
+ put_unaligned_le32 (file_sz , & buf [pe_header + 0x50 ]);
202
+
203
+ /*
204
+ * Size of code: Subtract the size of the first sector (512 bytes)
205
+ * which includes the header.
206
+ */
207
+ put_unaligned_le32 (file_sz - 512 , & buf [pe_header + 0x1c ]);
208
+
209
+ #ifdef CONFIG_X86_32
210
+ /*
211
+ * Address of entry point.
212
+ *
213
+ * The EFI stub entry point is +16 bytes from the start of
214
+ * the .text section.
215
+ */
216
+ put_unaligned_le32 (text_start + 16 , & buf [pe_header + 0x28 ]);
217
+ #else
218
+ /*
219
+ * Address of entry point. startup_32 is at the beginning and
220
+ * the 64-bit entry point (startup_64) is always 512 bytes
221
+ * after. The EFI stub entry point is 16 bytes after that, as
222
+ * the first instruction allows legacy loaders to jump over
223
+ * the EFI stub initialisation
224
+ */
225
+ put_unaligned_le32 (text_start + 528 , & buf [pe_header + 0x28 ]);
226
+ #endif /* CONFIG_X86_32 */
227
+
228
+ update_pecoff_section_header (".text" , text_start , text_sz );
229
+ }
230
+
231
+ #endif /* CONFIG_EFI_STUB */
232
+
233
+ int main (int argc , char * * argv )
234
+ {
141
235
unsigned int i , sz , setup_sectors ;
142
236
int c ;
143
237
u32 sys_size ;
@@ -163,13 +257,23 @@ int main(int argc, char ** argv)
163
257
die ("Boot block hasn't got boot flag (0xAA55)" );
164
258
fclose (file );
165
259
260
+ #ifdef CONFIG_EFI_STUB
261
+ /* Reserve 0x20 bytes for .reloc section */
262
+ memset (buf + c , 0 , PECOFF_RELOC_RESERVE );
263
+ c += PECOFF_RELOC_RESERVE ;
264
+ #endif
265
+
166
266
/* Pad unused space with zeros */
167
267
setup_sectors = (c + 511 ) / 512 ;
168
268
if (setup_sectors < SETUP_SECT_MIN )
169
269
setup_sectors = SETUP_SECT_MIN ;
170
270
i = setup_sectors * 512 ;
171
271
memset (buf + c , 0 , i - c );
172
272
273
+ #ifdef CONFIG_EFI_STUB
274
+ update_pecoff_setup_and_reloc (i );
275
+ #endif
276
+
173
277
/* Set the default root device */
174
278
put_unaligned_le16 (DEFAULT_ROOT_DEV , & buf [508 ]);
175
279
@@ -194,66 +298,8 @@ int main(int argc, char ** argv)
194
298
put_unaligned_le32 (sys_size , & buf [0x1f4 ]);
195
299
196
300
#ifdef CONFIG_EFI_STUB
197
- file_sz = sz + i + ((sys_size * 16 ) - sz );
198
-
199
- pe_header = get_unaligned_le32 (& buf [0x3c ]);
200
-
201
- /* Size of image */
202
- put_unaligned_le32 (file_sz , & buf [pe_header + 0x50 ]);
203
-
204
- /*
205
- * Subtract the size of the first section (512 bytes) which
206
- * includes the header and .reloc section. The remaining size
207
- * is that of the .text section.
208
- */
209
- file_sz -= 512 ;
210
-
211
- /* Size of code */
212
- put_unaligned_le32 (file_sz , & buf [pe_header + 0x1c ]);
213
-
214
- #ifdef CONFIG_X86_32
215
- /*
216
- * Address of entry point.
217
- *
218
- * The EFI stub entry point is +16 bytes from the start of
219
- * the .text section.
220
- */
221
- put_unaligned_le32 (i + 16 , & buf [pe_header + 0x28 ]);
222
-
223
- /* .text size */
224
- put_unaligned_le32 (file_sz , & buf [pe_header + 0xb0 ]);
225
-
226
- /* .text vma */
227
- put_unaligned_le32 (0x200 , & buf [pe_header + 0xb4 ]);
228
-
229
- /* .text size of initialised data */
230
- put_unaligned_le32 (file_sz , & buf [pe_header + 0xb8 ]);
231
-
232
- /* .text file offset */
233
- put_unaligned_le32 (0x200 , & buf [pe_header + 0xbc ]);
234
- #else
235
- /*
236
- * Address of entry point. startup_32 is at the beginning and
237
- * the 64-bit entry point (startup_64) is always 512 bytes
238
- * after. The EFI stub entry point is 16 bytes after that, as
239
- * the first instruction allows legacy loaders to jump over
240
- * the EFI stub initialisation
241
- */
242
- put_unaligned_le32 (i + 528 , & buf [pe_header + 0x28 ]);
243
-
244
- /* .text size */
245
- put_unaligned_le32 (file_sz , & buf [pe_header + 0xc0 ]);
246
-
247
- /* .text vma */
248
- put_unaligned_le32 (0x200 , & buf [pe_header + 0xc4 ]);
249
-
250
- /* .text size of initialised data */
251
- put_unaligned_le32 (file_sz , & buf [pe_header + 0xc8 ]);
252
-
253
- /* .text file offset */
254
- put_unaligned_le32 (0x200 , & buf [pe_header + 0xcc ]);
255
- #endif /* CONFIG_X86_32 */
256
- #endif /* CONFIG_EFI_STUB */
301
+ update_pecoff_text (setup_sectors * 512 , sz + i + ((sys_size * 16 ) - sz ));
302
+ #endif
257
303
258
304
crc = partial_crc32 (buf , i , crc );
259
305
if (fwrite (buf , 1 , i , stdout ) != i )
0 commit comments