source: bootcd/isolinux/syslinux-6.03/efi/main.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 32.1 KB
Line 
1/*
2 * Copyright 2011-2014 Intel Corporation - All Rights Reserved
3 */
4
5#include <codepage.h>
6#include <core.h>
7#include <fs.h>
8#include <com32.h>
9#include <syslinux/memscan.h>
10#include <syslinux/firmware.h>
11#include <syslinux/linux.h>
12#include <sys/ansi.h>
13#include <setjmp.h>
14
15#include "efi.h"
16#include "fio.h"
17#include "version.h"
18
19__export uint16_t PXERetry;
20__export char copyright_str[] = "Copyright (C) 2011-" YEAR_STR "\n";
21uint8_t SerialNotice = 1;
22__export char syslinux_banner[] = "Syslinux " VERSION_STR " (EFI; " DATE_STR ")\n";
23char CurrentDirName[CURRENTDIR_MAX];
24struct com32_sys_args __com32;
25
26uint32_t _IdleTimer = 0;
27char __lowmem_heap[32];
28uint32_t BIOS_timer_next;
29uint32_t timer_irq;
30__export uint8_t KbdMap[256];
31char aux_seg[256];
32
33static jmp_buf load_error_buf;
34
35static inline EFI_STATUS
36efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
37                   EFI_HANDLE controller)
38{
39    return uefi_call_wrapper(BS->CloseProtocol, 4, handle,
40                             guid, agent, controller);
41}
42
43struct efi_binding *efi_create_binding(EFI_GUID *bguid, EFI_GUID *pguid)
44{
45    EFI_SERVICE_BINDING *sbp;
46    struct efi_binding *b;
47    EFI_STATUS status;
48    EFI_HANDLE protocol, child, *handles = NULL;
49    UINTN i, nr_handles = 0;
50
51    b = malloc(sizeof(*b));
52    if (!b)
53        return NULL;
54
55    status = LibLocateHandle(ByProtocol, bguid, NULL, &nr_handles, &handles);
56    if (status != EFI_SUCCESS)
57        goto free_binding;
58
59    for (i = 0; i < nr_handles; i++) {
60        status = uefi_call_wrapper(BS->OpenProtocol, 6, handles[i],
61                                   bguid, (void **)&sbp,
62                                   image_handle, handles[i],
63                                   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
64        if (status == EFI_SUCCESS)
65            break;
66
67        uefi_call_wrapper(BS->CloseProtocol, 4, handles[i], bguid,
68                          image_handle, handles[i]);
69    }
70
71    if (i == nr_handles)
72        goto free_binding;
73
74    child = NULL;
75
76    status = uefi_call_wrapper(sbp->CreateChild, 2, sbp, (EFI_HANDLE *)&child);
77    if (status != EFI_SUCCESS)
78        goto close_protocol;
79
80    status = uefi_call_wrapper(BS->OpenProtocol, 6, child,
81                              pguid, (void **)&protocol,
82                              image_handle, sbp,
83                              EFI_OPEN_PROTOCOL_GET_PROTOCOL);
84    if (status != EFI_SUCCESS)
85        goto destroy_child;
86
87    b->parent = handles[i];
88    b->binding = sbp;
89    b->child = child;
90    b->this = protocol;
91
92    return b;
93
94destroy_child:
95    uefi_call_wrapper(sbp->DestroyChild, 2, sbp, child);
96
97close_protocol:
98    uefi_call_wrapper(BS->CloseProtocol, 4, handles[i], bguid,
99                      image_handle, handles[i]);
100
101free_binding:
102    free(b);
103    return NULL;
104}
105
106void efi_destroy_binding(struct efi_binding *b, EFI_GUID *guid)
107{
108    efi_close_protocol(b->child, guid, image_handle, b->binding);
109    uefi_call_wrapper(b->binding->DestroyChild, 2, b->binding, b->child);
110    efi_close_protocol(b->parent, guid, image_handle, b->parent);
111
112    free(b);
113}
114
115#undef kaboom
116void kaboom(void)
117{
118}
119
120void printf_init(void)
121{
122}
123
124__export void local_boot(uint16_t ax)
125{
126    /*
127     * Inform the firmware that we failed to execute correctly, which
128     * will trigger the next entry in the EFI Boot Manager list.
129     */
130    longjmp(load_error_buf, 1);
131}
132
133void bios_timer_cleanup(void)
134{
135}
136
137char trackbuf[4096];
138
139void __cdecl core_farcall(uint32_t c, const com32sys_t *a, com32sys_t *b)
140{
141}
142
143__export struct firmware *firmware = NULL;
144__export void *__syslinux_adv_ptr;
145__export size_t __syslinux_adv_size;
146char core_xfer_buf[65536];
147struct iso_boot_info {
148        uint32_t pvd;               /* LBA of primary volume descriptor */
149        uint32_t file;              /* LBA of boot file */
150        uint32_t length;            /* Length of boot file */
151        uint32_t csum;              /* Checksum of boot file */
152        uint32_t reserved[10];      /* Currently unused */
153} iso_boot_info;
154
155uint8_t DHCPMagic;
156uint32_t RebootTime;
157
158void pxenv(void)
159{
160}
161
162uint16_t BIOS_fbm = 1;
163far_ptr_t InitStack;
164far_ptr_t PXEEntry;
165
166void gpxe_unload(void)
167{
168}
169
170void do_idle(void)
171{
172}
173
174void pxe_int1a(void)
175{
176}
177
178uint8_t KeepPXE;
179
180struct semaphore;
181mstime_t sem_down(struct semaphore *sem, mstime_t time)
182{
183        /* EFI is single threaded */
184        return 0;
185}
186
187void sem_up(struct semaphore *sem)
188{
189        /* EFI is single threaded */
190}
191
192__export volatile uint32_t __ms_timer = 0;
193volatile uint32_t __jiffies = 0;
194
195void efi_write_char(uint8_t ch, uint8_t attribute)
196{
197        SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
198        uint16_t c[2];
199
200        uefi_call_wrapper(out->SetAttribute, 2, out, attribute);
201
202        /* Lookup primary Unicode encoding in the system codepage */
203        c[0] = codepage.uni[0][ch];
204        c[1] = '\0';
205
206        uefi_call_wrapper(out->OutputString, 2, out, c);
207}
208
209static void efi_showcursor(const struct term_state *st)
210{
211        SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
212        bool cursor = st->cursor ? true : false;
213
214        uefi_call_wrapper(out->EnableCursor, 2, out, cursor);
215}
216
217static void efi_set_cursor(int x, int y, bool visible)
218{
219        SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
220
221        uefi_call_wrapper(out->SetCursorPosition, 3, out, x, y);
222}
223
224static void efi_scroll_up(uint8_t cols, uint8_t rows, uint8_t attribute)
225{
226        efi_write_char('\n', 0);
227        efi_write_char('\r', 0);
228}
229
230static void efi_get_mode(int *cols, int *rows)
231{
232        SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
233        UINTN c, r;
234
235        uefi_call_wrapper(out->QueryMode, 4, out, out->Mode->Mode, &c, &r);
236        *rows = r;
237        *cols = c;
238}
239
240static void efi_erase(int x0, int y0, int x1, int y1, uint8_t attribute)
241{
242        SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
243        int cols, rows;
244
245        efi_get_mode(&cols, &rows);
246
247        /*
248         * The BIOS version of this function has the ability to erase
249         * parts or all of the screen - the UEFI console doesn't
250         * support this so we just set the cursor position unless
251         * we're clearing the whole screen.
252         */
253        if (!x0 && y0 == (cols - 1)) {
254                /* Really clear the screen */
255                uefi_call_wrapper(out->ClearScreen, 1, out);
256        } else {
257                uefi_call_wrapper(out->SetCursorPosition, 3, out, y1, x1);
258        }
259}
260
261static void efi_text_mode(void)
262{
263}
264
265static void efi_get_cursor(uint8_t *x, uint8_t *y)
266{
267        SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
268        *x = out->Mode->CursorColumn;
269        *y = out->Mode->CursorRow;
270}
271
272struct output_ops efi_ops = {
273        .erase = efi_erase,
274        .write_char = efi_write_char,
275        .showcursor = efi_showcursor,
276        .set_cursor = efi_set_cursor,
277        .scroll_up = efi_scroll_up,
278        .get_mode = efi_get_mode,
279        .text_mode = efi_text_mode,
280        .get_cursor = efi_get_cursor,
281};
282
283char SubvolName[2];
284static inline EFI_MEMORY_DESCRIPTOR *
285get_memory_map(UINTN *nr_entries, UINTN *key, UINTN *desc_sz,
286               uint32_t *desc_ver)
287{
288        return LibMemoryMap(nr_entries, key, desc_sz, desc_ver);
289}
290
291
292int efi_scan_memory(scan_memory_callback_t callback, void *data)
293{
294        UINTN i, nr_entries, key, desc_sz;
295        UINTN buf, bufpos;
296        UINT32 desc_ver;
297        int rv = 0;
298
299        buf = (UINTN)get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
300        if (!buf)
301                return -1;
302        bufpos = buf;
303
304        for (i = 0; i < nr_entries; bufpos += desc_sz, i++) {
305                EFI_MEMORY_DESCRIPTOR *m;
306                UINT64 region_sz;
307                enum syslinux_memmap_types type;
308
309                m = (EFI_MEMORY_DESCRIPTOR *)bufpos;
310                region_sz = m->NumberOfPages * EFI_PAGE_SIZE;
311
312                switch (m->Type) {
313                case EfiConventionalMemory:
314                        type = SMT_FREE;
315                        break;
316                default:
317                        type = SMT_RESERVED;
318                        break;
319                }
320
321                rv = callback(data, m->PhysicalStart, region_sz, type);
322                if (rv)
323                        break;
324        }
325
326        FreePool((void *)buf);
327        return rv;
328}
329
330static struct syslinux_memscan efi_memscan = {
331    .func = efi_scan_memory,
332};
333
334extern uint16_t *bios_free_mem;
335void efi_init(void)
336{
337        /* XXX timer */
338        *bios_free_mem = 0;
339        syslinux_memscan_add(&efi_memscan);
340        mem_init();
341}
342
343char efi_getchar(char *hi)
344{
345        SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
346        EFI_INPUT_KEY key;
347        EFI_STATUS status;
348
349        do {
350                status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
351        } while (status == EFI_NOT_READY);
352
353        if (!key.ScanCode)
354                return (char)key.UnicodeChar;
355
356        /*
357         * We currently only handle scan codes that fit in 8 bits.
358         */
359        *hi = (char)key.ScanCode;
360        return 0;
361}
362
363int efi_pollchar(void)
364{
365        SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
366        EFI_STATUS status;
367
368        status = WaitForSingleEvent(in->WaitForKey, 1);
369        return status != EFI_TIMEOUT;
370}
371
372struct input_ops efi_iops = {
373        .getchar = efi_getchar,
374        .pollchar = efi_pollchar,
375};
376
377extern void efi_adv_init(void);
378extern int efi_adv_write(void);
379
380struct adv_ops efi_adv_ops = {
381        .init = efi_adv_init,
382        .write = efi_adv_write,
383};
384
385struct efi_info {
386        uint32_t load_signature;
387        uint32_t systab;
388        uint32_t desc_size;
389        uint32_t desc_version;
390        uint32_t memmap;
391        uint32_t memmap_size;
392        uint32_t systab_hi;
393        uint32_t memmap_hi;
394};
395
396#define E820MAX 128
397#define E820_RAM        1
398#define E820_RESERVED   2
399#define E820_ACPI       3
400#define E820_NVS        4
401#define E820_UNUSABLE   5
402
403#define BOOT_SIGNATURE  0xaa55
404#define SYSLINUX_EFILDR 0x30    /* Is this published value? */
405#define DEFAULT_TIMER_TICK_DURATION     500000 /* 500000 == 500000 * 100 * 10^-9 == 50 msec */
406#define DEFAULT_MSTIMER_INC             0x32    /* 50 msec */
407struct e820_entry {
408        uint64_t start;
409        uint64_t len;
410        uint32_t type;
411} __packed;
412
413struct boot_params {
414        struct screen_info screen_info;
415        uint8_t _pad[0x1c0 - sizeof(struct screen_info)];
416        struct efi_info efi;
417        uint8_t _pad2[8];
418        uint8_t e820_entries;
419        uint8_t _pad3[0x2d0 - 0x1e8 - sizeof(uint8_t)];
420        struct e820_entry e820_map[E820MAX];
421} __packed;
422
423/* Allocate boot parameter block aligned to page */
424#define BOOT_PARAM_BLKSIZE      EFI_SIZE_TO_PAGES(sizeof(struct boot_params)) * EFI_PAGE_SIZE
425
426/* Routines in support of efi boot loader were obtained from
427 * http://git.kernel.org/?p=boot/efilinux/efilinux.git:
428 * kernel_jump(), handover_jump(),
429 * emalloc()/efree, alloc_pages/free_pages
430 * allocate_pool()/free_pool()
431 * memory_map()
432 */
433extern void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start,
434                               struct boot_params *boot_params);
435#if __SIZEOF_POINTER__ == 4
436#define EFI_LOAD_SIG    "EL32"
437#elif __SIZEOF_POINTER__ == 8
438#define EFI_LOAD_SIG    "EL64"
439#else
440#error "unsupported architecture"
441#endif
442
443struct dt_desc {
444        uint16_t limit;
445        uint64_t *base;
446} __packed;
447
448struct dt_desc gdt = { 0x800, (uint64_t *)0 };
449struct dt_desc idt = { 0, 0 };
450
451static inline EFI_MEMORY_DESCRIPTOR *
452get_mem_desc(unsigned long memmap, UINTN desc_sz, int i)
453{
454        return (EFI_MEMORY_DESCRIPTOR *)(memmap + (i * desc_sz));
455}
456
457EFI_HANDLE image_handle;
458
459static inline UINT64 round_up(UINT64 x, UINT64 y)
460{
461        return (((x - 1) | (y - 1)) + 1);
462}
463
464static inline UINT64 round_down(UINT64 x, UINT64 y)
465{
466        return (x & ~(y - 1));
467}
468
469static void find_addr(EFI_PHYSICAL_ADDRESS *first,
470                      EFI_PHYSICAL_ADDRESS *last,
471                      EFI_PHYSICAL_ADDRESS min,
472                      EFI_PHYSICAL_ADDRESS max,
473                      size_t size, size_t align)
474{
475        EFI_MEMORY_DESCRIPTOR *map;
476        UINT32 desc_ver;
477        UINTN i, nr_entries, key, desc_sz;
478
479        map = get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
480        if (!map)
481                return;
482
483        for (i = 0; i < nr_entries; i++) {
484                EFI_MEMORY_DESCRIPTOR *m;
485                EFI_PHYSICAL_ADDRESS best;
486                UINT64 start, end;
487
488                m = get_mem_desc((unsigned long)map, desc_sz, i);
489                if (m->Type != EfiConventionalMemory)
490                        continue;
491
492                if (m->NumberOfPages < EFI_SIZE_TO_PAGES(size))
493                        continue;
494
495                start = m->PhysicalStart;
496                end = m->PhysicalStart + (m->NumberOfPages << EFI_PAGE_SHIFT);
497                if (first) {
498                        if (end < min)
499                                continue;
500
501                        /* What's the best address? */
502                        if (start < min && min < end)
503                                best = min;
504                        else
505                                best = m->PhysicalStart;
506
507                        start = round_up(best, align);
508                        if (start > max)
509                                continue;
510
511                        /* Have we run out of space in this region? */
512                        if (end < start || (start + size) > end)
513                                continue;
514
515                        if (start < *first)
516                                *first = start;
517                }
518
519                if (last) {
520                        if (start > max)
521                                continue;
522
523                        /* What's the best address? */
524                        if (start < max && max < end)
525                                best = max - size;
526                        else
527                                best = end - size;
528
529                        start = round_down(best, align);
530                        if (start < min || start < m->PhysicalStart)
531                                continue;
532
533                        if (start > *last)
534                                *last = start;
535                }
536        }
537
538        FreePool(map);
539}
540
541/**
542 * allocate_pages - Allocate memory pages from the system
543 * @atype: type of allocation to perform
544 * @mtype: type of memory to allocate
545 * @num_pages: number of contiguous 4KB pages to allocate
546 * @memory: used to return the address of allocated pages
547 *
548 * Allocate @num_pages physically contiguous pages from the system
549 * memory and return a pointer to the base of the allocation in
550 * @memory if the allocation succeeds. On success, the firmware memory
551 * map is updated accordingly.
552 *
553 * If @atype is AllocateAddress then, on input, @memory specifies the
554 * address at which to attempt to allocate the memory pages.
555 */
556static inline EFI_STATUS
557allocate_pages(EFI_ALLOCATE_TYPE atype, EFI_MEMORY_TYPE mtype,
558               UINTN num_pages, EFI_PHYSICAL_ADDRESS *memory)
559{
560        return uefi_call_wrapper(BS->AllocatePages, 4, atype,
561                                 mtype, num_pages, memory);
562}
563/**
564 * free_pages - Return memory allocated by allocate_pages() to the firmware
565 * @memory: physical base address of the page range to be freed
566 * @num_pages: number of contiguous 4KB pages to free
567 *
568 * On success, the firmware memory map is updated accordingly.
569 */
570static inline EFI_STATUS
571free_pages(EFI_PHYSICAL_ADDRESS memory, UINTN num_pages)
572{
573        return uefi_call_wrapper(BS->FreePages, 2, memory, num_pages);
574}
575
576static EFI_STATUS allocate_addr(EFI_PHYSICAL_ADDRESS *addr, size_t size)
577{
578        UINTN npages = EFI_SIZE_TO_PAGES(size);
579
580        return uefi_call_wrapper(BS->AllocatePages, 4,
581                                   AllocateAddress,
582                                   EfiLoaderData, npages,
583                                   addr);
584}
585/**
586 * allocate_pool - Allocate pool memory
587 * @type: the type of pool to allocate
588 * @size: number of bytes to allocate from pool of @type
589 * @buffer: used to return the address of allocated memory
590 *
591 * Allocate memory from pool of @type. If the pool needs more memory
592 * pages are allocated from EfiConventionalMemory in order to grow the
593 * pool.
594 *
595 * All allocations are eight-byte aligned.
596 */
597static inline EFI_STATUS
598allocate_pool(EFI_MEMORY_TYPE type, UINTN size, void **buffer)
599{
600        return uefi_call_wrapper(BS->AllocatePool, 3, type, size, buffer);
601}
602
603/**
604 * free_pool - Return pool memory to the system
605 * @buffer: the buffer to free
606 *
607 * Return @buffer to the system. The returned memory is marked as
608 * EfiConventionalMemory.
609 */
610static inline EFI_STATUS free_pool(void *buffer)
611{
612        return uefi_call_wrapper(BS->FreePool, 1, buffer);
613}
614
615static void free_addr(EFI_PHYSICAL_ADDRESS addr, size_t size)
616{
617        UINTN npages = EFI_SIZE_TO_PAGES(size);
618
619        uefi_call_wrapper(BS->FreePages, 2, addr, npages);
620}
621
622/* cancel the established timer */
623static EFI_STATUS cancel_timer(EFI_EVENT ev)
624{
625        return uefi_call_wrapper(BS->SetTimer, 3, ev, TimerCancel, 0);
626}
627
628/* Check if timer went off and update default timer counter */
629void timer_handler(EFI_EVENT ev, VOID *ctx)
630{
631        __ms_timer += DEFAULT_MSTIMER_INC;
632        ++__jiffies;
633}
634
635/* Setup a default periodic timer */
636static EFI_STATUS setup_default_timer(EFI_EVENT *ev)
637{
638        EFI_STATUS efi_status;
639
640        *ev = NULL;
641        efi_status = uefi_call_wrapper( BS->CreateEvent, 5, EVT_TIMER|EVT_NOTIFY_SIGNAL, TPL_NOTIFY, (EFI_EVENT_NOTIFY)timer_handler, NULL, ev);
642        if (efi_status == EFI_SUCCESS) {
643                efi_status = uefi_call_wrapper(BS->SetTimer, 3, *ev, TimerPeriodic, DEFAULT_TIMER_TICK_DURATION);
644        }
645        return efi_status;
646}
647
648/**
649 * emalloc - Allocate memory with a strict alignment requirement
650 * @size: size in bytes of the requested allocation
651 * @align: the required alignment of the allocation
652 * @addr: a pointer to the allocated address on success
653 *
654 * If we cannot satisfy @align we return 0.
655 */
656EFI_STATUS emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr)
657{
658        UINTN i, nr_entries, map_key, desc_size;
659        EFI_MEMORY_DESCRIPTOR *map_buf;
660        UINTN d;
661        UINT32 desc_version;
662        EFI_STATUS err;
663        UINTN nr_pages = EFI_SIZE_TO_PAGES(size);
664
665        map_buf = get_memory_map(&nr_entries, &map_key,
666                                 &desc_size, &desc_version);
667        if (!map_buf)
668                goto fail;
669
670        d = (UINTN)map_buf;
671
672        for (i = 0; i < nr_entries; i++, d += desc_size) {
673                EFI_MEMORY_DESCRIPTOR *desc;
674                EFI_PHYSICAL_ADDRESS start, end, aligned;
675
676                desc = (EFI_MEMORY_DESCRIPTOR *)d;
677                if (desc->Type != EfiConventionalMemory)
678                        continue;
679
680                if (desc->NumberOfPages < nr_pages)
681                        continue;
682
683                start = desc->PhysicalStart;
684                end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT);
685
686                /* Low-memory is super-precious! */
687                if (end <= 1 << 20)
688                        continue;
689                if (start < 1 << 20)
690                        start = (1 << 20);
691
692                aligned = (start + align -1) & ~(align -1);
693
694                if ((aligned + size) <= end) {
695                        err = allocate_pages(AllocateAddress, EfiLoaderData,
696                                             nr_pages, &aligned);
697                        if (err == EFI_SUCCESS) {
698                                *addr = aligned;
699                                break;
700                        }
701                }
702        }
703
704        if (i == nr_entries)
705                err = EFI_OUT_OF_RESOURCES;
706
707        free_pool(map_buf);
708fail:
709        return err;
710}
711/**
712 * efree - Return memory allocated with emalloc
713 * @memory: the address of the emalloc() allocation
714 * @size: the size of the allocation
715 */
716void efree(EFI_PHYSICAL_ADDRESS memory, UINTN size)
717{
718        UINTN nr_pages = EFI_SIZE_TO_PAGES(size);
719
720        free_pages(memory, nr_pages);
721}
722
723/*
724 * Check whether 'buf' contains a PE/COFF header and that the PE/COFF
725 * file can be executed by this architecture.
726 */
727static bool valid_pecoff_image(char *buf)
728{
729    struct pe_header {
730        uint16_t signature;
731        uint8_t _pad[0x3a];
732        uint32_t offset;
733    } *pehdr = (struct pe_header *)buf;
734    struct coff_header {
735        uint32_t signature;
736        uint16_t machine;
737    } *chdr;
738
739    if (pehdr->signature != 0x5a4d) {
740        dprintf("Invalid MS-DOS header signature\n");
741        return false;
742    }
743
744    if (!pehdr->offset || pehdr->offset > 512) {
745        dprintf("Invalid PE header offset\n");
746        return false;
747    }
748
749    chdr = (struct coff_header *)&buf[pehdr->offset];
750    if (chdr->signature != 0x4550) {
751        dprintf("Invalid PE header signature\n");
752        return false;
753    }
754
755#if defined(__x86_64__)
756    if (chdr->machine != 0x8664) {
757        dprintf("Invalid PE machine field\n");
758        return false;
759    }
760#else
761    if (chdr->machine != 0x14c) {
762        dprintf("Invalid PE machine field\n");
763        return false;
764    }
765#endif
766
767    return true;
768}
769
770/*
771 * Boot a Linux kernel using the EFI boot stub handover protocol.
772 *
773 * This function will not return to its caller if booting the kernel
774 * image succeeds. If booting the kernel image fails, a legacy boot
775 * method should be attempted.
776 */
777static void handover_boot(struct linux_header *hdr, struct boot_params *bp)
778{
779    unsigned long address = hdr->code32_start + hdr->handover_offset;
780    handover_func_t *func = efi_handover;
781
782    dprintf("Booting kernel using handover protocol\n");
783
784    /*
785     * Ensure that the kernel is a valid PE32(+) file and that the
786     * architecture of the file matches this version of Syslinux - we
787     * can't mix firmware and kernel bitness (e.g. 32-bit kernel on
788     * 64-bit EFI firmware) using the handover protocol.
789     */
790    if (!valid_pecoff_image((char *)hdr))
791        return;
792
793    if (hdr->version >= 0x20c) {
794        if (hdr->xloadflags & XLF_EFI_HANDOVER_32)
795            func = efi_handover_32;
796
797        if (hdr->xloadflags & XLF_EFI_HANDOVER_64)
798            func = efi_handover_64;
799    }
800
801    efi_console_restore();
802    func(image_handle, ST, bp, address);
803}
804
805static int check_linux_header(struct linux_header *hdr)
806{
807        if (hdr->version < 0x205)
808                hdr->relocatable_kernel = 0;
809
810        /* FIXME: check boot sector signature */
811        if (hdr->boot_flag != BOOT_SIGNATURE) {
812                printf("Invalid Boot signature 0x%x, bailing out\n", hdr->boot_flag);
813                return -1;
814        }
815
816        return 0;
817}
818
819static char *build_cmdline(char *str)
820{
821        EFI_PHYSICAL_ADDRESS addr;
822        EFI_STATUS status;
823        char *cmdline = NULL; /* internal, in efi_physical below 0x3FFFFFFF */
824
825        /*
826         * The kernel expects cmdline to be allocated pretty low,
827         * Documentation/x86/boot.txt says,
828         *
829         *      "The kernel command line can be located anywhere
830         *      between the end of the setup heap and 0xA0000"
831         */
832        addr = 0xA0000;
833        status = allocate_pages(AllocateMaxAddress, EfiLoaderData,
834                             EFI_SIZE_TO_PAGES(strlen(str) + 1),
835                             &addr);
836        if (status != EFI_SUCCESS) {
837                printf("Failed to allocate memory for kernel command line, bailing out\n");
838                return NULL;
839        }
840        cmdline = (char *)(UINTN)addr;
841        memcpy(cmdline, str, strlen(str) + 1);
842        return cmdline;
843}
844
845static int build_gdt(void)
846{
847        EFI_STATUS status;
848
849        /* Allocate gdt consistent with the alignment for architecture */
850        status = emalloc(gdt.limit, __SIZEOF_POINTER__ , (EFI_PHYSICAL_ADDRESS *)&gdt.base);
851        if (status != EFI_SUCCESS) {
852                printf("Failed to allocate memory for GDT, bailing out\n");
853                return -1;
854        }
855        memset(gdt.base, 0x0, gdt.limit);
856
857        /*
858         * 4Gb - (0x100000*0x1000 = 4Gb)
859         * base address=0
860         * code read/exec
861         * granularity=4096, 386 (+5th nibble of limit)
862         */
863        gdt.base[2] = 0x00cf9a000000ffff;
864
865        /*
866         * 4Gb - (0x100000*0x1000 = 4Gb)
867         * base address=0
868         * data read/write
869         * granularity=4096, 386 (+5th nibble of limit)
870         */
871        gdt.base[3] = 0x00cf92000000ffff;
872
873        /* Task segment value */
874        gdt.base[4] = 0x0080890000000000;
875
876        return 0;
877}
878
879/*
880 * Callers use ->ramdisk_size to check whether any memory was
881 * allocated (and therefore needs free'ing). The return value indicates
882 * hard error conditions, such as failing to alloc memory for the
883 * ramdisk image. Having no initramfs is not an error.
884 */
885static int handle_ramdisks(struct linux_header *hdr,
886                           struct initramfs *initramfs)
887{
888        EFI_PHYSICAL_ADDRESS last;
889        struct initramfs *ip;
890        EFI_STATUS status;
891        addr_t irf_size;
892        addr_t next_addr, len, pad;
893
894        hdr->ramdisk_image = 0;
895        hdr->ramdisk_size = 0;
896
897        /*
898         * Figure out the size of the initramfs, and where to put it.
899         * We should put it at the highest possible address which is
900         * <= hdr->initrd_addr_max, which fits the entire initramfs.
901         */
902        irf_size = initramfs_size(initramfs);   /* Handles initramfs == NULL */
903        if (!irf_size)
904                return 0;
905
906        last = 0;
907        find_addr(NULL, &last, 0x1000, hdr->initrd_addr_max,
908                  irf_size, INITRAMFS_MAX_ALIGN);
909        if (last)
910                status = allocate_addr(&last, irf_size);
911
912        if (!last || status != EFI_SUCCESS) {
913                printf("Failed to allocate initramfs memory, bailing out\n");
914                return -1;
915        }
916
917        hdr->ramdisk_image = (uint32_t)last;
918        hdr->ramdisk_size = irf_size;
919
920        /* Copy initramfs into allocated memory */
921        for (ip = initramfs->next; ip->len; ip = ip->next) {
922                len = ip->len;
923                next_addr = last + len;
924
925                /*
926                 * If this isn't the last entry, extend the
927                 * zero-pad region to enforce the alignment of
928                 * the next chunk.
929                 */
930                if (ip->next->len) {
931                        pad = -next_addr & (ip->next->align - 1);
932                        len += pad;
933                        next_addr += pad;
934                }
935
936                if (ip->data_len)
937                        memcpy((void *)(UINTN)last, ip->data, ip->data_len);
938
939                if (len > ip->data_len)
940                        memset((void *)(UINTN)(last + ip->data_len), 0,
941                               len - ip->data_len);
942
943                last = next_addr;
944        }
945        return 0;
946}
947
948static int exit_boot(struct boot_params *bp)
949{
950        struct e820_entry *e820buf, *e;
951        EFI_MEMORY_DESCRIPTOR *map;
952        EFI_STATUS status;
953        uint32_t e820_type;
954        UINTN i, nr_entries, key, desc_sz;
955        UINT32 desc_ver;
956
957        /* Build efi memory map */
958        map = get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
959        if (!map)
960                return -1;
961
962        bp->efi.memmap = (uint32_t)(unsigned long)map;
963        bp->efi.memmap_size = nr_entries * desc_sz;
964        bp->efi.systab = (uint32_t)(unsigned long)ST;
965        bp->efi.desc_size = desc_sz;
966        bp->efi.desc_version = desc_ver;
967#if defined(__x86_64__)
968        bp->efi.systab_hi = ((unsigned long)ST) >> 32;
969        bp->efi.memmap_hi = ((unsigned long)map) >> 32;
970#endif
971
972
973        /*
974         * Even though 'memmap' contains the memory map we provided
975         * previously in efi_scan_memory(), we should recalculate the
976         * e820 map because it will most likely have changed in the
977         * interim.
978         */
979        e = e820buf = bp->e820_map;
980        for (i = 0; i < nr_entries && i < E820MAX; i++) {
981                struct e820_entry *prev = NULL;
982
983                if (e > e820buf)
984                        prev = e - 1;
985
986                map = get_mem_desc(bp->efi.memmap, desc_sz, i);
987                e->start = map->PhysicalStart;
988                e->len = map->NumberOfPages << EFI_PAGE_SHIFT;
989
990                switch (map->Type) {
991                case EfiReservedMemoryType:
992                case EfiRuntimeServicesCode:
993                case EfiRuntimeServicesData:
994                case EfiMemoryMappedIO:
995                case EfiMemoryMappedIOPortSpace:
996                case EfiPalCode:
997                        e820_type = E820_RESERVED;
998                        break;
999
1000                case EfiUnusableMemory:
1001                        e820_type = E820_UNUSABLE;
1002                        break;
1003
1004                case EfiACPIReclaimMemory:
1005                        e820_type = E820_ACPI;
1006                        break;
1007
1008                case EfiLoaderCode:
1009                case EfiLoaderData:
1010                case EfiBootServicesCode:
1011                case EfiBootServicesData:
1012                case EfiConventionalMemory:
1013                        e820_type = E820_RAM;
1014                        break;
1015
1016                case EfiACPIMemoryNVS:
1017                        e820_type = E820_NVS;
1018                        break;
1019                default:
1020                        continue;
1021                }
1022
1023                e->type = e820_type;
1024
1025                /* Check for adjacent entries we can merge. */
1026                if (prev && (prev->start + prev->len) == e->start &&
1027                    prev->type == e->type)
1028                        prev->len += e->len;
1029                else
1030                        e++;
1031        }
1032
1033        bp->e820_entries = e - e820buf;
1034
1035        status = uefi_call_wrapper(BS->ExitBootServices, 2, image_handle, key);
1036        if (status != EFI_SUCCESS) {
1037                printf("Failed to exit boot services: 0x%016lx\n", status);
1038                FreePool(map);
1039                return -1;
1040        }
1041
1042        return 0;
1043}
1044
1045/* efi_boot_linux:
1046 * Boots the linux kernel using the image and parameters to boot with.
1047 * The EFI boot loader is reworked taking the cue from
1048 * http://git.kernel.org/?p=boot/efilinux/efilinux.git on the need to
1049 * cap key kernel data structures at * 0x3FFFFFFF.
1050 * The kernel image, kernel command line and boot parameter block are copied
1051 * into allocated memory areas that honor the address capping requirement
1052 * prior to kernel handoff.
1053 *
1054 * FIXME
1055 * Can we move this allocation requirement to com32 linux loader in order
1056 * to avoid double copying kernel image?
1057 */
1058int efi_boot_linux(void *kernel_buf, size_t kernel_size,
1059                   struct initramfs *initramfs,
1060                   struct setup_data *setup_data,
1061                   char *cmdline)
1062{
1063        struct linux_header *hdr;
1064        struct boot_params *bp;
1065        EFI_STATUS status;
1066        EFI_PHYSICAL_ADDRESS addr, pref_address, kernel_start = 0;
1067        UINT64 setup_sz, init_size = 0;
1068        char *_cmdline;
1069
1070        if (check_linux_header(kernel_buf))
1071                goto bail;
1072
1073        /* allocate for boot parameter block */
1074        addr = 0x3FFFFFFF;
1075        status = allocate_pages(AllocateMaxAddress, EfiLoaderData,
1076                             BOOT_PARAM_BLKSIZE, &addr);
1077        if (status != EFI_SUCCESS) {
1078                printf("Failed to allocate memory for kernel boot parameter block, bailing out\n");
1079                goto bail;
1080        }
1081
1082        bp = (struct boot_params *)(UINTN)addr;
1083
1084        memset((void *)bp, 0x0, BOOT_PARAM_BLKSIZE);
1085        /* Copy the first two sectors to boot_params */
1086        memcpy((char *)bp, kernel_buf, 2 * 512);
1087        hdr = (struct linux_header *)bp;
1088
1089        setup_sz = (hdr->setup_sects + 1) * 512;
1090        if (hdr->version >= 0x20a) {
1091                pref_address = hdr->pref_address;
1092                init_size = hdr->init_size;
1093        } else {
1094                pref_address = 0x100000;
1095
1096                /*
1097                 * We need to account for the fact that the kernel
1098                 * needs room for decompression, otherwise we could
1099                 * end up trashing other chunks of allocated memory.
1100                 */
1101                init_size = (kernel_size - setup_sz) * 3;
1102        }
1103        hdr->type_of_loader = SYSLINUX_EFILDR;  /* SYSLINUX boot loader module */
1104        _cmdline = build_cmdline(cmdline);
1105        if (!_cmdline)
1106                goto bail;
1107
1108        hdr->cmd_line_ptr = (UINT32)(UINTN)_cmdline;
1109
1110        addr = pref_address;
1111        status = allocate_pages(AllocateAddress, EfiLoaderData,
1112                             EFI_SIZE_TO_PAGES(init_size), &addr);
1113        if (status != EFI_SUCCESS) {
1114                /*
1115                 * We failed to allocate the preferred address, so
1116                 * just allocate some memory and hope for the best.
1117                 */
1118                if (!hdr->relocatable_kernel) {
1119                        printf("Cannot relocate kernel, bailing out\n");
1120                        goto bail;
1121                }
1122
1123                status = emalloc(init_size, hdr->kernel_alignment, &addr);
1124                if (status != EFI_SUCCESS) {
1125                        printf("Failed to allocate memory for kernel image, bailing out\n");
1126                        goto free_map;
1127                }
1128        }
1129        kernel_start = addr;
1130        /* FIXME: we copy the kernel into the physical memory allocated here
1131         * The syslinux kernel image load elsewhere could allocate the EFI memory from here
1132         * prior to copying kernel and save an extra copy
1133         */
1134        memcpy((void *)(UINTN)kernel_start, kernel_buf+setup_sz, kernel_size-setup_sz);
1135
1136        hdr->code32_start = (UINT32)((UINT64)kernel_start);
1137
1138        dprintf("efi_boot_linux: kernel_start 0x%x kernel_size 0x%x initramfs 0x%x setup_data 0x%x cmdline 0x%x\n",
1139        kernel_start, kernel_size, initramfs, setup_data, _cmdline);
1140
1141        if (handle_ramdisks(hdr, initramfs))
1142                goto free_map;
1143
1144        /* Attempt to use the handover protocol if available */
1145        if (hdr->version >= 0x20b && hdr->handover_offset)
1146                handover_boot(hdr, bp);
1147
1148        setup_screen(&bp->screen_info);
1149
1150        if (build_gdt())
1151                goto free_map;
1152
1153        dprintf("efi_boot_linux: setup_sects %d kernel_size %d\n", hdr->setup_sects, kernel_size);
1154
1155        efi_console_restore();
1156
1157        if (exit_boot(bp))
1158                goto free_map;
1159
1160        memcpy(&bp->efi.load_signature, EFI_LOAD_SIG, sizeof(uint32_t));
1161
1162        asm volatile ("lidt %0" :: "m" (idt));
1163        asm volatile ("lgdt %0" :: "m" (gdt));
1164
1165        kernel_jump(kernel_start, bp);
1166
1167        /* NOTREACHED */
1168
1169free_map:
1170        if (_cmdline)
1171                efree((EFI_PHYSICAL_ADDRESS)(unsigned long)_cmdline,
1172                      strlen(_cmdline) + 1);
1173
1174        if (bp)
1175                efree((EFI_PHYSICAL_ADDRESS)(unsigned long)bp,
1176                       BOOT_PARAM_BLKSIZE);
1177        if (kernel_start) efree(kernel_start, init_size);
1178        if (hdr->ramdisk_size)
1179                free_addr(hdr->ramdisk_image, hdr->ramdisk_size);
1180bail:
1181        return -1;
1182}
1183
1184extern struct disk *efi_disk_init(EFI_HANDLE);
1185extern void serialcfg(uint16_t *, uint16_t *, uint16_t *);
1186
1187extern struct vesa_ops efi_vesa_ops;
1188
1189struct mem_ops efi_mem_ops = {
1190        .malloc = efi_malloc,
1191        .realloc = efi_realloc,
1192        .free = efi_free,
1193};
1194
1195struct firmware efi_fw = {
1196        .init = efi_init,
1197        .disk_init = efi_disk_init,
1198        .o_ops = &efi_ops,
1199        .i_ops = &efi_iops,
1200        .get_serial_console_info = serialcfg,
1201        .adv_ops = &efi_adv_ops,
1202        .boot_linux = efi_boot_linux,
1203        .vesa = &efi_vesa_ops,
1204        .mem = &efi_mem_ops,
1205};
1206
1207static inline void syslinux_register_efi(void)
1208{
1209        firmware = &efi_fw;
1210}
1211
1212extern void init(void);
1213extern const struct fs_ops vfat_fs_ops;
1214extern const struct fs_ops pxe_fs_ops;
1215
1216char free_high_memory[4096];
1217
1218extern char __bss_start[];
1219extern char __bss_end[];
1220
1221static void efi_setcwd(CHAR16 *dp)
1222{
1223        CHAR16 *c16;
1224        char *c8;
1225        int i, j;
1226
1227        /* Search for the start of the last path component */
1228        for (i = StrLen(dp) - 1; i >= 0; i--) {
1229                if (dp[i] == '\\' || dp[i] == '/')
1230                        break;
1231        }
1232
1233        if (i < 0 || i > CURRENTDIR_MAX) {
1234                dp = L"\\";
1235                i = 1;
1236        }
1237
1238        c8 = CurrentDirName;
1239        c16 = dp;
1240
1241        for (j = 0; j < i; j++) {
1242                if (*c16 == '\\') {
1243                        *c8++ = '/';
1244                        c16++;
1245                } else
1246                        *c8++ = *c16++;
1247        }
1248
1249        *c8 = '\0';
1250}
1251
1252EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
1253{
1254        EFI_PXE_BASE_CODE *pxe;
1255        EFI_LOADED_IMAGE *info;
1256        EFI_STATUS status = EFI_SUCCESS;
1257        const struct fs_ops *ops[] = { NULL, NULL };
1258        unsigned long len = (unsigned long)__bss_end - (unsigned long)__bss_start;
1259        static struct efi_disk_private priv;
1260        SIMPLE_INPUT_INTERFACE *in;
1261        EFI_INPUT_KEY key;
1262        EFI_EVENT timer_ev;
1263
1264        memset(__bss_start, 0, len);
1265        InitializeLib(image, table);
1266
1267        image_handle = image;
1268        syslinux_register_efi();
1269
1270        efi_console_save();
1271        init();
1272
1273        status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
1274                                   &LoadedImageProtocol, (void **)&info);
1275        if (status != EFI_SUCCESS) {
1276                Print(L"Failed to lookup LoadedImageProtocol\n");
1277                goto out;
1278        }
1279
1280        status = uefi_call_wrapper(BS->HandleProtocol, 3, info->DeviceHandle,
1281                                   &PxeBaseCodeProtocol, (void **)&pxe);
1282        if (status != EFI_SUCCESS) {
1283                /*
1284                 * Use device handle to set up the volume root to
1285                 * proceed with ADV init.
1286                 */
1287                if (EFI_ERROR(efi_set_volroot(info->DeviceHandle))) {
1288                        Print(L"Failed to locate root device to prep for ");
1289                        Print(L"file operations & ADV initialization\n");
1290                        goto out;
1291                }
1292
1293                efi_derivative(SYSLINUX_FS_SYSLINUX);
1294                ops[0] = &vfat_fs_ops;
1295        } else {
1296                efi_derivative(SYSLINUX_FS_PXELINUX);
1297                ops[0] = &pxe_fs_ops;
1298        }
1299
1300        /* setup timer for boot menu system support */
1301        status = setup_default_timer(&timer_ev);
1302        if (status != EFI_SUCCESS) {
1303                Print(L"Failed to set up EFI timer support, bailing out\n");
1304                goto out;
1305        }
1306
1307        /* TODO: once all errors are captured in efi_errno, bail out if necessary */
1308
1309        priv.dev_handle = info->DeviceHandle;
1310
1311        /*
1312         * Set the current working directory, which should be the
1313         * directory that syslinux.efi resides in.
1314         */
1315        efi_setcwd(DevicePathToStr(info->FilePath));
1316
1317        fs_init(ops, (void *)&priv);
1318
1319        /*
1320         * There may be pending user input that wasn't processed by
1321         * whatever application invoked us. Consume and discard that
1322         * data now.
1323         */
1324        in = ST->ConIn;
1325        do {
1326                status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
1327        } while (status != EFI_NOT_READY);
1328
1329        if (!setjmp(load_error_buf))
1330                load_env32(NULL);
1331
1332        /* load_env32() failed.. cancel timer and bailout */
1333        status = cancel_timer(timer_ev);
1334        if (status != EFI_SUCCESS)
1335                Print(L"Failed to cancel EFI timer: %x\n", status);
1336
1337        /*
1338         * Tell the firmware that Syslinux failed to load.
1339         */
1340        status = EFI_LOAD_ERROR;
1341out:
1342        efi_console_restore();
1343        return status;
1344}
Note: See TracBrowser for help on using the repository browser.