1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include "loader_efi.h"
#include <stdbool.h>
#include <stddef.h>
EFI_SYSTEM_TABLE *e_st;
EFI_BOOT_SERVICES *e_bs;
EFI_RUNTIME_SERVICES *e_rt;
EFI_HANDLE e_image_handle;
EFI_LOADED_IMAGE_PROTOCOL *e_loaded_image;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *e_system_partition;
EFI_GRAPHICS_OUTPUT_PROTOCOL *e_graphics_output;
EFI_STATUS e_last_error;
extern int _text;
extern int _data;
static EFI_LOADED_IMAGE_PROTOCOL *open_loaded_image(void);
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *open_system_partition(void);
static EFI_GRAPHICS_OUTPUT_PROTOCOL *open_graphics_output(void);
EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
{
e_image_handle = image_handle;
e_st = system_table;
e_bs = e_st->BootServices;
e_rt = e_st->RuntimeServices;
InitializeLib(e_image_handle, e_st);
Print(L"loader starting\r\n");
e_loaded_image = open_loaded_image();
e_system_partition = open_system_partition();
e_graphics_output = open_graphics_output();
loader_main();
efi_exit(EFI_ABORTED);
}
noreturn void efi_exit(EFI_STATUS status)
{
if (EFI_ERROR(status))
{
Print(L"loader exited: %r\r\n", status);
}
e_bs->Exit(e_image_handle, status, 0, NULL);
while (true);
}
static EFI_LOADED_IMAGE_PROTOCOL *open_loaded_image(void)
{
Print(L"opening loaded image\r\n");
EFI_STATUS status;
EFI_LOADED_IMAGE_PROTOCOL *image;
status = e_bs->OpenProtocol(e_image_handle,
&LoadedImageProtocol,
(void **)&image,
e_image_handle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if (EFI_ERROR(status))
{
Print(L"failed opening loaded image\r\n");
efi_exit(status);
}
Print(L"image base: 0x%16.0x\r\n", image->ImageBase);
Print(L"image .text segment: 0x%16.0x\r\n", &_text);
Print(L"image .data segment: 0x%16.0x\r\n", &_data);
return image;
}
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *open_system_partition(void)
{
Print(L"opening system partition\r\n");
EFI_STATUS status;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *partition;
status = e_bs->OpenProtocol(e_loaded_image->DeviceHandle,
&FileSystemProtocol,
(void **)&partition,
e_image_handle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if (EFI_ERROR(status))
{
Print(L"failed opening system partition\r\n");
efi_exit(status);
}
Print(L"opened system partition\r\n");
return partition;
}
static EFI_GRAPHICS_OUTPUT_PROTOCOL *open_graphics_output(void)
{
EFI_STATUS status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *graphics;
Print(L"opening graphics output\r\n");
status = e_bs->LocateProtocol(&GraphicsOutputProtocol,
NULL,
(VOID **)&graphics);
if (EFI_ERROR(status))
{
Print(L"failed opening graphics output: %r\r\n", status);
return NULL;
}
Print(L"graphics output opened\r\n");
return graphics;
}
|