Overview   API Reference  

mbr.hpp

00001 #if !defined(__MBR_HPP__)
00002 #define __MBR_HPP__
00003 
00004 //
00005 // local includes
00006 //
00007 #include "core/common.hpp"
00008 
00012 struct __packed(mbr)
00013 {
00014     static const uint16_t SIGNATURE = 0xaa55;
00015 
00019     struct __packed(entry)
00020     {
00021         enum attributes_constants
00022         {
00024             BOOTABLE = 0x80
00025         };
00026 
00027         uint8_t     attributes;             
00028         uint8_t     start_chs[3];           
00029         uint8_t     type;                   
00030         uint8_t     end_chs[3];             
00031         le_uint32_t start_lba;              
00032         le_uint32_t size_lba;               
00033 
00037         inline entry(void)
00038         {
00039             memset(this, 0, sizeof(entry));
00040         }
00041 
00045         inline entry(uint8_t type, uint32_t start_lba, uint32_t size_lba, uint8_t attributes=0)
00046         {
00047             // initialize attributes
00048             this->attributes=attributes;
00049             this->start_chs[0]=0xfe;
00050             this->start_chs[1]=this->start_chs[2]=0xff;
00051             this->type=type;
00052             this->end_chs[0]=0xfe;
00053             this->end_chs[1]=this->end_chs[2]=0xff;
00054             this->start_lba=start_lba;
00055             this->size_lba=size_lba;
00056         }
00057 
00058         inline bool is_used(void) const
00059         {
00060             // a size of 0 is definitely stupid.
00061             return type && size_lba;
00062         }
00063 
00064         inline bool is_valid(const uint32_t disk_size) const
00065         {
00066             // an unused entry must be valid
00067             return (start_lba < disk_size) && (start_lba + size_lba <= disk_size);
00068         }
00069 
00070         inline bool overlaps(const entry &other) const
00071         {
00072             const uint64_t end_lba=static_cast<uint64_t>(start_lba) + size_lba - 1,
00073                            other_end_lba=static_cast<uint64_t>(other.start_lba) + other.size_lba - 1;
00074             return (start_lba <= other_end_lba) && (other.start_lba <= end_lba);
00075         }
00076     };
00077 
00078     // mandated by the BIOS32 specification
00079     static_assert(sizeof(entry) == 16, "entry's size must be 16");
00080 
00081     uint8_t     boot_code[440];             
00082     le_uint32_t uid;                        
00083     le_uint16_t unknown;                    
00084     entry       partitions[4];              
00085     le_uint16_t signature;                  
00086 
00090     inline mbr(void)
00091     {
00092         memset(this, 0, sizeof(mbr));
00093     }
00094 
00098     inline mbr(uint32_t uid, const uint8_t *boot_code=nullptr)
00099     {
00100         // clear data structure
00101         memset(this, 0, sizeof(mbr));
00102         // initialize attributes
00103         if (boot_code) memcpy(this->boot_code, boot_code, sizeof(this->boot_code));
00104         this->uid=uid;
00105         this->signature=SIGNATURE;
00106     }
00107 
00108     inline bool is_valid(void) const
00109     {
00110         return signature == SIGNATURE;
00111     }
00112 
00113     inline bool is_consistent(const uint64_t disk_size) const
00114     {
00115         for (int i=0; i < 4; i++)
00116             if (partitions[i].is_used()) {
00117                 if (!partitions[i].is_valid(disk_size)) return false;
00118 
00119                 for (int j=0; j < i; j++)
00120                     if (partitions[j].is_used() && partitions[i].overlaps(partitions[j]))
00121                         return false;
00122             }
00123 
00124         return true;
00125     }
00126 
00127     inline bool matches(const mbr &other) const
00128     {
00129         return (uid == other.uid) &&
00130                (signature == other.signature) &&
00131                !memcmp(partitions, other.partitions, sizeof(partitions));
00132     }
00133 };
00134 
00135 // mandated by the BIOS32 specification
00136 static_assert(sizeof(mbr) == 512, "mbr's size must be 512");
00137 
00138 #endif
00139 
00140 // ***** end of source ***** //
00141 

L4vmm Reference Manual, written by Mario Schwalbe  © 2006-2008