- Update address of Free Software Foundation.
[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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 extern CHAR szBootPath[255];
29 extern CHAR SystemRoot[255];
30 extern CHAR szHalName[255];
31
32 extern char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE];
33 extern ULONG_PTR KernelBase;
34 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
35
36 extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
37 extern BOOLEAN FrLdrLoadNlsFile(PCSTR szFileName, PCSTR szModuleName);
38
39 #define USE_UI
40
41 VOID LoadReactOSSetup(VOID)
42 {
43 ULONG i;
44 LPCSTR SourcePath;
45 LPCSTR LoadOptions, DbgLoadOptions = "";
46 BOOLEAN BootFromFloppy;
47 LPCSTR sourcePaths[] = {
48 "", /* Only for floppy boot */
49 #if defined(_M_IX86)
50 "\\I386",
51 #elif defined(_M_MPPC)
52 "\\PPC",
53 #elif defined(_M_MRX000)
54 "\\MIPS",
55 #endif
56 "\\reactos",
57 NULL };
58 CHAR FileName[256];
59
60 HINF InfHandle;
61 ULONG ErrorLine;
62 INFCONTEXT InfContext;
63 PIMAGE_NT_HEADERS NtHeader;
64 PVOID LoadBase;
65 extern BOOLEAN FrLdrBootType;
66
67 /* Setup multiboot information structure */
68 LoaderBlock.CommandLine = reactos_kernel_cmdline;
69 LoaderBlock.PageDirectoryStart = (ULONG_PTR)&PageDirectoryStart;
70 LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
71 LoaderBlock.ModsCount = 0;
72 LoaderBlock.ModsAddr = reactos_modules;
73 LoaderBlock.MmapLength = (unsigned long)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
74 if (LoaderBlock.MmapLength)
75 {
76 #if defined (_M_IX86) || defined (_M_AMD64)
77 ULONG i;
78 #endif
79 LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
80 LoaderBlock.MmapAddr = (ULONG_PTR)&reactos_memory_map;
81 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
82 #if defined (_M_IX86) || defined (_M_AMD64)
83 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
84 {
85 if (BiosMemoryUsable == reactos_memory_map[i].type &&
86 0 == reactos_memory_map[i].base_addr_low)
87 {
88 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
89 if (640 < LoaderBlock.MemLower)
90 {
91 LoaderBlock.MemLower = 640;
92 }
93 }
94 if (BiosMemoryUsable == reactos_memory_map[i].type &&
95 reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
96 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
97 {
98 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
99 }
100 }
101 #endif
102 }
103
104 #ifdef USE_UI
105 SetupUiInitialize();
106 #endif
107 UiDrawStatusText("");
108
109 FrLdrBootType = TRUE;
110
111 /* Detect hardware */
112 UiDrawStatusText("Detecting hardware...");
113 LoaderBlock.ArchExtra = (ULONG_PTR)MachHwDetect();
114 UiDrawStatusText("");
115
116 /* Check if we booted from floppy */
117 MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
118 BootFromFloppy = strstr(reactos_kernel_cmdline, "fdisk") != NULL;
119
120 UiDrawStatusText("Loading txtsetup.sif...");
121 /* Open 'txtsetup.sif' */
122 for (i = BootFromFloppy ? 0 : 1; ; i++)
123 {
124 SourcePath = sourcePaths[i];
125 if (!SourcePath)
126 {
127 printf("Failed to open 'txtsetup.sif'\n");
128 return;
129 }
130 sprintf(FileName,"%s\\txtsetup.sif", SourcePath);
131 if (InfOpenFile (&InfHandle, FileName, &ErrorLine))
132 break;
133 }
134 if (!*SourcePath)
135 SourcePath = "\\";
136
137 #if DBG
138 /* Get load options */
139 if (InfFindFirstLine (InfHandle,
140 "SetupData",
141 "DbgOsLoadOptions",
142 &InfContext))
143 {
144 if (!InfGetDataField (&InfContext, 1, &DbgLoadOptions))
145 DbgLoadOptions = "";
146 }
147 #endif
148 if (!strlen(DbgLoadOptions) && !InfFindFirstLine (InfHandle,
149 "SetupData",
150 "OsLoadOptions",
151 &InfContext))
152 {
153 printf("Failed to find 'SetupData/OsLoadOptions'\n");
154 return;
155 }
156
157 if (!InfGetDataField (&InfContext,
158 1,
159 &LoadOptions))
160 {
161 printf("Failed to get load options\n");
162 return;
163 }
164
165 /* Set kernel command line */
166 MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
167 strcat(strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
168 LoadOptions), DbgLoadOptions);
169
170 /* Setup the boot path and kernel path */
171 strcpy(szBootPath, SourcePath);
172
173 sprintf(SystemRoot,"%s\\", SourcePath);
174 sprintf(FileName,"%s\\ntoskrnl.exe", SourcePath);
175 sprintf(szHalName,"%s\\hal.dll", SourcePath);
176
177 /* Load the kernel */
178 LoadBase = FrLdrLoadImage(FileName, 5, 1);
179 if (!LoadBase)
180 {
181 DPRINT1("Loading the kernel failed!\n");
182 return;
183 }
184
185 /* Get the NT header, kernel base and kernel entry */
186 NtHeader = RtlImageNtHeader(LoadBase);
187 KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
188 KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
189 LoaderBlock.KernelBase = KernelBase;
190
191 /* Insert boot disk 2 */
192 if (BootFromFloppy)
193 {
194 UiMessageBox("Please insert \"ReactOS Boot Disk 2\" and press ENTER");
195
196 /* FIXME: check volume label or disk marker file */
197 }
198
199
200 /* Get ANSI codepage file */
201 if (!InfFindFirstLine (InfHandle,
202 "NLS",
203 "AnsiCodepage",
204 &InfContext))
205 {
206 printf("Failed to find 'NLS/AnsiCodepage'\n");
207 return;
208 }
209
210 if (!InfGetDataField (&InfContext,
211 1,
212 &LoadOptions))
213 {
214 printf("Failed to get load options\n");
215 return;
216 }
217
218 sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
219 /* Load ANSI codepage file */
220 if (!FrLdrLoadNlsFile(FileName, "ansi.nls"))
221 {
222 UiMessageBox("Failed to load the ANSI codepage file.");
223 return;
224 }
225
226 /* Get OEM codepage file */
227 if (!InfFindFirstLine (InfHandle,
228 "NLS",
229 "OemCodepage",
230 &InfContext))
231 {
232 printf("Failed to find 'NLS/AnsiCodepage'\n");
233 return;
234 }
235
236 if (!InfGetDataField (&InfContext,
237 1,
238 &LoadOptions))
239 {
240 printf("Failed to get load options\n");
241 return;
242 }
243
244 sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
245 /* Load OEM codepage file */
246 if (!FrLdrLoadNlsFile(FileName, "oem.nls"))
247 {
248 UiMessageBox("Failed to load the OEM codepage file.");
249 return;
250 }
251
252 /* Get Unicode Casemap file */
253 if (!InfFindFirstLine (InfHandle,
254 "NLS",
255 "UnicodeCasetable",
256 &InfContext))
257 {
258 printf("Failed to find 'NLS/AnsiCodepage'\n");
259 return;
260 }
261
262 if (!InfGetDataField (&InfContext,
263 1,
264 &LoadOptions))
265 {
266 printf("Failed to get load options\n");
267 return;
268 }
269
270 sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
271 /* Load Unicode casemap file */
272 if (!FrLdrLoadNlsFile(FileName, "casemap.nls"))
273 {
274 UiMessageBox("Failed to load the Unicode casemap file.");
275 return;
276 }
277
278 /* Load additional files specified in txtsetup.inf */
279 if (InfFindFirstLine(InfHandle,
280 "SourceDisksFiles",
281 NULL,
282 &InfContext))
283 {
284 do
285 {
286 LPCSTR Media, DriverName;
287 if (InfGetDataField(&InfContext, 7, &Media) &&
288 InfGetDataField(&InfContext, 0, &DriverName))
289 {
290 if (strcmp(Media, "x") == 0)
291 {
292 if (!FrLdrLoadDriver((PCHAR)DriverName,0))
293 {
294 DPRINTM(DPRINT_WARNING, "could not load %s, %s\n", SourcePath, DriverName);
295 return;
296 }
297 }
298 }
299 } while (InfFindNextLine(&InfContext, &InfContext));
300 }
301
302 UiUnInitialize("Booting ReactOS...");
303
304 //
305 // Perform architecture-specific pre-boot configuration
306 //
307 MachPrepareForReactOS(TRUE);
308
309 //
310 // Setup paging and jump to kernel
311 //
312 FrLdrStartup(0x2badb002);
313 }
314
315 /* EOF */