BIOS Int 13h Extensions Support
[reactos.git] / freeldr / freeldr / reactos.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20
21 #include "freeldr.h"
22 #include "asmcode.h"
23 #include "reactos.h"
24 #include "stdlib.h"
25 #include "fs.h"
26 #include "tui.h"
27 #include "multiboot.h"
28 #include "arcname.h"
29 #include "memory.h"
30 #include "parseini.h"
31
32 BOOL LoadReactOSKernel(PUCHAR OperatingSystemName);
33 BOOL LoadReactOSDrivers(PUCHAR OperatingSystemName);
34
35 void LoadAndBootReactOS(PUCHAR OperatingSystemName)
36 {
37 PFILE FilePointer;
38 char name[1024];
39 char value[1024];
40 char szFileName[1024];
41 char szBootPath[256];
42 int i;
43 int nNumDriverFiles=0;
44 int nNumFilesLoaded=0;
45 char MsgBuffer[256];
46 ULONG SectionId;
47
48 //
49 // Open the operating system section
50 // specified in the .ini file
51 //
52 if (!OpenSection(OperatingSystemName, &SectionId))
53 {
54 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
55 MessageBox(MsgBuffer);
56 return;
57 }
58
59 /*
60 * Setup multiboot information structure
61 */
62 mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
63 mb_info.mem_lower = GetConventionalMemorySize();
64 mb_info.mem_upper = GetExtendedMemorySize();
65 mb_info.boot_device = 0xffffffff;
66 mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
67 mb_info.mods_count = 0;
68 mb_info.mods_addr = (unsigned long)multiboot_modules;
69 mb_info.mmap_length = GetBiosMemoryMap(&multiboot_memory_map);
70 if (mb_info.mmap_length)
71 {
72 mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
73 mb_info.flags |= MB_INFO_FLAG_MEMORY_MAP;
74 //printf("memory map length: %d\n", mb_info.mmap_length);
75 //printf("dumping memory map:\n");
76 //for (i=0; i<(mb_info.mmap_length / 4); i++)
77 //{
78 // printf("0x%x\n", ((unsigned long *)&multiboot_memory_map)[i]);
79 //}
80 //getch();
81 }
82 //printf("low_mem = %d\n", mb_info.mem_lower);
83 //printf("high_mem = %d\n", mb_info.mem_upper);
84
85 /*
86 * Make sure the system path is set in the .ini file
87 */
88 if (!ReadSectionSettingByName(SectionId, "SystemPath", value, 1024))
89 {
90 MessageBox("System path not specified for selected operating system.");
91 return;
92 }
93
94 /*
95 * Verify system path
96 */
97 if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
98 {
99 sprintf(MsgBuffer,"Invalid system path: '%s'", value);
100 MessageBox(MsgBuffer);
101 return;
102 }
103
104 /* set boot drive and partition */
105 ((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
106 ((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
107
108 /* copy ARC path into kernel command line */
109 strcpy(multiboot_kernel_cmdline, value);
110
111 /*
112 * Read the optional kernel parameters (if any)
113 */
114 if (ReadSectionSettingByName(SectionId, "Options", value, 1024))
115 {
116 strcat(multiboot_kernel_cmdline, " ");
117 strcat(multiboot_kernel_cmdline, value);
118 }
119
120 /* append a backslash */
121 if ((strlen(szBootPath)==0) ||
122 szBootPath[strlen(szBootPath)] != '\\')
123 strcat(szBootPath, "\\");
124
125 /*
126 * Find the kernel image name
127 */
128 if(!ReadSectionSettingByName(SectionId, "Kernel", value, 1024))
129 {
130 MessageBox("Kernel image file not specified for selected operating system.");
131 return;
132 }
133
134 DrawBackdrop();
135
136 DrawStatusText(" Loading...");
137 DrawProgressBar(0);
138
139 /*
140 * Try to open boot drive
141 */
142 if (!OpenDiskDrive(BootDrive, BootPartition))
143 {
144 MessageBox("Failed to open boot drive.");
145 return;
146 }
147
148 /*
149 * Parse the ini file and count the kernel and drivers
150 */
151 for (i=1; i<=GetNumSectionItems(SectionId); i++)
152 {
153 /*
154 * Read the setting and check if it's a driver
155 */
156 ReadSectionSettingByNumber(SectionId, i, name, 1024, value, 1024);
157 if ((stricmp(name, "Kernel") == 0) || (stricmp(name, "Driver") == 0))
158 nNumDriverFiles++;
159 }
160
161 /*
162 * Find the kernel image name
163 * and try to load the kernel off the disk
164 */
165 if(ReadSectionSettingByName(SectionId, "Kernel", value, 1024))
166 {
167 /*
168 * Set the name and try to open the PE image
169 */
170 //strcpy(szFileName, szBootPath);
171 //strcat(szFileName, value);
172 strcpy(szFileName, value);
173
174 FilePointer = OpenFile(szFileName);
175 if (FilePointer == NULL)
176 {
177 strcat(value, " not found.");
178 MessageBox(value);
179 return;
180 }
181
182 /*
183 * Update the status bar with the current file
184 */
185 strcpy(name, " Reading ");
186 strcat(name, value);
187 while (strlen(name) < 80)
188 strcat(name, " ");
189 DrawStatusText(name);
190
191 /*
192 * Load the kernel image
193 */
194 MultiBootLoadKernel(FilePointer);
195
196 nNumFilesLoaded++;
197 DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
198 }
199
200 /*
201 * Parse the ini file and load the kernel and
202 * load all the drivers specified
203 */
204 for (i=1; i<=GetNumSectionItems(SectionId); i++)
205 {
206 /*
207 * Read the setting and check if it's a driver
208 */
209 ReadSectionSettingByNumber(SectionId, i, name, 1024, value, 1024);
210 if (stricmp(name, "Driver") == 0)
211 {
212 /*
213 * Set the name and try to open the PE image
214 */
215 //strcpy(szFileName, szBootPath);
216 //strcat(szFileName, value);
217 strcpy(szFileName, value);
218
219 FilePointer = OpenFile(szFileName);
220 if (FilePointer == NULL)
221 {
222 strcat(value, " not found.");
223 MessageBox(value);
224 return;
225 }
226
227 /*
228 * Update the status bar with the current file
229 */
230 strcpy(name, " Reading ");
231 strcat(name, value);
232 while (strlen(name) < 80)
233 strcat(name, " ");
234 DrawStatusText(name);
235
236 /*
237 * Load the driver
238 */
239 MultiBootLoadModule(FilePointer, szFileName);
240
241
242 nNumFilesLoaded++;
243 DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
244 }
245 else if (stricmp(name, "MessageBox") == 0)
246 {
247 DrawStatusText(" Press ENTER to continue");
248 MessageBox(value);
249 }
250 else if (stricmp(name, "MessageLine") == 0)
251 MessageLine(value);
252 else if (stricmp(name, "ReOpenBootDrive") == 0)
253 {
254 if (!OpenDiskDrive(BootDrive, BootPartition))
255 {
256 MessageBox("Failed to open boot drive.");
257 return;
258 }
259 }
260 }
261
262 /*
263 * Clear the screen and redraw the backdrop and status bar
264 */
265 DrawBackdrop();
266 DrawStatusText(" Press any key to boot");
267
268 /*
269 * Wait for user
270 */
271 strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
272 strcat(name, OperatingSystemName);
273 strcat(name, ".");
274 //MessageBox(name);
275
276 RestoreScreen(ScreenBuffer);
277
278 /*
279 * Now boot the kernel
280 */
281 stop_floppy();
282 boot_reactos();
283 }
284