00001 00007 /* 00008 * Copyright (C) 2003,2004 Bregmasoft 00009 * 00010 * This program is free software; you can redistribute it and/or modify it under 00011 * the terms of the GNU General Public License as published by the Free Software 00012 * Foundation; either version 2 of the License, or (at your option) any later 00013 * version. 00014 * 00015 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 00016 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 00017 * PARTICULAR PURPOSE. See the GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License along with 00020 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 * Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 #ifndef ZYGOMA_X86_MULTIBOOT_H_ 00024 #define ZYGOMA_X86_MULTIBOOT_H_ 00025 00026 #include <arch/types.h> 00027 00028 namespace Zygoma 00029 { 00030 namespace ia32 00031 { 00046 struct MultibootHeader 00047 { 00053 /* @{ */ 00058 u32 m_magic; 00059 00063 static const u32 kMAGIC = 0x1BADB002; 00064 00080 u32 m_flags; 00081 static const u32 kFLAGS_ALIGN_ON_4K = (1 << 0); 00082 static const u32 kFLAGS_INCLUDE_MEM_FIELDS = (1 << 1); 00083 static const u32 kFLAGS_VIDEO_FIELDS_INCLUDED = (1 << 2); 00084 static const u32 kFLAGS_ADDRESS_FIELDS_INCLUDED = (1 << 16); 00085 00090 u32 m_checksum; 00091 00092 /* @} */ 00093 00100 /* @{ */ 00101 00105 u32 m_header_addr; 00106 00111 u32 m_load_addr; 00112 00119 u32 m_load_end_addr; 00120 00124 u32 m_bss_end_addr; 00125 00129 u32 m_entry_addr; 00130 00131 /* @} */ 00132 00139 /* @{ */ 00140 00144 u32 m_mode_type; 00145 enum GraphicsMode 00146 { 00147 kGRAPHMODE_GRAPHICS = 0, 00148 kGRAPHMODE_TEXT = 1 00149 }; 00150 00156 u32 m_width; 00157 00163 u32 m_height; 00164 00169 u32 m_depth; 00170 00171 /* @} */ 00172 }; 00173 00174 00180 struct LoadModuleDescriptor 00181 { 00182 u32 m_mod_start; 00183 u32 m_mod_end; 00184 u32 m_string; 00185 u32 m_reserved; 00186 }; 00187 00193 struct MemoryMapDescriptor 00194 { 00195 u32 m_size; 00196 u32 m_base_addr_low; 00197 u32 m_base_addr_high; 00198 u32 m_length_low; 00199 u32 m_length_high; 00200 u32 m_type; /* 1=available RAM, otherwise=other */ 00201 }; 00202 00208 struct DiskDriveMapDescriptor 00209 { 00210 u32 m_size; 00211 u08 m_drive_number; 00212 u08 m_drive_mode; /* 0 = CHS, 1 = LBA */ 00213 u16 m_drive_cylenders; 00214 u08 m_drive_heads; 00215 u08 m_drive_sectors; 00216 u16 m_drive_ports[1]; 00217 } ZYGOMA_PACKED; 00218 00219 00227 struct MultibootInfo 00228 { 00229 public: 00230 static const u32 kMAGIC = 0x2BADB002; 00231 00232 u32 m_flags; 00233 static const u32 kFLAG_MEM_FIELDS_VALID = (1 << 0); 00234 static const u32 kFLAG_BOOT_DEVICE_FIELDS_VALID = (1 << 1); 00235 static const u32 kFLAG_CMDLINE_FIELDS_VALID = (1 << 2); 00236 static const u32 kFLAG_MODULES_FIELDS_VALID = (1 << 3); 00237 static const u32 kFLAG_AOUT_FIELDS_VALID = (1 << 4); 00238 static const u32 kFLAG_ELF_FIELDS_VALID = (1 << 5); 00239 static const u32 kFLAG_MMAP_FIELDS_VALID = (1 << 6); 00240 static const u32 kFLAG_DRIVES_FIELDS_VALID = (1 << 7); 00241 static const u32 kFLAG_CONFIG_FIELDS_VALID = (1 << 8); 00242 static const u32 kFLAG_LOADER_NAME_FIELDS_VALID = (1 << 9); 00243 static const u32 kFLAG_APM_FIELDS_VALID = (1 << 10); 00244 static const u32 kFLAG_GRAPHICS_FIELDS_VALID = (1 << 11); 00245 00249 /* @{ */ 00250 private: 00251 u32 m_mem_lower; 00252 00253 public: 00261 u32 00262 mem_lower() const 00263 { 00264 if (m_flags & kFLAG_MEM_FIELDS_VALID) 00265 { 00266 return m_mem_lower; 00267 } 00268 else 00269 { 00270 return 0; 00271 } 00272 } 00273 00274 private: 00275 u32 m_mem_upper; 00276 00277 00278 public: 00285 u32 00286 mem_upper() const 00287 { 00288 if (m_flags & kFLAG_MEM_FIELDS_VALID) 00289 { 00290 return m_mem_upper; 00291 } 00292 else 00293 { 00294 return 0; 00295 } 00296 } 00307 /* @{ */ 00308 private: 00312 u32 m_boot_device; 00313 00314 public: 00320 u32 00321 boot_device() const 00322 { 00323 if (m_flags & kFLAG_BOOT_DEVICE_FIELDS_VALID) 00324 { 00325 return m_boot_device; 00326 } 00327 else 00328 { 00329 return 0xffffffff; 00330 } 00331 } 00332 00338 /* @{ */ 00339 private: 00340 u32 m_cmdline; 00341 00342 public: 00350 const char* 00351 cmdline() const 00352 { 00353 if ((m_flags & kFLAG_CMDLINE_FIELDS_VALID) && (m_cmdline != 0)) 00354 { 00355 return reinterpret_cast<const char*>(m_cmdline); 00356 } 00357 else 00358 { 00359 return ""; 00360 } 00361 } 00362 00363 /* @} */ 00364 00369 /* @{ */ 00370 public: 00374 u32 m_mods_count; 00375 00379 u32 m_mods_addr; 00380 00381 /* @} */ 00382 00386 /* @{ */ 00387 public: 00388 u32 m_syms[4]; 00389 /* @} */ 00390 00395 /* @{ */ 00396 private: 00397 u32 m_mmap_length; 00398 u32 m_mmap_addr; 00399 00400 public: 00408 MemoryMapDescriptor* 00409 memoryMapBase() 00410 { 00411 if (m_flags & kFLAG_MMAP_FIELDS_VALID) 00412 { 00413 return reinterpret_cast<MemoryMapDescriptor*>(m_mmap_addr); 00414 } 00415 else 00416 { 00417 return 0; 00418 } 00419 } 00420 00430 u32 00431 memoryMapLength() 00432 { 00433 if (m_flags & kFLAG_MMAP_FIELDS_VALID) 00434 { 00435 return m_mmap_length 00436 / (sizeof(MemoryMapDescriptor) - sizeof(u32)); 00437 } 00438 else 00439 { 00440 return 0; 00441 } 00442 } 00443 00444 /* @} */ 00445 00450 /* @{ */ 00451 public: 00452 u32 m_drives_length; 00453 u32 m_drives_addr; 00454 00455 /* @} */ 00456 00461 /* @{ */ 00462 public: 00463 u32 m_config_table; 00464 00465 /* @} */ 00466 00470 /* @{ */ 00471 private: 00472 u32 m_boot_loader_name; 00473 00474 public: 00482 const char* 00483 boot_loader_name() const 00484 { 00485 if ((m_flags & kFLAG_LOADER_NAME_FIELDS_VALID) && (m_boot_loader_name != 0)) 00486 { 00487 return reinterpret_cast<const char*>(m_boot_loader_name); 00488 } 00489 else 00490 { 00491 return "unknown"; 00492 } 00493 } 00494 00495 /* @} */ 00496 00501 /* @{ */ 00502 public: 00503 u32 m_apm_table; 00504 00505 /* @} */ 00506 00511 /* @{ */ 00512 public: 00513 u32 m_vbe_control_info; 00514 u32 m_vbe_mode_info; 00515 u32 m_vbe_mode; 00516 u16 m_vbe_interface_seg; 00517 u16 m_vbe_interface_of; 00518 u16 m_vbe_interface_len; 00519 /* @} */ 00520 }; 00530 inline u32 00531 endOfMemory(MultibootInfo* mbinfo) 00532 { 00533 u32 ramEnd = 0; 00534 MemoryMapDescriptor* mmd = mbinfo->memoryMapBase(); 00535 for (unsigned int i = 0; i < mbinfo->memoryMapLength(); ++i) 00536 { 00537 if (mmd[i].m_type == 1) 00538 { 00539 u32 mend = mmd[i].m_base_addr_low + mmd[i].m_length_low; 00540 if (mend > ramEnd) 00541 { 00542 ramEnd = mend; 00543 } 00544 } 00545 } 00546 return ramEnd; 00547 } 00548 00552 extern MultibootInfo* g_multibootInfo; 00553 } // namespace ia32 00554 } // namespace Zygoma 00555 00556 #endif // ZYGOMA_X86_MULTIBOOT_H_