3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
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.
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.
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.
25 #include "multiboot.h"
29 unsigned long next_module_load_base
= 0;
30 module_t
* pOpenModule
= NULL
;
33 BOOL
MultiBootLoadKernel(FILE *KernelImage
)
35 DWORD ImageHeaders
[2048];
37 DWORD dwHeaderChecksum
;
38 DWORD dwFileLoadOffset
;
44 * Load the first 8192 bytes of the kernel image
45 * so we can search for the multiboot header
47 ReadFile(KernelImage
, 8192, NULL
, ImageHeaders
);
50 * Now find the multiboot header and copy it
52 for (Idx
=0; Idx
<2048; Idx
++)
55 if (ImageHeaders
[Idx
] == MULTIBOOT_HEADER_MAGIC
)
57 // Yes, copy it and break out of this loop
58 memcpy(&mb_header
, &ImageHeaders
[Idx
], sizeof(multiboot_header_t
));
65 * If we reached the end of the 8192 bytes without
66 * finding the multiboot header then return error
70 MessageBox("No multiboot header found!");
74 /*printf("multiboot header:\n");
75 printf("0x%x\n", mb_header.magic);
76 printf("0x%x\n", mb_header.flags);
77 printf("0x%x\n", mb_header.checksum);
78 printf("0x%x\n", mb_header.header_addr);
79 printf("0x%x\n", mb_header.load_addr);
80 printf("0x%x\n", mb_header.load_end_addr);
81 printf("0x%x\n", mb_header.bss_end_addr);
82 printf("0x%x\n", mb_header.entry_addr);
86 * Calculate the checksum and make sure it matches
88 dwHeaderChecksum
= mb_header
.magic
;
89 dwHeaderChecksum
+= mb_header
.flags
;
90 dwHeaderChecksum
+= mb_header
.checksum
;
91 if (dwHeaderChecksum
!= 0)
93 MessageBox("Multiboot header checksum invalid!");
98 * Get the file offset, this should be 0, and move the file pointer
100 dwFileLoadOffset
= (Idx
* sizeof(DWORD
)) - (mb_header
.header_addr
- mb_header
.load_addr
);
101 SetFilePointer(KernelImage
, dwFileLoadOffset
);
104 * Load the file image
106 dwDataSize
= (mb_header
.load_end_addr
- mb_header
.load_addr
);
107 ReadFile(KernelImage
, dwDataSize
, NULL
, (void*)mb_header
.load_addr
);
110 * Initialize bss area
112 dwBssSize
= (mb_header
.bss_end_addr
- mb_header
.load_end_addr
);
113 memset((void*)mb_header
.load_end_addr
, 0, dwBssSize
);
115 next_module_load_base
= ROUND_UP(mb_header
.bss_end_addr
, /*PAGE_SIZE*/4096);
121 BOOL
MultiBootLoadModule(FILE *ModuleImage
, char *ModuleName
)
125 char* ModuleNameString
;
129 * Get current module data structure and module name string array
131 pModule
= &multiboot_modules
[mb_info
.mods_count
];
133 TempName
= strchr( ModuleName
, '\\' );
135 ModuleName
= TempName
+ 1;
138 ModuleNameString
= multiboot_module_strings
[mb_info
.mods_count
];
140 dwModuleSize
= GetFileSize(ModuleImage
);
141 pModule
->mod_start
= next_module_load_base
;
142 pModule
->mod_end
= next_module_load_base
+ dwModuleSize
;
143 strcpy(ModuleNameString
, ModuleName
);
144 pModule
->string
= (unsigned long)ModuleNameString
;
147 * Load the file image
149 ReadFile(ModuleImage
, dwModuleSize
, NULL
, (void*)next_module_load_base
);
151 next_module_load_base
= ROUND_UP(pModule
->mod_end
, /*PAGE_SIZE*/4096);
152 mb_info
.mods_count
++;
158 PVOID
MultiBootLoadModule(FILE *ModuleImage
, char *ModuleName
, PULONG ModuleSize
)
162 char* ModuleNameString
;
166 * Get current module data structure and module name string array
168 pModule
= &multiboot_modules
[mb_info
.mods_count
];
170 TempName
= strchr( ModuleName
, '\\' );
172 ModuleName
= TempName
+ 1;
175 ModuleNameString
= multiboot_module_strings
[mb_info
.mods_count
];
177 dwModuleSize
= GetFileSize(ModuleImage
);
178 pModule
->mod_start
= next_module_load_base
;
179 pModule
->mod_end
= next_module_load_base
+ dwModuleSize
;
180 strcpy(ModuleNameString
, ModuleName
);
181 pModule
->string
= (unsigned long)ModuleNameString
;
184 * Load the file image
186 ReadFile(ModuleImage
, dwModuleSize
, NULL
, (void*)next_module_load_base
);
188 next_module_load_base
= ROUND_UP(pModule
->mod_end
, /*PAGE_SIZE*/4096);
189 mb_info
.mods_count
++;
191 if (ModuleSize
!= NULL
)
192 *ModuleSize
= dwModuleSize
;
194 return((PVOID
)pModule
->mod_start
);
197 int GetBootPartition(char *OperatingSystemName
)
199 int BootPartitionNumber
= -1;
203 if (OpenSection(OperatingSystemName
, &SectionId
))
205 if (ReadSectionSettingByName(SectionId
, "BootPartition", value
, 1024))
207 BootPartitionNumber
= atoi(value
);
211 return BootPartitionNumber
;
215 PVOID
MultiBootCreateModule(char *ModuleName
)
218 char* ModuleNameString
;
221 * Get current module data structure and module name string array
223 pModule
= &multiboot_modules
[mb_info
.mods_count
];
225 ModuleNameString
= multiboot_module_strings
[mb_info
.mods_count
];
227 pModule
->mod_start
= next_module_load_base
;
228 pModule
->mod_end
= -1;
229 strcpy(ModuleNameString
, ModuleName
);
230 pModule
->string
= (unsigned long)ModuleNameString
;
232 pOpenModule
= pModule
;
234 return((PVOID
)pModule
->mod_start
);
238 BOOL
MultiBootCloseModule(PVOID ModuleBase
, DWORD dwModuleSize
)
242 if ((pOpenModule
!= NULL
) &&
243 ((module_t
*)ModuleBase
== pOpenModule
->mod_start
) &&
244 (pOpenModule
->mod_end
== -1))
246 pModule
= pOpenModule
;
247 pModule
->mod_end
= pModule
->mod_start
+ dwModuleSize
;
249 next_module_load_base
= ROUND_UP(pModule
->mod_end
, /*PAGE_SIZE*/4096);
250 mb_info
.mods_count
++;