- Fix most freeldr compilation issues, most notably:
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / setupldr.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #define _NTSYSTEM_
22 #include <freeldr.h>
23 #include <debug.h>
24
25 extern ULONG PageDirectoryStart;
26 extern ULONG PageDirectoryEnd;
27
28 ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
29 char reactos_kernel_cmdline[255]; // Command line passed to kernel
30 LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded for the kernel
31 char reactos_module_strings[64][256]; // Array to hold module names
32 reactos_mem_data_t reactos_mem_data;
33 extern char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE];
34 char szBootPath[256];
35 char szHalName[256];
36 CHAR SystemRoot[255];
37 extern ULONG_PTR KernelBase;
38 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
39
40 extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
41 extern BOOLEAN FrLdrLoadNlsFile(PCSTR szFileName, PCSTR szModuleName);
42
43 #define USE_UI
44
45 VOID LoadReactOSSetup(VOID)
46 {
47 ULONG i;
48 LPCSTR SourcePath;
49 LPCSTR LoadOptions, DbgLoadOptions = "";
50 LPCSTR sourcePaths[] = {
51 "", /* Only for floppy boot */
52 #if defined(_M_IX86)
53 "\\I386",
54 #elif defined(_M_MPPC)
55 "\\PPC",
56 #elif defined(_M_MRX000)
57 "\\MIPS",
58 #endif
59 "\\reactos",
60 NULL };
61 CHAR FileName[256];
62
63 HINF InfHandle;
64 ULONG ErrorLine;
65 INFCONTEXT InfContext;
66 PIMAGE_NT_HEADERS NtHeader;
67 PVOID LoadBase;
68 extern BOOLEAN FrLdrBootType;
69
70 /* Setup multiboot information structure */
71 LoaderBlock.CommandLine = reactos_kernel_cmdline;
72 LoaderBlock.PageDirectoryStart = (ULONG_PTR)&PageDirectoryStart;
73 LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
74 LoaderBlock.ModsCount = 0;
75 LoaderBlock.ModsAddr = reactos_modules;
76 LoaderBlock.MmapLength = (unsigned long)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
77 if (LoaderBlock.MmapLength)
78 {
79 #if defined (_M_IX86) || defined (_M_AMD64)
80 ULONG i;
81 #endif
82 LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
83 LoaderBlock.MmapAddr = (ULONG_PTR)&reactos_memory_map;
84 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
85 #if defined (_M_IX86) || defined (_M_AMD64)
86 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
87 {
88 if (BiosMemoryUsable == reactos_memory_map[i].type &&
89 0 == reactos_memory_map[i].base_addr_low)
90 {
91 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
92 if (640 < LoaderBlock.MemLower)
93 {
94 LoaderBlock.MemLower = 640;
95 }
96 }
97 if (BiosMemoryUsable == reactos_memory_map[i].type &&
98 reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
99 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
100 {
101 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
102 }
103 }
104 #endif
105 }
106
107 #ifdef USE_UI
108 SetupUiInitialize();
109 #endif
110 UiDrawStatusText("");
111
112 FrLdrBootType = TRUE;
113
114 /* Detect hardware */
115 UiDrawStatusText("Detecting hardware...");
116 LoaderBlock.ArchExtra = (ULONG_PTR)MachHwDetect();
117 UiDrawStatusText("");
118
119 /* set boot device */
120 MachDiskGetBootDevice(&LoaderBlock.BootDevice);
121
122 /* Open boot drive */
123 if (!FsOpenBootVolume())
124 {
125 UiMessageBox("Failed to open boot drive.");
126 return;
127 }
128
129 UiDrawStatusText("Loading txtsetup.sif...");
130 /* Open 'txtsetup.sif' */
131 for (i = MachDiskBootingFromFloppy() ? 0 : 1; ; i++)
132 {
133 SourcePath = sourcePaths[i];
134 if (!SourcePath)
135 {
136 printf("Failed to open 'txtsetup.sif'\n");
137 return;
138 }
139 sprintf(FileName,"%s\\txtsetup.sif", SourcePath);
140 if (InfOpenFile (&InfHandle, FileName, &ErrorLine))
141 break;
142 }
143 if (!*SourcePath)
144 SourcePath = "\\";
145
146 #if DBG
147 /* Get load options */
148 if (InfFindFirstLine (InfHandle,
149 "SetupData",
150 "DbgOsLoadOptions",
151 &InfContext))
152 {
153 if (!InfGetDataField (&InfContext, 1, &DbgLoadOptions))
154 DbgLoadOptions = "";
155 }
156 #endif
157 if (!strlen(DbgLoadOptions) && !InfFindFirstLine (InfHandle,
158 "SetupData",
159 "OsLoadOptions",
160 &InfContext))
161 {
162 printf("Failed to find 'SetupData/OsLoadOptions'\n");
163 return;
164 }
165
166 if (!InfGetDataField (&InfContext,
167 1,
168 &LoadOptions))
169 {
170 printf("Failed to get load options\n");
171 return;
172 }
173
174 /* Set kernel command line */
175 MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
176 strcat(strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
177 LoadOptions), DbgLoadOptions);
178
179 /* Setup the boot path and kernel path */
180 strcpy(szBootPath, SourcePath);
181
182 sprintf(SystemRoot,"%s\\", SourcePath);
183 sprintf(FileName,"%s\\ntoskrnl.exe", SourcePath);
184 sprintf(szHalName,"%s\\hal.dll", SourcePath);
185
186 /* Load the kernel */
187 LoadBase = FrLdrLoadImage(FileName, 5, 1);
188 if (!LoadBase)
189 {
190 DPRINT1("Loading the kernel failed!\n");
191 return;
192 }
193
194 /* Get the NT header, kernel base and kernel entry */
195 NtHeader = RtlImageNtHeader(LoadBase);
196 KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
197 KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
198 LoaderBlock.KernelBase = KernelBase;
199
200 /* Insert boot disk 2 */
201 if (MachDiskBootingFromFloppy())
202 {
203 UiMessageBox("Please insert \"ReactOS Boot Disk 2\" and press ENTER");
204
205 /* Open boot drive */
206 if (!FsOpenBootVolume())
207 {
208 UiMessageBox("Failed to open boot drive.");
209 return;
210 }
211
212 /* FIXME: check volume label or disk marker file */
213 }
214
215
216 /* Get ANSI codepage file */
217 if (!InfFindFirstLine (InfHandle,
218 "NLS",
219 "AnsiCodepage",
220 &InfContext))
221 {
222 printf("Failed to find 'NLS/AnsiCodepage'\n");
223 return;
224 }
225
226 if (!InfGetDataField (&InfContext,
227 1,
228 &LoadOptions))
229 {
230 printf("Failed to get load options\n");
231 return;
232 }
233
234 sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
235 /* Load ANSI codepage file */
236 if (!FrLdrLoadNlsFile(FileName, "ansi.nls"))
237 {
238 UiMessageBox("Failed to load the ANSI codepage file.");
239 return;
240 }
241
242 /* Get OEM codepage file */
243 if (!InfFindFirstLine (InfHandle,
244 "NLS",
245 "OemCodepage",
246 &InfContext))
247 {
248 printf("Failed to find 'NLS/AnsiCodepage'\n");
249 return;
250 }
251
252 if (!InfGetDataField (&InfContext,
253 1,
254 &LoadOptions))
255 {
256 printf("Failed to get load options\n");
257 return;
258 }
259
260 sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
261 /* Load OEM codepage file */
262 if (!FrLdrLoadNlsFile(FileName, "oem.nls"))
263 {
264 UiMessageBox("Failed to load the OEM codepage file.");
265 return;
266 }
267
268 /* Get Unicode Casemap file */
269 if (!InfFindFirstLine (InfHandle,
270 "NLS",
271 "UnicodeCasetable",
272 &InfContext))
273 {
274 printf("Failed to find 'NLS/AnsiCodepage'\n");
275 return;
276 }
277
278 if (!InfGetDataField (&InfContext,
279 1,
280 &LoadOptions))
281 {
282 printf("Failed to get load options\n");
283 return;
284 }
285
286 sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
287 /* Load Unicode casemap file */
288 if (!FrLdrLoadNlsFile(FileName, "casemap.nls"))
289 {
290 UiMessageBox("Failed to load the Unicode casemap file.");
291 return;
292 }
293
294 /* Load additional files specified in txtsetup.inf */
295 if (InfFindFirstLine(InfHandle,
296 "SourceDisksFiles",
297 NULL,
298 &InfContext))
299 {
300 do
301 {
302 LPCSTR Media, DriverName;
303 if (InfGetDataField(&InfContext, 7, &Media) &&
304 InfGetDataField(&InfContext, 0, &DriverName))
305 {
306 if (strcmp(Media, "x") == 0)
307 {
308 if (!FrLdrLoadDriver((PCHAR)DriverName,0))
309 {
310 DPRINTM(DPRINT_WARNING, "could not load %s, %s\n", SourcePath, DriverName);
311 return;
312 }
313 }
314 }
315 } while (InfFindNextLine(&InfContext, &InfContext));
316 }
317
318 UiUnInitialize("Booting ReactOS...");
319
320 //
321 // Perform architecture-specific pre-boot configuration
322 //
323 MachPrepareForReactOS(TRUE);
324
325 //
326 // Setup paging and jump to kernel
327 //
328 FrLdrStartup(0x2badb002);
329 }
330
331 /* EOF */