Mercurial > hg > Members > taiki > EFIKernel
comparison boot/bootx64.c @ 19:2fbe46f63d4c
separate source file.
author | taiki |
---|---|
date | Fri, 08 Feb 2013 19:12:05 +0900 |
parents | bd4c99e700e8 |
children | 5e184d4c01b8 |
comparison
equal
deleted
inserted
replaced
18:bd4c99e700e8 | 19:2fbe46f63d4c |
---|---|
5 * Author: Taiki TAIRA. | 5 * Author: Taiki TAIRA. |
6 */ | 6 */ |
7 | 7 |
8 #include "bootx64.h" | 8 #include "bootx64.h" |
9 #include "mach-o/mach_o.h" | 9 #include "mach-o/mach_o.h" |
10 | |
11 INTN | |
12 efi_error(CHAR16* error_massage, EFI_STATUS status) | |
13 { | |
14 Print(L"%s", error_massage); | |
15 if (status < 0) return ERROR; | |
16 return SUCCESS; | |
17 } | |
18 | |
19 EFI_STATUS | |
20 open(CHAR16 *name, EFI_FILE_HANDLE *fd, fs_t *fs) | |
21 { | |
22 EFI_STATUS status; | |
23 | |
24 if (name == NULL || fd == NULL) return EFI_INVALID_PARAMETER; | |
25 | |
26 status = uefi_call_wrapper(fs->volume->Open, 5, fs->volume, &fd, name, EFI_FILE_MODE_READ, (UINT64)0); | |
27 | |
28 return status; | |
29 } | |
30 | |
31 EFI_STATUS | |
32 close(fs_t *fs, EFI_FILE_HANDLE *fd) | |
33 { | |
34 if (fs == NULL || fd == NULL) return EFI_INVALID_PARAMETER; | |
35 | |
36 return uefi_call_wrapper(fs->volume->Close, 1, fd); | |
37 } | |
38 | |
39 EFI_STATUS | |
40 read(fs_t *fs, EFI_FILE_HANDLE *fd, VOID *buf, UINTN *size) | |
41 { | |
42 if (buf == NULL || fd == NULL || size == NULL) return EFI_INVALID_PARAMETER; | |
43 return uefi_call_wrapper(fs->volume->Read, 3, fd, size, buf); | |
44 } | |
45 | |
46 EFI_STATUS | |
47 seek(fs_t *fs, EFI_FILE_HANDLE fd, UINTN newpos) | |
48 { | |
49 if (newpos <= 0 || fd == NULL || fs == NULL) return EFI_INVALID_PARAMETER; | |
50 return uefi_call_wrapper(fs->volume->SetPosition, 2, fd, newpos); | |
51 } | |
52 | |
53 EFI_STATUS | |
54 config_fs_one(EFI_HANDLE dev, VOID *fs) | |
55 { | |
56 EFI_STATUS status; | |
57 EFI_FILE_IO_INTERFACE *volume; | |
58 EFI_FILE_HANDLE volume_fh; | |
59 EFI_GUID LocalFsProtocol = LOCALFS_PROTOCOL; | |
60 | |
61 status = uefi_call_wrapper(BS->HandleProtocol, 3, dev, &FileSystemProtocol, (VOID **)&volume); | |
62 if (EFI_ERROR(status)) return EFI_INVALID_PARAMETER; | |
63 | |
64 /* alloc */ | |
65 | |
66 status = uefi_call_wrapper(volume->OpenVolume, 2, volume, &volume_fh); | |
67 if (EFI_ERROR(status)) { | |
68 Print(L"Can not open volume.\n"); | |
69 return status; | |
70 } | |
71 Print(L"Open volume.\n"); | |
72 | |
73 fs_t *fs_tmp = (fs_t *)fs; | |
74 | |
75 SetMem(fs, sizeof(fs_t), 0); | |
76 | |
77 fs_tmp->dev = dev; | |
78 fs_tmp->volume = volume_fh; | |
79 | |
80 status = LibInstallProtocolInterfaces(&dev, &LocalFsProtocol, fs, NULL); | |
81 if (EFI_ERROR(status)) return status; | |
82 /* free */ | |
83 | |
84 return EFI_SUCCESS; | |
85 } | |
86 | |
87 EFI_STATUS | |
88 config_fs(EFI_HANDLE boot_handle, fs_t *fs, dev_tab_t *boot_dev) | |
89 { | |
90 UINTN size = 0; | |
91 UINTN i; | |
92 EFI_GUID *proto = NULL; | |
93 | |
94 Print(L"configure filesystems for all volume. \n"); | |
95 | |
96 uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &FileSystemProtocol, NULL, &size, NULL); | |
97 if (size == 0) return EFI_UNSUPPORTED; | |
98 | |
99 /* alloc */ | |
100 | |
101 dev_tab_t *dev_tab = NULL; // all devices | |
102 EFI_STATUS status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &FileSystemProtocol, NULL, &size, (VOID **)dev_tab); | |
103 if (status != EFI_SUCCESS) { | |
104 efi_error(L"can't get handler.\n", status); | |
105 /* free */ | |
106 return status; | |
107 } | |
108 | |
109 UINTN ndev = size / sizeof(EFI_HANDLE); | |
110 | |
111 for (i = 0; i < ndev; i++) { | |
112 VOID *fs = NULL; | |
113 config_fs_one(dev_tab[i].dev, &fs); | |
114 dev_tab[i].fs = fs; | |
115 } | |
116 | |
117 status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, proto, NULL, &size, NULL); | |
118 if (EFI_ERROR(status)) { | |
119 Print(L"No useable filesystem found.\n"); | |
120 return status; | |
121 } | |
122 | |
123 /* alloc */ | |
124 | |
125 SetMem(proto, sizeof(EFI_HANDLE), 0); | |
126 | |
127 uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &proto, NULL, &size, NULL); | |
128 | |
129 EFI_HANDLE *tab = NULL; | |
130 | |
131 SetMem(tab, size, 0); | |
132 | |
133 status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, proto, NULL, &size, tab); | |
134 if (status != EFI_SUCCESS) { | |
135 Print(L"faild to get handles\n"); | |
136 } | |
137 | |
138 size /= sizeof(EFI_HANDLE); | |
139 | |
140 UINTN idx = 0; | |
141 | |
142 for (i=0; i<size; i++) { | |
143 dev_tab[idx].dev = tab[i]; | |
144 if (tab[i] == boot_handle) boot_dev = dev_tab + idx; | |
145 idx++; | |
146 } | |
147 | |
148 return EFI_SUCCESS; | |
149 } | |
150 | |
151 EFI_STATUS | |
152 load(fs_t *fs, EFI_FILE_HANDLE *fd, CHAR16 *kname) | |
153 { | |
154 VOID *buf = NULL; | |
155 UINTN size; | |
156 read(fs ,fd, buf, &size); | |
157 //seek(fs ,fd); | |
158 | |
159 | |
160 | |
161 return EFI_SUCCESS; | |
162 } | |
163 | |
164 | 10 |
165 static inline void | 11 static inline void |
166 start_kernel() | 12 start_kernel() |
167 { | 13 { |
168 } | 14 } |
190 fs_t fs; | 36 fs_t fs; |
191 dev_tab_t boot_dev; | 37 dev_tab_t boot_dev; |
192 status = config_fs(info->DeviceHandle, &fs, &boot_dev); | 38 status = config_fs(info->DeviceHandle, &fs, &boot_dev); |
193 | 39 |
194 EFI_FILE_HANDLE fd; | 40 EFI_FILE_HANDLE fd; |
195 open(kname, &fd, &fs); | 41 open(&fs, &fd, kname); |
196 | 42 |
197 load(&fs, &fd, kname); | 43 load(&fs, &fd, kname); |
198 | 44 |
199 close(&fs, &fd); | 45 close(&fs, &fd); |
200 | 46 |
201 UINTN cookie = 0; | 47 UINTN cookie = 0; |
48 | |
202 uefi_call_wrapper(BS->ExitBootServices, 2, image, cookie); | 49 uefi_call_wrapper(BS->ExitBootServices, 2, image, cookie); |
203 | 50 |
204 start_kernel(); | 51 start_kernel(); |
205 | 52 |
206 status = EFI_SUCCESS; | 53 status = EFI_SUCCESS; |