78b11a830287f1bc419fb70b866edabf341d29f0
[reactos.git] / freeldr / freeldr / multiboot.c
1 /*
2 * FreeLoader
3 * Copyright (C) 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 "stdlib.h"
24 #include "fs.h"
25 #include "multiboot.h"
26 #include "tui.h"
27 #include "parseini.h"
28
29 unsigned long next_module_load_base = 0;
30
31 BOOL MultiBootLoadKernel(FILE *KernelImage)
32 {
33 DWORD ImageHeaders[2048];
34 int Idx;
35 DWORD dwHeaderChecksum;
36 DWORD dwFileLoadOffset;
37 DWORD dwDataSize;
38 DWORD dwBssSize;
39 ULONG BytesRead;
40
41 /*
42 * Load the first 8192 bytes of the kernel image
43 * so we can search for the multiboot header
44 */
45 ReadFile(KernelImage, 8192, NULL, ImageHeaders);
46
47 /*
48 * Now find the multiboot header and copy it
49 */
50 for (Idx=0; Idx<2048; Idx++)
51 {
52 // Did we find it?
53 if (ImageHeaders[Idx] == MULTIBOOT_HEADER_MAGIC)
54 {
55 // Yes, copy it and break out of this loop
56 memcpy(&mb_header, &ImageHeaders[Idx], sizeof(multiboot_header_t));
57
58 break;
59 }
60 }
61
62 /*
63 * If we reached the end of the 8192 bytes without
64 * finding the multiboot header then return error
65 */
66 if (Idx == 2048)
67 {
68 MessageBox("No multiboot header found!");
69 return FALSE;
70 }
71
72 /*printf("multiboot header:\n");
73 printf("0x%x\n", mb_header.magic);
74 printf("0x%x\n", mb_header.flags);
75 printf("0x%x\n", mb_header.checksum);
76 printf("0x%x\n", mb_header.header_addr);
77 printf("0x%x\n", mb_header.load_addr);
78 printf("0x%x\n", mb_header.load_end_addr);
79 printf("0x%x\n", mb_header.bss_end_addr);
80 printf("0x%x\n", mb_header.entry_addr);
81 getch();*/
82
83 /*
84 * Calculate the checksum and make sure it matches
85 */
86 dwHeaderChecksum = mb_header.magic;
87 dwHeaderChecksum += mb_header.flags;
88 dwHeaderChecksum += mb_header.checksum;
89 if (dwHeaderChecksum != 0)
90 {
91 MessageBox("Multiboot header checksum invalid!");
92 return FALSE;
93 }
94
95 /*
96 * Get the file offset, this should be 0, and move the file pointer
97 */
98 dwFileLoadOffset = (Idx * sizeof(DWORD)) - (mb_header.header_addr - mb_header.load_addr);
99 SetFilePointer(KernelImage, dwFileLoadOffset);
100
101 /*
102 * Load the file image
103 */
104 dwDataSize = (mb_header.load_end_addr - mb_header.load_addr);
105 ReadFile(KernelImage, dwDataSize, NULL, (void*)mb_header.load_addr);
106
107 /*
108 * Initialize bss area
109 */
110 dwBssSize = (mb_header.bss_end_addr - mb_header.load_end_addr);
111 memset((void*)mb_header.load_end_addr, 0, dwBssSize);
112
113 next_module_load_base = ROUND_UP(mb_header.bss_end_addr, /*PAGE_SIZE*/4096);
114
115 return TRUE;
116 }
117
118 BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
119 {
120 DWORD dwModuleSize;
121 module_t* pModule;
122 char* ModuleNameString;
123 char * TempName;
124
125 /*
126 * Get current module data structure and module name string array
127 */
128 pModule = &multiboot_modules[mb_info.mods_count];
129 do {
130 TempName = strchr( ModuleName, '\\' );
131 if( TempName )
132 ModuleName = TempName + 1;
133 } while( TempName );
134
135 ModuleNameString = multiboot_module_strings[mb_info.mods_count];
136
137 dwModuleSize = GetFileSize(ModuleImage);
138 pModule->mod_start = next_module_load_base;
139 pModule->mod_end = next_module_load_base + dwModuleSize;
140 strcpy(ModuleNameString, ModuleName);
141 pModule->string = (unsigned long)ModuleNameString;
142
143 /*
144 * Load the file image
145 */
146 ReadFile(ModuleImage, dwModuleSize, NULL, (void*)next_module_load_base);
147
148 next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
149 mb_info.mods_count++;
150
151 return TRUE;
152 }
153
154 int GetBootPartition(char *OperatingSystemName)
155 {
156 int BootPartitionNumber = -1;
157 char value[1024];
158 ULONG SectionId;
159
160 if (OpenSection(OperatingSystemName, &SectionId))
161 {
162 if (ReadSectionSettingByName(SectionId, "BootPartition", value, 1024))
163 {
164 BootPartitionNumber = atoi(value);
165 }
166 }
167
168 return BootPartitionNumber;
169 }