3 * Copyright (C) 1998-2003 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>
30 unsigned long next_module_load_base
= 0;
31 module_t
* pOpenModule
= NULL
;
34 BOOL
MultiBootLoadKernel(FILE *KernelImage
)
43 // Allocate 8192 bytes for multiboot header
44 ImageHeaders
= (U32
*)MmAllocateMemory(8192);
45 if (ImageHeaders
== NULL
)
51 * Load the first 8192 bytes of the kernel image
52 * so we can search for the multiboot header
54 if (!FsReadFile(KernelImage
, 8192, NULL
, ImageHeaders
))
56 MmFreeMemory(ImageHeaders
);
61 * Now find the multiboot header and copy it
63 for (Idx
=0; Idx
<2048; Idx
++)
66 if (ImageHeaders
[Idx
] == MULTIBOOT_HEADER_MAGIC
)
68 // Yes, copy it and break out of this loop
69 memcpy(&mb_header
, &ImageHeaders
[Idx
], sizeof(multiboot_header_t
));
75 MmFreeMemory(ImageHeaders
);
78 * If we reached the end of the 8192 bytes without
79 * finding the multiboot header then return error
83 UiMessageBox("No multiboot header found!");
87 /*printf("multiboot header:\n");
88 printf("0x%x\n", mb_header.magic);
89 printf("0x%x\n", mb_header.flags);
90 printf("0x%x\n", mb_header.checksum);
91 printf("0x%x\n", mb_header.header_addr);
92 printf("0x%x\n", mb_header.load_addr);
93 printf("0x%x\n", mb_header.load_end_addr);
94 printf("0x%x\n", mb_header.bss_end_addr);
95 printf("0x%x\n", mb_header.entry_addr);
99 * Calculate the checksum and make sure it matches
101 dwHeaderChecksum
= mb_header
.magic
;
102 dwHeaderChecksum
+= mb_header
.flags
;
103 dwHeaderChecksum
+= mb_header
.checksum
;
104 if (dwHeaderChecksum
!= 0)
106 UiMessageBox("Multiboot header checksum invalid!");
111 * Get the file offset, this should be 0, and move the file pointer
113 dwFileLoadOffset
= (Idx
* sizeof(U32
)) - (mb_header
.header_addr
- mb_header
.load_addr
);
114 FsSetFilePointer(KernelImage
, dwFileLoadOffset
);
117 * Load the file image
119 dwDataSize
= (mb_header
.load_end_addr
- mb_header
.load_addr
);
120 FsReadFile(KernelImage
, dwDataSize
, NULL
, (void*)mb_header
.load_addr
);
123 * Initialize bss area
125 dwBssSize
= (mb_header
.bss_end_addr
- mb_header
.load_end_addr
);
126 memset((void*)mb_header
.load_end_addr
, 0, dwBssSize
);
128 next_module_load_base
= ROUND_UP(mb_header
.bss_end_addr
, /*PAGE_SIZE*/4096);
134 BOOL
MultiBootLoadModule(FILE *ModuleImage
, char *ModuleName
)
138 char* ModuleNameString
;
142 * Get current module data structure and module name string array
144 pModule
= &multiboot_modules
[mb_info
.mods_count
];
146 TempName
= strchr( ModuleName
, '\\' );
148 ModuleName
= TempName
+ 1;
151 ModuleNameString
= multiboot_module_strings
[mb_info
.mods_count
];
153 dwModuleSize
= FsGetFileSize(ModuleImage
);
154 pModule
->mod_start
= next_module_load_base
;
155 pModule
->mod_end
= next_module_load_base
+ dwModuleSize
;
156 strcpy(ModuleNameString
, ModuleName
);
157 pModule
->string
= (unsigned long)ModuleNameString
;
160 * Load the file image
162 FsReadFile(ModuleImage
, dwModuleSize
, NULL
, (void*)next_module_load_base
);
164 next_module_load_base
= ROUND_UP(pModule
->mod_end
, /*PAGE_SIZE*/4096);
165 mb_info
.mods_count
++;
171 PVOID
MultiBootLoadModule(FILE *ModuleImage
, char *ModuleName
, U32
* ModuleSize
)
175 char* ModuleNameString
;
179 * Get current module data structure and module name string array
181 pModule
= &multiboot_modules
[mb_info
.mods_count
];
183 TempName
= strchr( ModuleName
, '\\' );
185 ModuleName
= TempName
+ 1;
188 ModuleNameString
= multiboot_module_strings
[mb_info
.mods_count
];
190 dwModuleSize
= FsGetFileSize(ModuleImage
);
191 pModule
->mod_start
= next_module_load_base
;
192 pModule
->mod_end
= next_module_load_base
+ dwModuleSize
;
193 strcpy(ModuleNameString
, ModuleName
);
194 pModule
->string
= (unsigned long)ModuleNameString
;
197 * Load the file image
199 FsReadFile(ModuleImage
, dwModuleSize
, NULL
, (void*)next_module_load_base
);
201 next_module_load_base
= ROUND_UP(pModule
->mod_end
, /*PAGE_SIZE*/4096);
202 mb_info
.mods_count
++;
204 if (ModuleSize
!= NULL
)
205 *ModuleSize
= dwModuleSize
;
207 return((PVOID
)pModule
->mod_start
);
211 int GetBootPartition(char *OperatingSystemName
)
213 int BootPartitionNumber
= -1;
217 if (IniOpenSection(OperatingSystemName
, &SectionId
))
219 if (IniReadSettingByName(SectionId
, "BootPartition", value
, 1024))
221 BootPartitionNumber
= atoi(value
);
225 return BootPartitionNumber
;
229 PVOID
MultiBootCreateModule(char *ModuleName
)
232 char* ModuleNameString
;
235 * Get current module data structure and module name string array
237 pModule
= &multiboot_modules
[mb_info
.mods_count
];
239 ModuleNameString
= multiboot_module_strings
[mb_info
.mods_count
];
241 pModule
->mod_start
= next_module_load_base
;
242 pModule
->mod_end
= -1;
243 strcpy(ModuleNameString
, ModuleName
);
244 pModule
->string
= (unsigned long)ModuleNameString
;
246 pOpenModule
= pModule
;
248 return((PVOID
)pModule
->mod_start
);
252 BOOL
MultiBootCloseModule(PVOID ModuleBase
, U32 dwModuleSize
)
256 if ((pOpenModule
!= NULL
) &&
257 ((module_t
*)ModuleBase
== (module_t
*)pOpenModule
->mod_start
) &&
258 (pOpenModule
->mod_end
== -1))
260 pModule
= pOpenModule
;
261 pModule
->mod_end
= pModule
->mod_start
+ dwModuleSize
;
263 next_module_load_base
= ROUND_UP(pModule
->mod_end
, /*PAGE_SIZE*/4096);
264 mb_info
.mods_count
++;