aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/boot/header.S26
-rw-r--r--arch/x86/boot/tools/build.c38
-rw-r--r--drivers/firmware/efi/efi-pstore.c2
-rw-r--r--drivers/firmware/efi/efi.c28
-rw-r--r--drivers/firmware/efi/libstub/fdt.c2
6 files changed, 73 insertions, 24 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7ea8aaaab7fc..842a5abf3aed 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1537,6 +1537,7 @@ config EFI
1537config EFI_STUB 1537config EFI_STUB
1538 bool "EFI stub support" 1538 bool "EFI stub support"
1539 depends on EFI && !X86_USE_3DNOW 1539 depends on EFI && !X86_USE_3DNOW
1540 select RELOCATABLE
1540 ---help--- 1541 ---help---
1541 This kernel feature allows a bzImage to be loaded directly 1542 This kernel feature allows a bzImage to be loaded directly
1542 by EFI firmware without the use of a bootloader. 1543 by EFI firmware without the use of a bootloader.
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 1fdb350c4a58..16ef02596db2 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -91,10 +91,9 @@ bs_die:
91 91
92 .section ".bsdata", "a" 92 .section ".bsdata", "a"
93bugger_off_msg: 93bugger_off_msg:
94 .ascii "Direct floppy boot is not supported. " 94 .ascii "Use a boot loader.\r\n"
95 .ascii "Use a boot loader program instead.\r\n"
96 .ascii "\n" 95 .ascii "\n"
97 .ascii "Remove disk and press any key to reboot ...\r\n" 96 .ascii "Remove disk and press any key to reboot...\r\n"
98 .byte 0 97 .byte 0
99 98
100#ifdef CONFIG_EFI_STUB 99#ifdef CONFIG_EFI_STUB
@@ -108,7 +107,7 @@ coff_header:
108#else 107#else
109 .word 0x8664 # x86-64 108 .word 0x8664 # x86-64
110#endif 109#endif
111 .word 3 # nr_sections 110 .word 4 # nr_sections
112 .long 0 # TimeDateStamp 111 .long 0 # TimeDateStamp
113 .long 0 # PointerToSymbolTable 112 .long 0 # PointerToSymbolTable
114 .long 1 # NumberOfSymbols 113 .long 1 # NumberOfSymbols
@@ -250,6 +249,25 @@ section_table:
250 .word 0 # NumberOfLineNumbers 249 .word 0 # NumberOfLineNumbers
251 .long 0x60500020 # Characteristics (section flags) 250 .long 0x60500020 # Characteristics (section flags)
252 251
252 #
253 # The offset & size fields are filled in by build.c.
254 #
255 .ascii ".bss"
256 .byte 0
257 .byte 0
258 .byte 0
259 .byte 0
260 .long 0
261 .long 0x0
262 .long 0 # Size of initialized data
263 # on disk
264 .long 0x0
265 .long 0 # PointerToRelocations
266 .long 0 # PointerToLineNumbers
267 .word 0 # NumberOfRelocations
268 .word 0 # NumberOfLineNumbers
269 .long 0xc8000080 # Characteristics (section flags)
270
253#endif /* CONFIG_EFI_STUB */ 271#endif /* CONFIG_EFI_STUB */
254 272
255 # Kernel attributes; used by setup. This is part 1 of the 273 # Kernel attributes; used by setup. This is part 1 of the
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 1a2f2121cada..a7661c430cd9 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -143,7 +143,7 @@ static void usage(void)
143 143
144#ifdef CONFIG_EFI_STUB 144#ifdef CONFIG_EFI_STUB
145 145
146static void update_pecoff_section_header(char *section_name, u32 offset, u32 size) 146static void update_pecoff_section_header_fields(char *section_name, u32 vma, u32 size, u32 datasz, u32 offset)
147{ 147{
148 unsigned int pe_header; 148 unsigned int pe_header;
149 unsigned short num_sections; 149 unsigned short num_sections;
@@ -164,10 +164,10 @@ static void update_pecoff_section_header(char *section_name, u32 offset, u32 siz
164 put_unaligned_le32(size, section + 0x8); 164 put_unaligned_le32(size, section + 0x8);
165 165
166 /* section header vma field */ 166 /* section header vma field */
167 put_unaligned_le32(offset, section + 0xc); 167 put_unaligned_le32(vma, section + 0xc);
168 168
169 /* section header 'size of initialised data' field */ 169 /* section header 'size of initialised data' field */
170 put_unaligned_le32(size, section + 0x10); 170 put_unaligned_le32(datasz, section + 0x10);
171 171
172 /* section header 'file offset' field */ 172 /* section header 'file offset' field */
173 put_unaligned_le32(offset, section + 0x14); 173 put_unaligned_le32(offset, section + 0x14);
@@ -179,6 +179,11 @@ static void update_pecoff_section_header(char *section_name, u32 offset, u32 siz
179 } 179 }
180} 180}
181 181
182static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
183{
184 update_pecoff_section_header_fields(section_name, offset, size, size, offset);
185}
186
182static void update_pecoff_setup_and_reloc(unsigned int size) 187static void update_pecoff_setup_and_reloc(unsigned int size)
183{ 188{
184 u32 setup_offset = 0x200; 189 u32 setup_offset = 0x200;
@@ -203,9 +208,6 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
203 208
204 pe_header = get_unaligned_le32(&buf[0x3c]); 209 pe_header = get_unaligned_le32(&buf[0x3c]);
205 210
206 /* Size of image */
207 put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
208
209 /* 211 /*
210 * Size of code: Subtract the size of the first sector (512 bytes) 212 * Size of code: Subtract the size of the first sector (512 bytes)
211 * which includes the header. 213 * which includes the header.
@@ -220,6 +222,22 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
220 update_pecoff_section_header(".text", text_start, text_sz); 222 update_pecoff_section_header(".text", text_start, text_sz);
221} 223}
222 224
225static void update_pecoff_bss(unsigned int file_sz, unsigned int init_sz)
226{
227 unsigned int pe_header;
228 unsigned int bss_sz = init_sz - file_sz;
229
230 pe_header = get_unaligned_le32(&buf[0x3c]);
231
232 /* Size of uninitialized data */
233 put_unaligned_le32(bss_sz, &buf[pe_header + 0x24]);
234
235 /* Size of image */
236 put_unaligned_le32(init_sz, &buf[pe_header + 0x50]);
237
238 update_pecoff_section_header_fields(".bss", file_sz, bss_sz, 0, 0);
239}
240
223static int reserve_pecoff_reloc_section(int c) 241static int reserve_pecoff_reloc_section(int c)
224{ 242{
225 /* Reserve 0x20 bytes for .reloc section */ 243 /* Reserve 0x20 bytes for .reloc section */
@@ -259,6 +277,8 @@ static void efi_stub_entry_update(void)
259static inline void update_pecoff_setup_and_reloc(unsigned int size) {} 277static inline void update_pecoff_setup_and_reloc(unsigned int size) {}
260static inline void update_pecoff_text(unsigned int text_start, 278static inline void update_pecoff_text(unsigned int text_start,
261 unsigned int file_sz) {} 279 unsigned int file_sz) {}
280static inline void update_pecoff_bss(unsigned int file_sz,
281 unsigned int init_sz) {}
262static inline void efi_stub_defaults(void) {} 282static inline void efi_stub_defaults(void) {}
263static inline void efi_stub_entry_update(void) {} 283static inline void efi_stub_entry_update(void) {}
264 284
@@ -310,7 +330,7 @@ static void parse_zoffset(char *fname)
310 330
311int main(int argc, char ** argv) 331int main(int argc, char ** argv)
312{ 332{
313 unsigned int i, sz, setup_sectors; 333 unsigned int i, sz, setup_sectors, init_sz;
314 int c; 334 int c;
315 u32 sys_size; 335 u32 sys_size;
316 struct stat sb; 336 struct stat sb;
@@ -376,7 +396,9 @@ int main(int argc, char ** argv)
376 buf[0x1f1] = setup_sectors-1; 396 buf[0x1f1] = setup_sectors-1;
377 put_unaligned_le32(sys_size, &buf[0x1f4]); 397 put_unaligned_le32(sys_size, &buf[0x1f4]);
378 398
379 update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz)); 399 update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
400 init_sz = get_unaligned_le32(&buf[0x260]);
401 update_pecoff_bss(i + (sys_size * 16), init_sz);
380 402
381 efi_stub_entry_update(); 403 efi_stub_entry_update();
382 404
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 4b9dc836dcf9..e992abc5ef26 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -40,7 +40,7 @@ struct pstore_read_data {
40static inline u64 generic_id(unsigned long timestamp, 40static inline u64 generic_id(unsigned long timestamp,
41 unsigned int part, int count) 41 unsigned int part, int count)
42{ 42{
43 return (timestamp * 100 + part) * 1000 + count; 43 return ((u64) timestamp * 100 + part) * 1000 + count;
44} 44}
45 45
46static int efi_pstore_read_func(struct efivar_entry *entry, void *data) 46static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 36ffa1747e84..64ecbb501c50 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -364,6 +364,7 @@ static __initdata struct {
364 364
365struct param_info { 365struct param_info {
366 int verbose; 366 int verbose;
367 int found;
367 void *params; 368 void *params;
368}; 369};
369 370
@@ -371,25 +372,21 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
371 int depth, void *data) 372 int depth, void *data)
372{ 373{
373 struct param_info *info = data; 374 struct param_info *info = data;
374 void *prop, *dest; 375 const void *prop;
375 unsigned long len; 376 void *dest;
376 u64 val; 377 u64 val;
377 int i; 378 int i, len;
378 379
379 if (depth != 1 || 380 if (depth != 1 ||
380 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) 381 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
381 return 0; 382 return 0;
382 383
383 pr_info("Getting parameters from FDT:\n");
384
385 for (i = 0; i < ARRAY_SIZE(dt_params); i++) { 384 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
386 prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len); 385 prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
387 if (!prop) { 386 if (!prop)
388 pr_err("Can't find %s in device tree!\n",
389 dt_params[i].name);
390 return 0; 387 return 0;
391 }
392 dest = info->params + dt_params[i].offset; 388 dest = info->params + dt_params[i].offset;
389 info->found++;
393 390
394 val = of_read_number(prop, len / sizeof(u32)); 391 val = of_read_number(prop, len / sizeof(u32));
395 392
@@ -408,10 +405,21 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
408int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose) 405int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
409{ 406{
410 struct param_info info; 407 struct param_info info;
408 int ret;
409
410 pr_info("Getting EFI parameters from FDT:\n");
411 411
412 info.verbose = verbose; 412 info.verbose = verbose;
413 info.found = 0;
413 info.params = params; 414 info.params = params;
414 415
415 return of_scan_flat_dt(fdt_find_uefi_params, &info); 416 ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
417 if (!info.found)
418 pr_info("UEFI not found.\n");
419 else if (!ret)
420 pr_err("Can't find '%s' in device tree!\n",
421 dt_params[info.found].name);
422
423 return ret;
416} 424}
417#endif /* CONFIG_EFI_PARAMS_FROM_FDT */ 425#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 86d2934840e2..a56bb3528755 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -57,7 +57,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
57 */ 57 */
58 prev = 0; 58 prev = 0;
59 for (;;) { 59 for (;;) {
60 const char *type, *name; 60 const char *type;
61 int len; 61 int len;
62 62
63 node = fdt_next_node(fdt, prev, NULL); 63 node = fdt_next_node(fdt, prev, NULL);