[haiku-commits] haiku: hrev45205 - in src/add-ons: kernel/partitioning_systems/gpt disk_systems/gpt

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 26 Jan 2013 01:37:30 +0100 (CET)

hrev45205 adds 3 changesets to branch 'master'
old head: 95a11c765de55b451edd061a4b494ac363d893bd
new head: 9e8d42ac443b81b85d608cdbc8c8f809e8aad79a
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=9e8d42a+%5E95a11c7

----------------------------------------------------------------------------

d013c8e: Possibly fixed BootLoaderTest build.
  
  * Adapted to x86_64 changes.

ab31389: Implemented write support, reorganized source files.
  
  * Moved some functionality into their own files so that they can easily
    be reused by other code.
  * Added crc32() function from FreeBSD. Implemented CRC handling and
    validation.
  * Implemented missing write functionality.

9e8d42a: Work in progress in getting GPTPartitionHandle working.
  
  * Tried to use EFI::Header class, but there doesn't seem to be an easy
    way to actually hit the disk -- which we'll have to do to find out
    how large the GPT table is.
  * Initialization of GPT disks is now working which is why I added the disk
    system add-on to the image. However, there is a caveat, as the backup
    header and table aren't written yet.
  * Partitions can be deleted.
  * Creating partitions does not work yet, but I don't know yet why; in
    theory it could already work.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

17 files changed, 741 insertions(+), 388 deletions(-)
build/jam/HaikuImage                             |   2 +-
src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef   |   8 +-
.../disk_systems/gpt/GPTPartitionHandle.cpp      |  45 ++-
.../disk_systems/gpt/GPTPartitionHandle.h        |   5 +
src/add-ons/disk_systems/gpt/Jamfile             |   7 +-
.../kernel/partitioning_systems/gpt/Header.cpp   | 310 +++++++++++++++
.../kernel/partitioning_systems/gpt/Header.h     |  73 ++++
.../kernel/partitioning_systems/gpt/Jamfile      |   3 +
.../kernel/partitioning_systems/gpt/crc32.cpp    | 105 ++++++
.../kernel/partitioning_systems/gpt/crc32.h      |  15 +
.../kernel/partitioning_systems/gpt/efi_gpt.cpp  | 373 +------------------
.../partitioning_systems/gpt/gpt_known_guids.h   |  15 +-
.../kernel/partitioning_systems/gpt/utility.cpp  | 108 ++++++
.../kernel/partitioning_systems/gpt/utility.h    |  31 ++
src/system/boot/loader/Jamfile                   |   7 +-
src/tests/system/boot/loader/Jamfile             |  13 +-
src/tests/system/boot/loader/platform_start.cpp  |   9 +-

############################################################################

Commit:      d013c8e96a4b83909b818372d1cb730ac148e56f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d013c8e
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Fri Jan 25 22:37:41 2013 UTC

Possibly fixed BootLoaderTest build.

* Adapted to x86_64 changes.

----------------------------------------------------------------------------

diff --git a/src/tests/system/boot/loader/platform_start.cpp 
b/src/tests/system/boot/loader/platform_start.cpp
index cc379b5..66b7fbd 100644
--- a/src/tests/system/boot/loader/platform_start.cpp
+++ b/src/tests/system/boot/loader/platform_start.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2003-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -25,7 +25,11 @@ platform_exit(void)
 void
 platform_start_kernel(void)
 {
-       printf("*** jump to kernel at %p ***\n*** program exits.\n", (void 
*)gKernelArgs.kernel_image.elf_header.e_entry);
+       preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
+               gKernelArgs.kernel_image.Pointer());
+
+       printf("*** jump to kernel at %p ***\n*** program exits.\n",
+               (void *)image->elf_header.e_entry);
        exit(0);
 }
 
@@ -40,4 +44,3 @@ main(int argc, char **argv)
 
        return 0;
 }
-

############################################################################

Commit:      ab313893415e1eaed50e2af3b3517b614ee10e8a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ab31389
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Sat Jan 26 00:30:23 2013 UTC

Implemented write support, reorganized source files.

* Moved some functionality into their own files so that they can easily
  be reused by other code.
* Added crc32() function from FreeBSD. Implemented CRC handling and
  validation.
* Implemented missing write functionality.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp 
b/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp
new file mode 100644
index 0000000..6bcd288
--- /dev/null
+++ b/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2007-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2009, Michael Lotz, mmlr@xxxxxxxx. All rights reserved.
+ *
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "Header.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <KernelExport.h>
+
+#ifdef _KERNEL_MODE
+#      include <util/kernel_cpp.h>
+#else
+#      include <new>
+#endif
+
+#include "crc32.h"
+#include "utility.h"
+
+
+#define TRACE_EFI_GPT
+#ifdef TRACE_EFI_GPT
+#      ifndef _KERNEL_MODE
+#              define dprintf printf
+#      endif
+#      define TRACE(x) dprintf x
+#else
+#      define TRACE(x) ;
+#endif
+
+
+namespace EFI {
+
+
+Header::Header(int fd, off_t block, uint32 blockSize)
+       :
+       fBlock(block),
+       fBlockSize(blockSize),
+       fStatus(B_NO_INIT),
+       fEntries(NULL)
+{
+       // TODO: check the correctness of the protective MBR
+
+       // read and check the partition table header
+
+       ssize_t bytesRead = read_pos(fd, block * blockSize, &fHeader,
+               sizeof(efi_table_header));
+       if (bytesRead != (ssize_t)sizeof(efi_table_header)) {
+               if (bytesRead < B_OK)
+                       fStatus = bytesRead;
+               else
+                       fStatus = B_IO_ERROR;
+
+               return;
+       }
+
+       if (memcmp(fHeader.header, EFI_PARTITION_HEADER, sizeof(fHeader.header))
+               || !_ValidateHeaderCRC()
+               || fHeader.AbsoluteBlock() != fBlock) {
+               // TODO: check that partition counts are in valid bounds
+               fStatus = B_BAD_DATA;
+               return;
+       }
+
+       // allocate, read, and check partition entry array
+
+       fEntries = new (std::nothrow) uint8[_EntryArraySize()];
+       if (fEntries == NULL) {
+               // TODO: if there cannot be allocated enough (ie. the boot 
loader's
+               //      heap is limited), try a smaller size before failing
+               fStatus = B_NO_MEMORY;
+               return;
+       }
+
+       bytesRead = read_pos(fd, fHeader.EntriesBlock() * blockSize,
+               fEntries, _EntryArraySize());
+       if (bytesRead != (ssize_t)_EntryArraySize()) {
+               if (bytesRead < B_OK)
+                       fStatus = bytesRead;
+               else
+                       fStatus = B_IO_ERROR;
+
+               return;
+       }
+
+       if (!_ValidateEntriesCRC()) {
+               // TODO: check overlapping or out of range partitions
+               fStatus = B_BAD_DATA;
+               return;
+       }
+
+#ifdef TRACE_EFI_GPT
+       _Dump();
+       _DumpPartitions();
+#endif
+
+       fStatus = B_OK;
+}
+
+
+#ifndef _BOOT_MODE
+Header::Header(off_t block, off_t lastBlock, uint32 blockSize)
+       :
+       fBlock(block),
+       fBlockSize(blockSize),
+       fStatus(B_NO_INIT),
+       fEntries(NULL)
+{
+       // initialize to an empty header
+       memcpy(fHeader.header, EFI_PARTITION_HEADER, sizeof(fHeader.header));
+       fHeader.SetRevision(EFI_TABLE_REVISION);
+       fHeader.SetHeaderSize(sizeof(fHeader));
+       fHeader.SetHeaderCRC(0);
+       fHeader.SetAbsoluteBlock(fBlock);
+       fHeader.SetAlternateBlock(0); // TODO
+       // TODO: set disk guid
+       fHeader.SetEntriesBlock(EFI_PARTITION_ENTRIES_BLOCK);
+       fHeader.SetEntryCount(EFI_PARTITION_ENTRY_COUNT);
+       fHeader.SetEntrySize(EFI_PARTITION_ENTRY_SIZE);
+       fHeader.SetEntriesCRC(0);
+
+       size_t arraySize = _EntryArraySize();
+       fEntries = new (std::nothrow) uint8[arraySize];
+       if (fEntries == NULL) {
+               fStatus = B_NO_MEMORY;
+               return;
+       }
+
+       memset(fEntries, 0, arraySize);
+               // TODO: initialize the entry guids
+
+       uint32 entryBlocks = (arraySize + fBlockSize - 1) / fBlockSize;
+       fHeader.SetFirstUsableBlock(EFI_PARTITION_ENTRIES_BLOCK + entryBlocks);
+       fHeader.SetLastUsableBlock(lastBlock - 1 - entryBlocks);
+
+#ifdef TRACE_EFI_GPT
+       _Dump();
+       _DumpPartitions();
+       dprintf("GPT: HERE I AM!\n");
+#else
+       dprintf("GPT: Nope!\n");
+#endif
+
+       fStatus = B_OK;
+}
+#endif // !_BOOT_MODE
+
+
+Header::~Header()
+{
+       delete[] fEntries;
+}
+
+
+status_t
+Header::InitCheck() const
+{
+       return fStatus;
+}
+
+
+#ifndef _BOOT_MODE
+status_t
+Header::WriteEntry(int fd, uint32 entryIndex)
+{
+       // Determine block to write
+       off_t block = fHeader.EntriesBlock()
+               + entryIndex * fHeader.EntrySize() / fBlockSize;
+       uint32 entryOffset = entryIndex * fHeader.EntrySize() % fBlockSize;
+
+       status_t status = _Write(fd, block * fBlockSize, fEntries + entryOffset,
+               fBlockSize);
+       if (status != B_OK)
+               return status;
+
+       // TODO: write mirror at the end
+
+       // Update header, too -- the entries CRC changed
+       return Write(fd);
+}
+
+
+status_t
+Header::Write(int fd)
+{
+       _UpdateCRC();
+
+       status_t status = _Write(fd, fHeader.AbsoluteBlock() * fBlockSize,
+               &fHeader, sizeof(efi_table_header));
+       if (status != B_OK)
+               return status;
+
+       // TODO: write mirror at the end
+
+       return B_OK;
+}
+#endif // !_BOOT_MODE
+
+
+status_t
+Header::_Write(int fd, off_t offset, const void* data, size_t size) const
+{
+       ssize_t bytesWritten = write_pos(fd, offset, data, size);
+       if (bytesWritten < 0)
+               return bytesWritten;
+       if (bytesWritten != (ssize_t)size)
+               return B_IO_ERROR;
+
+       return B_OK;
+}
+
+
+void
+Header::_UpdateCRC()
+{
+       fHeader.SetEntriesCRC(crc32(fEntries, _EntryArraySize()));
+       fHeader.SetHeaderCRC(0);
+       fHeader.SetHeaderCRC(crc32((uint8*)&fHeader, sizeof(efi_table_header)));
+}
+
+
+bool
+Header::_ValidateHeaderCRC()
+{
+       uint32 originalCRC = fHeader.HeaderCRC();
+       fHeader.SetHeaderCRC(0);
+
+       bool matches = originalCRC == crc32((const uint8*)&fHeader,
+               sizeof(efi_table_header));
+dprintf("GPT: MATCHES %d!\n", matches);
+
+       fHeader.SetHeaderCRC(originalCRC);
+       return matches;
+}
+
+
+bool
+Header::_ValidateEntriesCRC() const
+{
+       return fHeader.EntriesCRC() == crc32(fEntries, _EntryArraySize());
+}
+
+
+#ifdef TRACE_EFI_GPT
+const char *
+Header::_PrintGUID(const guid_t &id)
+{
+       static char guid[48];
+       snprintf(guid, sizeof(guid),
+               "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               B_LENDIAN_TO_HOST_INT32(id.data1), 
B_LENDIAN_TO_HOST_INT16(id.data2),
+               B_LENDIAN_TO_HOST_INT16(id.data3), id.data4[0], id.data4[1],
+               id.data4[2], id.data4[3], id.data4[4], id.data4[5], id.data4[6],
+               id.data4[7]);
+       return guid;
+}
+
+
+void
+Header::_Dump()
+{
+       dprintf("EFI header: %.8s\n", fHeader.header);
+       dprintf("EFI revision: %ld\n", fHeader.Revision());
+       dprintf("header size: %ld\n", fHeader.HeaderSize());
+       dprintf("header CRC: %ld\n", fHeader.HeaderCRC());
+       dprintf("absolute block: %Ld\n", fHeader.AbsoluteBlock());
+       dprintf("alternate block: %Ld\n", fHeader.AlternateBlock());
+       dprintf("first usable block: %Ld\n", fHeader.FirstUsableBlock());
+       dprintf("last usable block: %Ld\n", fHeader.LastUsableBlock());
+       dprintf("disk GUID: %s\n", _PrintGUID(fHeader.disk_guid));
+       dprintf("entries block: %Ld\n", fHeader.EntriesBlock());
+       dprintf("entry size:  %ld\n", fHeader.EntrySize());
+       dprintf("entry count: %ld\n", fHeader.EntryCount());
+       dprintf("entries CRC: %ld\n", fHeader.EntriesCRC());
+}
+
+
+void
+Header::_DumpPartitions()
+{
+       for (uint32 i = 0; i < EntryCount(); i++) {
+               const efi_partition_entry &entry = EntryAt(i);
+
+               if (entry.partition_type == kEmptyGUID)
+                       continue;
+
+               dprintf("[%3ld] partition type: %s\n", i,
+                       _PrintGUID(entry.partition_type));
+               dprintf("      unique id: %s\n", _PrintGUID(entry.unique_guid));
+               dprintf("      start block: %Ld\n", entry.StartBlock());
+               dprintf("      end block: %Ld\n", entry.EndBlock());
+               dprintf("      size: %g MB\n", (entry.EndBlock() - 
entry.StartBlock())
+                       * 512 / 1024.0 / 1024.0);
+               dprintf("      attributes: %Lx\n", entry.Attributes());
+
+               char name[64];
+               to_utf8(entry.name, EFI_PARTITION_NAME_LENGTH, name, 
sizeof(name));
+               dprintf("      name: %s\n", name);
+       }
+}
+#endif // TRACE_EFI_GPT
+
+
+}      // namespace EFI
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/Header.h 
b/src/add-ons/kernel/partitioning_systems/gpt/Header.h
new file mode 100644
index 0000000..d87dd12
--- /dev/null
+++ b/src/add-ons/kernel/partitioning_systems/gpt/Header.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2009, Michael Lotz, mmlr@xxxxxxxx. All rights reserved.
+ *
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef GPT_HEADER_H
+#define GPT_HEADER_H
+
+
+#include "efi_gpt.h"
+
+
+namespace EFI {
+
+
+class Header {
+public:
+                                                               Header(int fd, 
off_t block, uint32 blockSize);
+#ifndef _BOOT_MODE
+                                                               // constructor 
for empty header
+                                                               Header(off_t 
block, off_t lastBlock,
+                                                                       uint32 
blockSize);
+#endif
+                                                               ~Header();
+
+                       status_t                        InitCheck() const;
+                       bool                            IsPrimary() const
+                                                                       { 
return fBlock == EFI_HEADER_LOCATION; }
+
+                       uint64                          FirstUsableBlock() const
+                                                                       { 
return fHeader.FirstUsableBlock(); }
+                       uint64                          LastUsableBlock() const
+                                                                       { 
return fHeader.LastUsableBlock(); }
+
+                       uint32                          EntryCount() const
+                                                                       { 
return fHeader.EntryCount(); }
+                       efi_partition_entry& EntryAt(int32 index) const
+                                                                       { 
return *(efi_partition_entry*)(fEntries
+                                                                               
+ fHeader.EntrySize() * index); }
+
+#ifndef _BOOT_MODE
+                       status_t                        WriteEntry(int fd, 
uint32 entryIndex);
+                       status_t                        Write(int fd);
+#endif
+
+private:
+                       const char*                     _PrintGUID(const 
guid_t& id);
+                       void                            _Dump();
+                       void                            _DumpPartitions();
+
+                       status_t                        _Write(int fd, off_t 
offset, const void* data,
+                                                                       size_t 
size) const;
+                       void                            _UpdateCRC();
+                       bool                            _ValidateHeaderCRC();
+                       bool                            _ValidateEntriesCRC() 
const;
+                       size_t                          _EntryArraySize() const
+                                                                       { 
return fHeader.EntrySize()
+                                                                               
* fHeader.EntryCount(); }
+
+private:
+                       uint64                          fBlock;
+                       uint32                          fBlockSize;
+                       status_t                        fStatus;
+                       efi_table_header        fHeader;
+                       uint8*                          fEntries;
+};
+
+
+}      // namespace EFI
+
+
+#endif // GPT_HEADER_H
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/Jamfile 
b/src/add-ons/kernel/partitioning_systems/gpt/Jamfile
index 11fbc69..3d31aba 100644
--- a/src/add-ons/kernel/partitioning_systems/gpt/Jamfile
+++ b/src/add-ons/kernel/partitioning_systems/gpt/Jamfile
@@ -5,5 +5,8 @@ UsePrivateSystemHeaders ;
 
 KernelAddon efi_gpt :
        efi_gpt.cpp
+       Header.cpp
+       crc32.cpp
+       utility.cpp
        PartitionLocker.cpp
 ;
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/crc32.cpp 
b/src/add-ons/kernel/partitioning_systems/gpt/crc32.cpp
new file mode 100644
index 0000000..3fbf7ec
--- /dev/null
+++ b/src/add-ons/kernel/partitioning_systems/gpt/crc32.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+/*
+ *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
+ *  code or tables extracted from it, as desired without restriction.
+ */
+
+/*
+ *  First, the polynomial itself and its table of feedback terms.  The
+ *  polynomial is
+ *  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
+ *
+ *  Note that we take it "backwards" and put the highest-order term in
+ *  the lowest-order bit.  The X^32 term is "implied"; the LSB is the
+ *  X^31 term, etc.  The X^0 term (usually shown as "+1") results in
+ *  the MSB being 1
+ *
+ *  Note that the usual hardware shift register implementation, which
+ *  is what we're using (we're merely optimizing it by doing eight-bit
+ *  chunks at a time) shifts bits into the lowest-order term.  In our
+ *  implementation, that means shifting towards the right.  Why do we
+ *  do it this way?  Because the calculated CRC must be transmitted in
+ *  order from highest-order term to lowest-order term.  UARTs transmit
+ *  characters in order from LSB to MSB.  By storing the CRC this way
+ *  we hand it to the UART in the order low-byte to high-byte; the UART
+ *  sends each low-bit to hight-bit; and the result is transmission bit
+ *  by bit from highest- to lowest-order term without requiring any bit
+ *  shuffling on our part.  Reception works similarly
+ *
+ *  The feedback terms table consists of 256, 32-bit entries.  Notes
+ *
+ *      The table can be generated at runtime if desired; code to do so
+ *      is shown later.  It might not be obvious, but the feedback
+ *      terms simply represent the results of eight shift/xor opera
+ *      tions for all combinations of data and CRC register values
+ *
+ *      The values must be right-shifted by eight bits by the "updcrc
+ *      logic; the shift must be unsigned (bring in zeroes).  On some
+ *      hardware you could probably optimize the shift in assembler by
+ *      using byte-swap instructions
+ *      polynomial $edb88320
+ */
+
+
+#include "crc32.h"
+
+
+static const uint32 kTab[] = {
+       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+       0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+       0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+       0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+       0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+       0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+       0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+       0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+       0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+       0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+       0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+       0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+       0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+       0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+       0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+       0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+       0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+       0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+       0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+       0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+       0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+       0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+       0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+       0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+       0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+       0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+       0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+       0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+       0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+       0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+       0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+       0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+       0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+       0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+       0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+
+uint32
+crc32(const uint8* buffer, size_t size)
+{
+       uint32 crc = ~0U;
+       while (size-- != 0)
+               crc = kTab[(crc ^ *buffer++) & 0xff] ^ (crc >> 8);
+       return crc ^ ~0U;
+}
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/crc32.h 
b/src/add-ons/kernel/partitioning_systems/gpt/crc32.h
new file mode 100644
index 0000000..1509379
--- /dev/null
+++ b/src/add-ons/kernel/partitioning_systems/gpt/crc32.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef CRC32_H
+#define CRC32_H
+
+
+#include <SupportDefs.h>
+
+
+uint32 crc32(const uint8* buffer, size_t size);
+
+
+#endif // CRC32_H
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp 
b/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp
index 33fcede..12e88c7 100644
--- a/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp
+++ b/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp
@@ -16,7 +16,6 @@
 #else
 #      include <DiskDeviceTypes.h>
 #      include "PartitionLocker.h"
-#      include <utf8_functions.h>
 #endif
 #include <util/kernel_cpp.h>
 
@@ -24,7 +23,8 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "gpt_known_guids.h"
+#include "Header.h"
+#include "utility.h"
 
 
 #define TRACE_EFI_GPT
@@ -38,156 +38,7 @@
 #define EFI_PARTITION_MODULE_NAME "partitioning_systems/efi_gpt/v1"
 
 
-namespace EFI {
-
-class Header {
-       public:
-               Header(int fd, off_t block, uint32 blockSize);
-#ifndef _BOOT_MODE
-               // constructor for empty header
-               Header(off_t block, uint32 blockSize);
-#endif
-               ~Header();
-
-               status_t InitCheck() const;
-               bool IsPrimary() const
-                       { return fBlock == EFI_HEADER_LOCATION; }
-
-               uint64 FirstUsableBlock() const
-                       { return fHeader.FirstUsableBlock(); }
-               uint64 LastUsableBlock() const
-                       { return fHeader.LastUsableBlock(); }
-
-               uint32 EntryCount() const
-                       { return fHeader.EntryCount(); }
-               efi_partition_entry &EntryAt(int32 index) const
-                       { return *(efi_partition_entry *)
-                               (fEntries + fHeader.EntrySize() * index); }
-
-#ifndef _BOOT_MODE
-               status_t WriteEntry(int fd, uint32 entryIndex);
-               status_t Write(int fd);
-#endif
-
-       private:
-#ifdef TRACE_EFI_GPT
-               const char *_PrintGUID(const guid_t &id);
-               void _Dump();
-               void _DumpPartitions();
-#endif
-
-               bool _ValidateCRC(uint8 *data, size_t size) const;
-               size_t _EntryArraySize() const
-                       { return fHeader.EntrySize() * fHeader.EntryCount(); }
-
-               uint64                          fBlock;
-               uint32                          fBlockSize;
-               status_t                        fStatus;
-               efi_table_header        fHeader;
-               uint8                           *fEntries;
-};
-
-}      // namespace EFI
-
-
-const static guid_t kEmptyGUID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
-
-
-inline bool
-static_guid::operator==(const guid_t &other) const
-{
-       return B_HOST_TO_LENDIAN_INT32(data1) == other.data1
-               && B_HOST_TO_LENDIAN_INT16(data2) == other.data2
-               && B_HOST_TO_LENDIAN_INT16(data3) == other.data3
-               && B_HOST_TO_BENDIAN_INT64(*(uint64 *)&data4) == *(uint64 
*)other.data4;
-                       // the last 8 bytes are in big-endian order
-}
-
-
-static void
-put_utf8_byte(char *&to, size_t &left, char c)
-{
-       if (left <= 1)
-               return;
-
-       *(to++) = c;
-       left--;
-}
-
-
-static void
-to_utf8(const uint16 *from, size_t maxFromLength, char *to, size_t toSize)
-{
-       for (uint32 i = 0; i < maxFromLength; i++) {
-               uint16 c = B_LENDIAN_TO_HOST_INT16(from[i]);
-               if (!c)
-                       break;
-
-               if (c < 0x80)
-                       put_utf8_byte(to, toSize, c);
-               else if (c < 0x800) {
-                       put_utf8_byte(to, toSize, 0xc0 | (c >> 6));
-                       put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
-               } else if (c < 0x10000) {
-                       put_utf8_byte(to, toSize, 0xe0 | (c >> 12));
-                       put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f));
-                       put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
-               } else if (c <= 0x10ffff) {
-                       put_utf8_byte(to, toSize, 0xf0 | (c >> 18));
-                       put_utf8_byte(to, toSize, 0x80 | ((c >> 12) & 0x3f));
-                       put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f));
-                       put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
-               }
-       }
-
-       if (toSize > 0)
-               *to = '\0';
-}
-
-
 #ifndef _BOOT_MODE
-static void
-to_ucs2(const char *from, size_t fromLength, uint16 *to, size_t maxToLength)
-{
-       size_t index = 0;
-       while (from[0] && index < maxToLength) {
-               // TODO: handle characters that are not representable in UCS-2 
better
-               uint32 code = UTF8ToCharCode(&from);
-               if (code < 0x10000)
-                       to[index++] = code;
-       }
-
-       if (index < maxToLength)
-               to[index] = '\0';
-}
-#endif // !_BOOT_MODE
-
-
-static const char *
-get_partition_type(const guid_t &guid)
-{
-       for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) {
-               if (kTypeMap[i].guid == guid)
-                       return kTypeMap[i].type;
-       }
-
-       return NULL;
-}
-
-
-#ifndef _BOOT_MODE
-static const static_guid *
-guid_for_partition_type(const char *type)
-{
-       for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) {
-               if (strcmp(kTypeMap[i].type, type) == 0)
-                       return &kTypeMap[i].guid;
-       }
-
-       return NULL;
-}
-
-
 static off_t
 block_align(partition_data *partition, off_t offset, bool upwards)
 {
@@ -201,223 +52,6 @@ block_align(partition_data *partition, off_t offset, bool 
upwards)
 #endif // !_BOOT_MODE
 
 
-//     #pragma mark -
-
-
-namespace EFI {
-
-Header::Header(int fd, off_t block, uint32 blockSize)
-       :
-       fBlock(block),
-       fBlockSize(blockSize),
-       fStatus(B_NO_INIT),
-       fEntries(NULL)
-{
-       // TODO: check the correctness of the protective MBR
-
-       // read and check the partition table header
-
-       ssize_t bytesRead = read_pos(fd, block * blockSize, &fHeader,
-               sizeof(fHeader));
-       if (bytesRead != (ssize_t)sizeof(fHeader)) {
-               if (bytesRead < B_OK)
-                       fStatus = bytesRead;
-               else
-                       fStatus = B_IO_ERROR;
-
-               return;
-       }
-
-       if (memcmp(fHeader.header, EFI_PARTITION_HEADER, sizeof(fHeader.header))
-               || !_ValidateCRC((uint8 *)&fHeader, sizeof(fHeader))
-               || fHeader.AbsoluteBlock() != fBlock) {
-               // TODO: check that partition counts are in valid bounds
-               fStatus = B_BAD_DATA;
-               return;
-       }
-
-       // allocate, read, and check partition entry array
-
-       fEntries = new (std::nothrow) uint8[_EntryArraySize()];
-       if (fEntries == NULL) {
-               // TODO: if there cannot be allocated enough (ie. the boot 
loader's
-               //      heap is limited), try a smaller size before failing
-               fStatus = B_NO_MEMORY;
-               return;
-       }
-
-       bytesRead = read_pos(fd, fHeader.EntriesBlock() * blockSize,
-               fEntries, _EntryArraySize());
-       if (bytesRead != (ssize_t)_EntryArraySize()) {
-               if (bytesRead < B_OK)
-                       fStatus = bytesRead;
-               else
-                       fStatus = B_IO_ERROR;
-
-               return;
-       }
-
-       if (!_ValidateCRC(fEntries, _EntryArraySize())) {
-               // TODO: check overlapping or out of range partitions
-               fStatus = B_BAD_DATA;
-               return;
-       }
-
-#ifdef TRACE_EFI_GPT
-       _Dump();
-       _DumpPartitions();
-#endif
-
-       fStatus = B_OK;
-}
-
-
-#ifndef _BOOT_MODE
-Header::Header(off_t block, uint32 blockSize)
-       :
-       fBlock(block),
-       fBlockSize(blockSize),
-       fStatus(B_NO_INIT),
-       fEntries(NULL)
-{
-       // initialize to an empty header
-       memcpy(fHeader.header, EFI_PARTITION_HEADER, sizeof(fHeader.header));
-       fHeader.SetRevision(EFI_TABLE_REVISION);
-       fHeader.SetHeaderSize(sizeof(fHeader));
-       fHeader.SetHeaderCRC(0);
-       fHeader.SetAbsoluteBlock(fBlock);
-       fHeader.SetAlternateBlock(0); // TODO
-       // TODO: set disk guid
-       fHeader.SetEntriesBlock(EFI_PARTITION_ENTRIES_BLOCK);
-       fHeader.SetEntryCount(EFI_PARTITION_ENTRY_COUNT);
-       fHeader.SetEntrySize(EFI_PARTITION_ENTRY_SIZE);
-       fHeader.SetEntriesCRC(0);
-
-       size_t arraySize = _EntryArraySize();
-       fEntries = new (std::nothrow) uint8[arraySize];
-       if (fEntries == NULL) {
-               fStatus = B_NO_MEMORY;
-               return;
-       }
-
-       memset(fEntries, 0, arraySize);
-               // TODO: initialize the entry guids
-
-       fHeader.SetFirstUsableBlock(EFI_PARTITION_ENTRIES_BLOCK
-               + (arraySize + fBlockSize - 1) / fBlockSize);
-       fHeader.SetLastUsableBlock(0); // TODO
-
-#ifdef TRACE_EFI_GPT
-       _Dump();
-       _DumpPartitions();
-#endif
-
-       fStatus = B_OK;
-}
-#endif // !_BOOT_MODE
-
-
-Header::~Header()
-{
-       delete[] fEntries;
-}
-
-
-status_t
-Header::InitCheck() const
-{
-       return fStatus;
-}
-
-
-#ifndef _BOOT_MODE
-status_t
-Header::WriteEntry(int fd, uint32 entryIndex)
-{
-       // TODO: implement
-       return B_ERROR;
-}
-
-
-status_t
-Header::Write(int fd)
-{
-       // TODO: implement
-       return B_ERROR;
-}
-#endif // !_BOOT_MODE
-
-
-bool
-Header::_ValidateCRC(uint8 *data, size_t size) const
-{
-       // TODO: implement!
-       return true;
-}
-
-
-#ifdef TRACE_EFI_GPT
-const char *
-Header::_PrintGUID(const guid_t &id)
-{
-       static char guid[48];
-       snprintf(guid, sizeof(guid),
-               "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-               B_LENDIAN_TO_HOST_INT32(id.data1), 
B_LENDIAN_TO_HOST_INT16(id.data2),
-               B_LENDIAN_TO_HOST_INT16(id.data3), id.data4[0], id.data4[1],
-               id.data4[2], id.data4[3], id.data4[4], id.data4[5], id.data4[6],
-               id.data4[7]);
-       return guid;
-}
-
-
-void
-Header::_Dump()
-{
-       dprintf("EFI header: %.8s\n", fHeader.header);
-       dprintf("EFI revision: %ld\n", fHeader.Revision());
-       dprintf("header size: %ld\n", fHeader.HeaderSize());
-       dprintf("header CRC: %ld\n", fHeader.HeaderCRC());
-       dprintf("absolute block: %Ld\n", fHeader.AbsoluteBlock());
-       dprintf("alternate block: %Ld\n", fHeader.AlternateBlock());
-       dprintf("first usable block: %Ld\n", fHeader.FirstUsableBlock());
-       dprintf("last usable block: %Ld\n", fHeader.LastUsableBlock());
-       dprintf("disk GUID: %s\n", _PrintGUID(fHeader.disk_guid));
-       dprintf("entries block: %Ld\n", fHeader.EntriesBlock());
-       dprintf("entry size:  %ld\n", fHeader.EntrySize());
-       dprintf("entry count: %ld\n", fHeader.EntryCount());
-       dprintf("entries CRC: %ld\n", fHeader.EntriesCRC());
-}
-
-
-void
-Header::_DumpPartitions()
-{
-       for (uint32 i = 0; i < EntryCount(); i++) {
-               const efi_partition_entry &entry = EntryAt(i);
-
-               if (entry.partition_type == kEmptyGUID)
-                       continue;
-
-               dprintf("[%3ld] partition type: %s\n", i,
-                       _PrintGUID(entry.partition_type));
-               dprintf("      unique id: %s\n", _PrintGUID(entry.unique_guid));
-               dprintf("      start block: %Ld\n", entry.StartBlock());
-               dprintf("      end block: %Ld\n", entry.EndBlock());
-               dprintf("      size: %g MB\n", (entry.EndBlock() - 
entry.StartBlock())
-                       * 512 / 1024.0 / 1024.0);
-               dprintf("      attributes: %Lx\n", entry.Attributes());
-
-               char name[64];
-               to_utf8(entry.name, EFI_PARTITION_NAME_LENGTH, name, 
sizeof(name));
-               dprintf("      name: %s\n", name);
-       }
-}
-#endif // TRACE_EFI_GPT
-
-}      // namespace EFI
-
-
 //     #pragma mark - public module interface
 
 
@@ -1063,7 +697,8 @@ efi_gpt_initialize(int fd, partition_id partitionID, const 
char *name,
 
        update_disk_device_job_progress(job, 0.0);
 
-       EFI::Header header(EFI_HEADER_LOCATION, partition->block_size);
+       EFI::Header header(EFI_HEADER_LOCATION,
+               partitionSize / partition->block_size, partition->block_size);
        status_t result = header.InitCheck();
        if (result != B_OK)
                return result;
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/gpt_known_guids.h 
b/src/add-ons/kernel/partitioning_systems/gpt/gpt_known_guids.h
index 6f450a2..1fb1cef 100644
--- a/src/add-ons/kernel/partitioning_systems/gpt/gpt_known_guids.h
+++ b/src/add-ons/kernel/partitioning_systems/gpt/gpt_known_guids.h
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009, Michael Lotz, mmlr@xxxxxxxx. All rights reserved.
- * Copyright 2007-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2007-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  *
  * Distributed under the terms of the MIT License.
  */
@@ -8,6 +8,8 @@
 #define GPT_KNOWN_GUIDS_H
 
 
+#include <ByteOrder.h>
+
 #include <disk_device_types.h>
 
 
@@ -24,6 +26,17 @@ struct static_guid {
 } _PACKED;
 
 
+inline bool
+static_guid::operator==(const guid_t &other) const
+{
+       return B_HOST_TO_LENDIAN_INT32(data1) == other.data1
+               && B_HOST_TO_LENDIAN_INT16(data2) == other.data2
+               && B_HOST_TO_LENDIAN_INT16(data3) == other.data3
+               && B_HOST_TO_BENDIAN_INT64(*(uint64 *)&data4) == *(uint64 
*)other.data4;
+                       // the last 8 bytes are in big-endian order
+}
+
+
 const static struct type_map {
        static_guid     guid;
        const char      *type;
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/utility.cpp 
b/src/add-ons/kernel/partitioning_systems/gpt/utility.cpp
new file mode 100644
index 0000000..c43718d
--- /dev/null
+++ b/src/add-ons/kernel/partitioning_systems/gpt/utility.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2007-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2009, Michael Lotz, mmlr@xxxxxxxx. All rights reserved.
+ *
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "utility.h"
+
+#include <string.h>
+
+#ifndef _BOOT_MODE
+#      include <utf8_functions.h>
+#endif
+
+#include "gpt_known_guids.h"
+
+
+const guid_t kEmptyGUID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
+
+
+static void
+put_utf8_byte(char *&to, size_t &left, char c)
+{
+       if (left <= 1)
+               return;
+
+       *(to++) = c;
+       left--;
+}
+
+
+// #pragma mark -
+
+
+void
+to_utf8(const uint16 *from, size_t maxFromLength, char *to, size_t toSize)
+{
+       for (uint32 i = 0; i < maxFromLength; i++) {
+               uint16 c = B_LENDIAN_TO_HOST_INT16(from[i]);
+               if (!c)
+                       break;
+
+               if (c < 0x80)
+                       put_utf8_byte(to, toSize, c);
+               else if (c < 0x800) {
+                       put_utf8_byte(to, toSize, 0xc0 | (c >> 6));
+                       put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
+               } else if (c < 0x10000) {
+                       put_utf8_byte(to, toSize, 0xe0 | (c >> 12));
+                       put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f));
+                       put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
+               } else if (c <= 0x10ffff) {
+                       put_utf8_byte(to, toSize, 0xf0 | (c >> 18));
+                       put_utf8_byte(to, toSize, 0x80 | ((c >> 12) & 0x3f));
+                       put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f));
+                       put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
+               }
+       }
+
+       if (toSize > 0)
+               *to = '\0';
+}
+
+
+#ifndef _BOOT_MODE
+void
+to_ucs2(const char *from, size_t fromLength, uint16 *to, size_t maxToLength)
+{
+       size_t index = 0;
+       while (from[0] && index < maxToLength) {
+               // TODO: handle characters that are not representable in UCS-2 
better
+               uint32 code = UTF8ToCharCode(&from);
+               if (code < 0x10000)
+                       to[index++] = code;
+       }
+
+       if (index < maxToLength)
+               to[index] = '\0';
+}
+#endif // !_BOOT_MODE
+
+
+const char *
+get_partition_type(const guid_t &guid)
+{
+       for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) {
+               if (kTypeMap[i].guid == guid)
+                       return kTypeMap[i].type;
+       }
+
+       return NULL;
+}
+
+
+#ifndef _BOOT_MODE
+const static_guid *
+guid_for_partition_type(const char *type)
+{
+       for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) {
+               if (strcmp(kTypeMap[i].type, type) == 0)
+                       return &kTypeMap[i].guid;
+       }
+
+       return NULL;
+}
+#endif // !_BOOT_MODE
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/utility.h 
b/src/add-ons/kernel/partitioning_systems/gpt/utility.h
new file mode 100644
index 0000000..17f9fe0
--- /dev/null
+++ b/src/add-ons/kernel/partitioning_systems/gpt/utility.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2007-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2009, Michael Lotz, mmlr@xxxxxxxx. All rights reserved.
+ *
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef UTILITY_H
+#define UTILITY_H
+
+
+#include <SupportDefs.h>
+
+#include "guid.h"
+
+
+struct static_guid;
+
+extern const guid_t kEmptyGUID;
+
+
+void to_utf8(const uint16* from, size_t maxFromLength, char* to, size_t 
toSize);
+const char* get_partition_type(const guid_t& guid);
+
+#ifndef _BOOT_MODE
+void to_ucs2(const char* from, size_t fromLength, uint16* to,
+       size_t maxToLength);
+const static_guid* guid_for_partition_type(const char* type);
+#endif // !_BOOT_MODE
+
+
+#endif // UTILITY_H
diff --git a/src/system/boot/loader/Jamfile b/src/system/boot/loader/Jamfile
index a739155..83aabd5 100644
--- a/src/system/boot/loader/Jamfile
+++ b/src/system/boot/loader/Jamfile
@@ -88,7 +88,12 @@ BootStaticLibrary boot_partitions :
        FileMapDisk.cpp
        amiga_rdb.cpp
        apple.cpp
+
        efi_gpt.cpp
+       Header.cpp
+       crc32.cpp
+       utility.cpp
+
        intel.cpp
        PartitionMap.cpp
        PartitionMapParser.cpp
@@ -114,7 +119,7 @@ SEARCH on [ FGristFiles amiga_rdb.cpp ]
 SEARCH on [ FGristFiles apple.cpp ]
     = [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems apple ] ;
 
-SEARCH on [ FGristFiles efi_gpt.cpp ]
+SEARCH on [ FGristFiles efi_gpt.cpp Header.cpp crc32.cpp utility.cpp ]
     = [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems gpt ] ;
 
 SEARCH on [ FGristFiles intel.cpp PartitionMap.cpp PartitionMapParser.cpp ]
diff --git a/src/tests/system/boot/loader/Jamfile 
b/src/tests/system/boot/loader/Jamfile
index 5d9c06d..c4b084d 100644
--- a/src/tests/system/boot/loader/Jamfile
+++ b/src/tests/system/boot/loader/Jamfile
@@ -43,7 +43,12 @@ ObjectDefines
        # partitions
        amiga_rdb.cpp
        apple.cpp
+
        efi_gpt.cpp
+       Header.cpp
+       crc32.cpp
+       utility.cpp
+
        intel.cpp
        PartitionMap.cpp
        PartitionMapParser.cpp
@@ -71,6 +76,7 @@ ObjectDefines
        defines = [ FDefines $(defines) ] ;
 
        if $(OS) = "LINUX" {
+               SubDirC++Flags $(defines) ;
        } else {
                #SubDirC++Flags $(defines) -DHAVE_READ_POS=1 
-fcheck-memory-usage -D_NO_INLINE_ASM ;
                SubDirC++Flags $(defines) -DHAVE_READ_POS=1 -D_NO_INLINE_ASM ;
@@ -104,7 +110,12 @@ SimpleTest BootLoaderTest :
        # partitioning systems
        amiga_rdb.cpp
        apple.cpp
+
        efi_gpt.cpp
+       Header.cpp
+       crc32.cpp
+       utility.cpp
+
        intel.cpp
        PartitionMap.cpp
        PartitionMapParser.cpp
@@ -149,7 +160,7 @@ SEARCH on [ FGristFiles amiga_rdb.cpp ]
 SEARCH on [ FGristFiles apple.cpp ]
        = [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems apple 
] ;
 
-SEARCH on [ FGristFiles efi_gpt.cpp ]
+SEARCH on [ FGristFiles efi_gpt.cpp Header.cpp crc32.cpp utility.cpp ]
        = [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems gpt ] 
;
 
 SEARCH on [ FGristFiles intel.cpp PartitionMap.cpp PartitionMapParser.cpp ]

############################################################################

Revision:    hrev45205
Commit:      9e8d42ac443b81b85d608cdbc8c8f809e8aad79a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=9e8d42a
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Sat Jan 26 00:33:27 2013 UTC

Work in progress in getting GPTPartitionHandle working.

* Tried to use EFI::Header class, but there doesn't seem to be an easy
  way to actually hit the disk -- which we'll have to do to find out
  how large the GPT table is.
* Initialization of GPT disks is now working which is why I added the disk
  system add-on to the image. However, there is a caveat, as the backup
  header and table aren't written yet.
* Partitions can be deleted.
* Creating partitions does not work yet, but I don't know yet why; in
  theory it could already work.

----------------------------------------------------------------------------

diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage
index b943411..d2486b4 100644
--- a/build/jam/HaikuImage
+++ b/build/jam/HaikuImage
@@ -678,7 +678,7 @@ AddFilesToHaikuImage system add-ons Screen\ Savers
        : $(SYSTEM_ADD_ONS_SCREENSAVERS) ;
 
 AddFilesToHaikuImage system add-ons disk_systems
-       : <disk_system>intel <disk_system>bfs <disk_system>ntfs ;
+       : <disk_system>intel <disk_system>gpt <disk_system>bfs 
<disk_system>ntfs ;
 
 # decorators
 AddDirectoryToHaikuImage home config add-ons decorators ;
diff --git a/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef 
b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef
index 18ca93a..41771bd 100644
--- a/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef
+++ b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef
@@ -1,8 +1,4 @@
-/*
- * IntelDiskAddOn.rdef
- */
-
-resource app_signature "application/x-vnd.Haiku-IntelDiskAddOn";
+resource app_signature "application/x-vnd.Haiku-GPTDiskAddOn";
 
 resource app_version {
        major  = 1,
@@ -11,5 +7,5 @@ resource app_version {
        variety = 0,
        internal = 0,
        short_info = "1.0.0",
-       long_info = "Haiku Intel disk add-on."
+       long_info = "GUID Partition Table disk add-on."
 };
diff --git a/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp 
b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp
index 8efba51..66227fe 100644
--- a/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp
+++ b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright 2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2007, Ingo Weinhold, bonefish@xxxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -13,6 +14,7 @@
 #include <MutablePartition.h>
 #include <PartitioningInfo.h>
 #include <PartitionParameterEditor.h>
+#include <Path.h>
 
 #include <AutoDeleter.h>
 
@@ -43,6 +45,23 @@ GPTPartitionHandle::~GPTPartitionHandle()
 status_t
 GPTPartitionHandle::Init()
 {
+       // TODO: how to get the path of a BMutablePartition?
+       //BPath path;
+       //status_t status = Partition()->GetPath(&path);
+       //if (status != B_OK)
+               //return status;
+
+       //fd = open(path.Path(), O_RDONLY);
+       //if (fd < 0)
+               //return errno;
+
+       //fHeader = new EFI::Header(fd, Partition()->BlockSize(),
+               //Partition()->BlockSize());
+       //status = fHeader->InitCheck();
+       //if (status != B_OK)
+               //return status;
+
+       //close(fd);
        return B_OK;
 }
 
@@ -100,10 +119,12 @@ GPTPartitionHandle::GetNextSupportedType(const 
BMutablePartition* child,
 status_t
 GPTPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
 {
-       // init to the full size (minus the first sector)
+       // init to the full size (minus the GPT table header and entries)
        off_t size = Partition()->ContentSize();
-       status_t status = info->SetTo(Partition()->BlockSize(),
-               size - Partition()->BlockSize());
+       // TODO: use fHeader
+       size_t headerSize = Partition()->BlockSize() + 16384;
+       status_t status = info->SetTo(Partition()->BlockSize() + headerSize,
+               size - Partition()->BlockSize() - 2 * headerSize);
        if (status != B_OK)
                return status;
 
@@ -141,7 +162,7 @@ status_t
 GPTPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size,
        const char* typeString, BString* name, const char* parameters)
 {
-       return B_BAD_VALUE;
+       return B_OK;
 }
 
 
@@ -150,7 +171,21 @@ GPTPartitionHandle::CreateChild(off_t offset, off_t size,
        const char* typeString, const char* name, const char* parameters,
        BMutablePartition** _child)
 {
-       return B_BAD_VALUE;
+       // create the child
+       BMutablePartition* partition = Partition();
+       BMutablePartition* child;
+       status_t status = partition->CreateChild(0, typeString, name,
+               parameters, &child);
+       if (status != B_OK)
+               return status;
+
+       // init the child
+       child->SetOffset(offset);
+       child->SetSize(size);
+       child->SetBlockSize(partition->BlockSize());
+
+       *_child = child;
+       return B_OK;
 }
 
 
diff --git a/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h 
b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h
index 23fbf14..c743bd0 100644
--- a/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h
+++ b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h
@@ -8,6 +8,8 @@
 
 #include <DiskSystemAddOn.h>
 
+#include "Header.h"
+
 
 class GPTPartitionHandle : public BPartitionHandle {
 public:
@@ -39,6 +41,9 @@ public:
                                                                        const 
char* parameters,
                                                                        
BMutablePartition** child);
        virtual status_t                        DeleteChild(BMutablePartition* 
child);
+
+private:
+                       EFI::Header*            fHeader;
 };
 
 
diff --git a/src/add-ons/disk_systems/gpt/Jamfile 
b/src/add-ons/disk_systems/gpt/Jamfile
index 2083ced..5174bc5 100644
--- a/src/add-ons/disk_systems/gpt/Jamfile
+++ b/src/add-ons/disk_systems/gpt/Jamfile
@@ -1,6 +1,6 @@
 SubDir HAIKU_TOP src add-ons disk_systems gpt ;
 
-UsePrivateHeaders shared storage ;
+UsePrivateHeaders interface shared storage ;
 UsePrivateSystemHeaders ;
 
 SEARCH_SOURCE
@@ -13,5 +13,10 @@ Addon <disk_system>gpt :
        GPTDiskAddOn.cpp
        GPTPartitionHandle.cpp
 
+       # from the kernel partitioning system add-on
+       Header.cpp
+       crc32.cpp
+       utility.cpp
+
        : be $(TARGET_LIBSUPC++)
 ;


Other related posts:

  • » [haiku-commits] haiku: hrev45205 - in src/add-ons: kernel/partitioning_systems/gpt disk_systems/gpt - axeld