diff --git a/metropolis/pkg/gpt/gpt.go b/metropolis/pkg/gpt/gpt.go
new file mode 100644
index 0000000..5660237
--- /dev/null
+++ b/metropolis/pkg/gpt/gpt.go
@@ -0,0 +1,727 @@
+// Package gpt implements reading and writing GUID Partition Tables as specified
+// in the UEFI Specification. It only implements up to 128 partitions per table
+// (same as most other implementations) as more would require a dynamic table
+// size, significantly complicating the code for little gain.
+package gpt
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"hash/crc32"
+	"io"
+	"sort"
+	"strings"
+	"unicode/utf16"
+
+	"github.com/google/uuid"
+)
+
+var gptSignature = [8]byte{'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T'}
+var gptRevision uint32 = 0x00010000 // First 2 bytes major, second 2 bytes minor
+
+// See UEFI Specification 2.9 Table 5-5
+type header struct {
+	Signature   [8]byte
+	Revision    uint32
+	HeaderSize  uint32
+	HeaderCRC32 uint32
+	_           [4]byte
+
+	HeaderBlock          uint64
+	AlternateHeaderBlock uint64
+	FirstUsableBlock     uint64
+	LastUsableBlock      uint64
+
+	ID [16]byte
+
+	PartitionEntriesStartBlock uint64
+	PartitionEntryCount        uint32
+	PartitionEntrySize         uint32
+	PartitionEntriesCRC32      uint32
+}
+
+// See UEFI Specification 2.9 Table 5-6
+type partition struct {
+	Type       [16]byte
+	ID         [16]byte
+	FirstBlock uint64
+	LastBlock  uint64
+	Attributes uint64
+	Name       [36]uint16
+}
+
+var (
+	PartitionTypeEFISystem = uuid.MustParse("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")
+)
+
+var zeroUUID = [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+// Attribute is a bitfield of attributes set on a partition. Bits 0 to 47 are
+// reserved for UEFI specification use and all current assignments are in the
+// following const block. Bits 48 to 64 are available for per-Type use by
+// the organization controlling the partition Type.
+type Attribute uint64
+
+const (
+	// AttrRequiredPartition indicates that this partition is required for the
+	// platform to function. Mostly used by vendors to mark things like recovery
+	// partitions.
+	AttrRequiredPartition = 1 << 0
+	// AttrNoBlockIOProto indicates that EFI firmware must not provide an EFI
+	// block device (EFI_BLOCK_IO_PROTOCOL) for this partition.
+	AttrNoBlockIOProto = 1 << 1
+	// AttrLegacyBIOSBootable indicates to special-purpose software outside of
+	// UEFI that this partition can be booted using a traditional PC BIOS.
+	// Don't use this unless you know that you need it specifically.
+	AttrLegacyBIOSBootable = 1 << 2
+)
+
+// PerTypeAttrs returns the top 24 bits which are reserved for custom per-Type
+// attributes. The top 8 bits of the returned uint32 are always 0.
+func (a Attribute) PerTypeAttrs() uint32 {
+	return uint32(a >> 48)
+}
+
+// SetPerTypeAttrs sets the top 24 bits which are reserved for custom per-Type
+// attributes. It does not touch the lower attributes which are specified by the
+// UEFI specification. The top 8 bits of v are silently discarded.
+func (a *Attribute) SetPerTypeAttrs(v uint32) {
+	*a &= 0x000000FF_FFFFFFFF
+	*a |= Attribute(v) << 48
+}
+
+type Partition struct {
+	// Name of the partition, will be truncated if it expands to more than 36
+	// UTF-16 code points. Not all systems can display non-BMP code points.
+	Name string
+	// Type is the type of Table partition, can either be one of the predefined
+	// constants by the UEFI specification or a custom type identifier.
+	// Note that the all-zero UUID denotes an empty partition slot, so this
+	// MUST be set to something, otherwise it is not treated as a partition.
+	Type uuid.UUID
+	// ID is a unique identifier for this specific partition. It should be
+	// changed when cloning the partition.
+	ID uuid.UUID
+	// The first logical block of the partition (inclusive)
+	FirstBlock uint64
+	// The last logical block of the partition (inclusive)
+	LastBlock uint64
+	// Bitset of attributes of this partition.
+	Attributes Attribute
+}
+
+// SizeBlocks returns the size of the partition in blocks
+func (p *Partition) SizeBlocks() uint64 {
+	return 1 + p.LastBlock - p.FirstBlock
+}
+
+// IsUnused checks if the partition is unused, i.e. it is nil or its type is
+// the null UUID.
+func (p *Partition) IsUnused() bool {
+	if p == nil {
+		return true
+	}
+	return p.Type == zeroUUID
+}
+
+type Table struct {
+	// ID is the unique identifier of this specific disk / GPT.
+	// If this is left uninitialized/all-zeroes a new random ID is automatically
+	// generated when writing.
+	ID uuid.UUID
+
+	// Data put at the start of the very first block. Gets loaded and executed
+	// by a legacy BIOS bootloader. This can be used to make GPT-partitioned
+	// disks bootable by legacy systems or display a nice error message.
+	// Maximum length is 440 bytes, if that is exceeded Write returns an error.
+	// Should be left empty if the device is not bootable and/or compatibility
+	// with BIOS booting is not required. Only useful on x86 systems.
+	BootCode []byte
+
+	// BlockSize contains the logical block size of the block device. It must
+	// be a power of two equal to or larger than 512.
+	BlockSize int64
+	// BlockCount contains the number of logical blocks on the block device.
+	// BlockCount times BlockSize is the size of the block device in bytes.
+	BlockCount int64
+
+	// Partitions contains the list of partitions in this table. This is
+	// artificially limited to 128 partitions.
+	Partitions []*Partition
+}
+type addOptions struct {
+	preferEnd        bool
+	keepEmptyEntries bool
+	alignment        int64
+}
+
+// AddOption is a bitset controlling various
+type AddOption func(*addOptions)
+
+// WithPreferEnd tries to put the partition as close to the end as possible
+// instead of as close to the start.
+func WithPreferEnd() AddOption {
+	return func(options *addOptions) {
+		options.preferEnd = true
+	}
+}
+
+// WithKeepEmptyEntries does not fill up empty entries which are followed by
+// filled ones. It always appends the partition after the last used entry.
+// Without this flag, the partition is placed in the first empty entry.
+func WithKeepEmptyEntries() AddOption {
+	return func(options *addOptions) {
+		options.keepEmptyEntries = true
+	}
+}
+
+// WithAlignment allows aligning the partition start block to a non-default
+// value. By default, these are aligned to 1MiB.
+//  Only use this flag if you are certain you need it, it can cause quite severe
+// performance degradation under certain conditions.
+func WithAlignment(alignmenet int64) AddOption {
+	return func(options *addOptions) {
+		options.alignment = alignmenet
+	}
+}
+
+// AddPartition takes a pointer to a partition and adds it, placing it into
+// the first (or last using WithPreferEnd) continuous free space which fits it.
+// It writes the placement information (FirstBlock, LastBlock) back to p.
+// By default, AddPartition aligns FirstBlock to 1MiB boundaries, but this can
+// be overridden using WithAlignment.
+func (g *Table) AddPartition(p *Partition, size int64, options ...AddOption) error {
+	if g.BlockSize < 512 {
+		return errors.New("block size is smaller than 512 bytes, this is unsupported")
+	}
+	var opts addOptions
+	// Align to 1MiB or the block size, whichever is bigger
+	opts.alignment = 1 * 1024 * 1024
+	if g.BlockSize > opts.alignment {
+		opts.alignment = g.BlockSize
+	}
+	for _, o := range options {
+		o(&opts)
+	}
+	if opts.alignment%g.BlockSize != 0 {
+		return fmt.Errorf("requested alignment (%d bytes) is not an integer multiple of the block size (%d), unable to align", opts.alignment, g.BlockSize)
+	}
+	// Number of blocks the partition should occupy, rounded up.
+	blocks := (size + g.BlockSize - 1) / g.BlockSize
+	fs, _, err := g.GetFreeSpaces()
+	if err != nil {
+		return fmt.Errorf("unable to determine free space: %v", err)
+	}
+	if opts.preferEnd {
+		// Reverse fs slice to start iteration at the end
+		for i, j := 0, len(fs)-1; i < j; i, j = i+1, j-1 {
+			fs[i], fs[j] = fs[j], fs[i]
+		}
+	}
+	var maxFreeBlocks int64
+	for _, freeInt := range fs {
+		start := freeInt[0]
+		end := freeInt[1]
+		freeBlocks := end - start
+		// Align start properly
+		paddingBlocks := (-start) % (opts.alignment / g.BlockSize)
+		freeBlocks -= paddingBlocks
+		start += paddingBlocks
+		if maxFreeBlocks < freeBlocks {
+			maxFreeBlocks = freeBlocks
+		}
+		if freeBlocks >= blocks {
+			if !opts.preferEnd {
+				p.FirstBlock = uint64(start)
+				p.LastBlock = uint64(start + blocks)
+			} else {
+				// Realign FirstBlock. This will always succeed as
+				// there is enough space to align to the start.
+				moveLeft := (end - blocks - 1) % (opts.alignment / g.BlockSize)
+				p.FirstBlock = uint64(end - (blocks + 1 + moveLeft))
+				p.LastBlock = uint64(end - (1 + moveLeft))
+			}
+			newPartPos := -1
+			if !opts.keepEmptyEntries {
+				for i, part := range g.Partitions {
+					if part.IsUnused() {
+						newPartPos = i
+						break
+					}
+				}
+			}
+			if newPartPos == -1 {
+				g.Partitions = append(g.Partitions, p)
+			} else {
+				g.Partitions[newPartPos] = p
+			}
+			return nil
+		}
+	}
+
+	return fmt.Errorf("no space for partition of %d blocks, largest continuous free space after alignment is %d blocks", blocks, maxFreeBlocks)
+}
+
+// FirstUsableBlock returns the first usable (i.e. a partition can start there)
+// block.
+func (g *Table) FirstUsableBlock() int64 {
+	partitionEntryBlocks := (16384 + g.BlockSize - 1) / g.BlockSize
+	return 2 + partitionEntryBlocks
+}
+
+// LastUsableBlock returns the last usable (i.e. a partition can end there)
+// block. This block is inclusive.
+func (g *Table) LastUsableBlock() int64 {
+	partitionEntryBlocks := (16384 + g.BlockSize - 1) / g.BlockSize
+	return g.BlockCount - (2 + partitionEntryBlocks)
+}
+
+// GetFreeSpaces returns a slice of tuples, each containing a half-closed
+// interval of logical blocks not occupied by the GPT itself or any partition.
+// The returned intervals are always in ascending order as well as
+// non-overlapping. It also returns if it detected any overlaps between
+// partitions or partitions and the GPT. It returns an error if and only if any
+// partition has its FirstBlock before the LastBlock or exceeds the amount of
+// blocks on the block device.
+//
+// Note that the most common use cases for this function are covered by
+// AddPartition, you're encouraged to use it instead.
+func (g *Table) GetFreeSpaces() ([][2]int64, bool, error) {
+	// This implements an efficient algorithm for finding free intervals given
+	// a set of potentially overlapping occupying intervals. It uses O(n*log n)
+	// time for n being the amount of intervals, i.e. partitions. It uses O(n)
+	// additional memory. This makes it de facto infinitely scalable in the
+	// context of partition tables as the size of the block device is not part
+	// of its cyclomatic complexity and O(n*log n) is tiny for even very big
+	// partition tables.
+
+	// startBlocks contains the start blocks (inclusive) of all occupied
+	// intervals.
+	var startBlocks []int64
+	// endBlocks contains the end blocks (exclusive!) of all occupied intervals.
+	// The interval at index i is given by [startBlock[i], endBlock[i]).
+	var endBlocks []int64
+
+	// Reserve the primary GPT interval including the protective MBR.
+	startBlocks = append(startBlocks, 0)
+	endBlocks = append(endBlocks, g.FirstUsableBlock())
+
+	// Reserve the alternate GPT interval (needs +1 for exclusive interval)
+	startBlocks = append(startBlocks, g.LastUsableBlock()+1)
+	endBlocks = append(endBlocks, g.BlockCount)
+
+	for i, part := range g.Partitions {
+		if part.IsUnused() {
+			continue
+		}
+		// Bail if partition does not contain a valid interval. These are open
+		// intervals, thus part.FirstBlock == part.LastBlock denotes a valid
+		// partition with a size of one block.
+		if part.FirstBlock > part.LastBlock {
+			return nil, false, fmt.Errorf("partition %d has a LastBlock smaller than its FirstBlock, its interval is [%d, %d]", i, part.FirstBlock, part.LastBlock)
+		}
+		if part.FirstBlock >= uint64(g.BlockCount) || part.LastBlock >= uint64(g.BlockCount) {
+			return nil, false, fmt.Errorf("partition %d exceeds the block count of the block device", i)
+		}
+		startBlocks = append(startBlocks, int64(part.FirstBlock))
+		// Algorithm needs open-closed intervals, thus add +1 to the end.
+		endBlocks = append(endBlocks, int64(part.LastBlock)+1)
+	}
+	// Sort both sets of blocks independently in ascending order. Note that it
+	// is now no longer possible to extract the original intervals. Integers
+	// have no identity thus it doesn't matter if the sort is stable or not.
+	sort.Slice(startBlocks, func(i, j int) bool { return startBlocks[i] < startBlocks[j] })
+	sort.Slice(endBlocks, func(i, j int) bool { return endBlocks[i] < endBlocks[j] })
+
+	var freeSpaces [][2]int64
+
+	// currentIntervals contains the number of intervals which contain the
+	// position currently being iterated over. If currentIntervals is ever
+	// bigger than 1, there is overlap within the given intervals.
+	currentIntervals := 0
+	var hasOverlap bool
+
+	// Iterate for as long as there are interval boundaries to be processed.
+	for len(startBlocks) != 0 || len(endBlocks) != 0 {
+		// Short-circuit boundary processing. If an interval ends at x and the
+		// next one starts at x (this is using half-open intervals), it would
+		// otherwise perform useless processing as well as create an empty free
+		// interval which would then need to be filtered back out.
+		if len(startBlocks) != 0 && len(endBlocks) != 0 && startBlocks[0] == endBlocks[0] {
+			startBlocks = startBlocks[1:]
+			endBlocks = endBlocks[1:]
+			continue
+		}
+		// Pick the lowest boundary from either startBlocks or endBlocks,
+		// preferring endBlocks if they are equal. Don't try to pick from empty
+		// slices.
+		if (len(startBlocks) != 0 && len(endBlocks) != 0 && startBlocks[0] < endBlocks[0]) || len(endBlocks) == 0 {
+			// If currentIntervals == 0 a free space region ends here.
+			// Since this algorithm creates the free space interval at the end
+			// of an occupied interval, for the first interval there is no free
+			// space entry. But in this case it's fine to just ignore it as the
+			// first interval always starts at 0 because of the GPT.
+			if currentIntervals == 0 && len(freeSpaces) != 0 {
+				freeSpaces[len(freeSpaces)-1][1] = startBlocks[0]
+			}
+			// This is the start of an interval, increase the number of active
+			// intervals.
+			currentIntervals++
+			hasOverlap = hasOverlap || currentIntervals > 1
+			// Drop processed startBlock from slice.
+			startBlocks = startBlocks[1:]
+		} else {
+			// This is the end of an interval, decrease the number of active
+			// intervals.
+			currentIntervals--
+			// If currentIntervals == 0 a free space region starts here.
+			// Same as with the startBlocks, ignore a potential free block after
+			// the final range as the GPT occupies the last blocks anyway.
+			if currentIntervals == 0 && len(startBlocks) != 0 {
+				freeSpaces = append(freeSpaces, [2]int64{endBlocks[0], 0})
+			}
+			endBlocks = endBlocks[1:]
+		}
+	}
+	return freeSpaces, hasOverlap, nil
+}
+
+// Overhead returns the number of blocks the GPT partitioning itself consumes,
+// i.e. aren't usable for user data.
+func Overhead(blockSize int64) int64 {
+	// 3 blocks + 2x 16384 bytes (partition entry space)
+	partitionEntryBlocks := (16384 + blockSize - 1) / blockSize
+	return 3 + (2 * partitionEntryBlocks)
+}
+
+// Write writes a list of GPT partitions with a protective MBR to the given
+// WriteSeeker. It must have a defined end, i.e. w.Seek(-x, io.SeekEnd) must
+// seek to x bytes before the end of the disk. If gpt.ID or any of the
+// partition IDs are the all-zero UUID, a new random one is generated and
+// written back. If the output is supposed to be reproducible, generate the
+// UUIDs beforehand.
+func Write(w io.WriteSeeker, gpt *Table) error {
+	if gpt.BlockSize < 512 {
+		return errors.New("block size is smaller than 512 bytes, this is unsupported")
+	}
+	// Layout looks as follows:
+	// Block 0: Protective MBR
+	// Block 1: GPT Header
+	// Block 2-(16384 bytes): GPT partition entries
+	// Block (16384 bytes)-n: GPT partition entries alternate copy
+	// Block n: GPT Header alternate copy
+	if len(gpt.Partitions) > 128 {
+		return errors.New("Bigger-than default GPTs (>128 partitions) are unimplemented")
+	}
+
+	partitionEntryBlocks := (16384 + gpt.BlockSize - 1) / gpt.BlockSize
+	if gpt.BlockCount < 3+(2*partitionEntryBlocks) {
+		return errors.New("not enough blocks to write GPT")
+	}
+
+	if gpt.ID == zeroUUID {
+		gpt.ID = uuid.New()
+	}
+
+	partSize := binary.Size(partition{})
+	slotCount := 128
+
+	var partitionEntriesData bytes.Buffer
+	for i := 0; i < slotCount; i++ {
+		if len(gpt.Partitions) <= i || gpt.Partitions[i] == nil {
+			partitionEntriesData.Write(make([]byte, partSize))
+			continue
+		}
+		p := gpt.Partitions[i]
+		if p.ID == zeroUUID {
+			p.ID = uuid.New()
+		}
+		rawP := partition{
+			Type:       mangleUUID(p.Type),
+			ID:         mangleUUID(p.ID),
+			FirstBlock: p.FirstBlock,
+			LastBlock:  p.LastBlock,
+			Attributes: uint64(p.Attributes),
+		}
+		nameUTF16 := utf16.Encode([]rune(p.Name))
+		// copy will automatically truncate if target is too short
+		copy(rawP.Name[:], nameUTF16)
+		binary.Write(&partitionEntriesData, binary.LittleEndian, rawP)
+	}
+
+	hdr := header{
+		Signature:  gptSignature,
+		Revision:   gptRevision,
+		HeaderSize: uint32(binary.Size(&header{})),
+		ID:         mangleUUID(gpt.ID),
+
+		PartitionEntryCount: uint32(slotCount),
+		PartitionEntrySize:  uint32(partSize),
+
+		FirstUsableBlock: uint64(2 + partitionEntryBlocks),
+		LastUsableBlock:  uint64(gpt.BlockCount - (2 + partitionEntryBlocks)),
+	}
+	hdr.PartitionEntriesCRC32 = crc32.ChecksumIEEE(partitionEntriesData.Bytes())
+
+	hdrChecksum := crc32.NewIEEE()
+
+	// Write alternate header first, as otherwise resizes are unsafe. If the
+	// alternate is currently not at the end of the block device, it cannot
+	// be found. Thus if the write operation is aborted abnormally, the
+	// primary GPT is corrupted and the alternate cannot be found because it
+	// is not at its canonical location. Rewriting the alternate first avoids
+	// this problem.
+
+	// Alternate header
+	if _, err := w.Seek((gpt.LastUsableBlock()+1)*gpt.BlockSize, io.SeekStart); err != nil {
+		return fmt.Errorf("failed to seek to end of block device: %w", err)
+	}
+	hdr.HeaderBlock = uint64(gpt.BlockCount - 1)
+	hdr.AlternateHeaderBlock = 1
+	hdr.PartitionEntriesStartBlock = uint64(gpt.BlockCount - (1 + partitionEntryBlocks))
+
+	hdrChecksum.Reset()
+	hdr.HeaderCRC32 = 0
+	binary.Write(hdrChecksum, binary.LittleEndian, &hdr)
+	hdr.HeaderCRC32 = hdrChecksum.Sum32()
+
+	if _, err := w.Write(partitionEntriesData.Bytes()); err != nil {
+		return fmt.Errorf("failed to write alternate partition entries: %w", err)
+	}
+	if _, err := w.Seek((gpt.BlockCount-1)*gpt.BlockSize, io.SeekStart); err != nil {
+		return fmt.Errorf("failed to seek to end of block device: %w", err)
+	}
+
+	if err := binary.Write(w, binary.LittleEndian, &hdr); err != nil {
+		return fmt.Errorf("failed to write alternate header: %w", err)
+	}
+	if _, err := w.Write(make([]byte, gpt.BlockSize-int64(binary.Size(hdr)))); err != nil {
+		return fmt.Errorf("failed to write padding: %v", err)
+	}
+
+	// Primary header
+	if _, err := w.Seek(0, io.SeekStart); err != nil {
+		return fmt.Errorf("failed to seek to end of block device: %w", err)
+	}
+	hdr.HeaderBlock = 1
+	hdr.AlternateHeaderBlock = uint64(gpt.BlockCount - 1)
+	hdr.PartitionEntriesStartBlock = 2
+
+	hdrChecksum.Reset()
+	hdr.HeaderCRC32 = 0
+	binary.Write(hdrChecksum, binary.LittleEndian, &hdr)
+	hdr.HeaderCRC32 = hdrChecksum.Sum32()
+
+	if err := makeProtectiveMBR(w, gpt.BlockCount, gpt.BootCode); err != nil {
+		return fmt.Errorf("failed to write first block: %w", err)
+	}
+
+	if err := binary.Write(w, binary.LittleEndian, &hdr); err != nil {
+		return fmt.Errorf("failed to write primary header: %w", err)
+	}
+	if _, err := w.Write(make([]byte, gpt.BlockSize-int64(binary.Size(hdr)))); err != nil {
+		return fmt.Errorf("failed to write padding: %v", err)
+	}
+	if _, err := w.Write(partitionEntriesData.Bytes()); err != nil {
+		return fmt.Errorf("failed to write primary partition entries: %w", err)
+	}
+	return nil
+}
+
+// Read reads a Table from a block device given its block size and count.
+func Read(r io.ReadSeeker, blockSize int64, blockCount int64) (*Table, error) {
+	if Overhead(blockSize) > blockCount {
+		return nil, errors.New("disk cannot contain a GPT as the block count is too small to store one")
+	}
+	if _, err := r.Seek(0, io.SeekStart); err != nil {
+		return nil, fmt.Errorf("failed to seek to block 0: %w", err)
+	}
+	zeroBlock := make([]byte, blockSize)
+	if _, err := io.ReadFull(r, zeroBlock); err != nil {
+		return nil, fmt.Errorf("failed to read first two blocks: %w", err)
+	}
+
+	var m mbr
+	if err := binary.Read(bytes.NewReader(zeroBlock[:512]), binary.LittleEndian, &m); err != nil {
+		panic(err) // Read is from memory and with enough data
+	}
+	// The UEFI standard says that the only acceptable MBR for a GPT-partitioned
+	// device is a pure protective MBR with one partition of type 0xEE covering
+	// the entire disk. But reality is sadly not so simple. People have come up
+	// with hacks like Hybrid MBR which is basically a way to expose partitions
+	// as both GPT partitions and MBR partitions. There are also GPTs without
+	// any MBR at all.
+	// Following the standard strictly when reading means that this library
+	// would fail to read valid GPT disks where such schemes are employed.
+	// On the other hand just looking at the GPT signature is also dangerous
+	// as not all tools clear the second block where the GPT resides when
+	// writing an MBR, which results in reading a wrong/obsolete GPT.
+	// As a pragmatic solution this library treats any disk as GPT-formatted if
+	// the first block does not contain an MBR signature or at least one MBR
+	// partition has type 0xEE (GPT). It does however not care in which slot
+	// this partition is or if it begins at the start of the disk.
+	//
+	// Note that the block signatures for MBR and FAT are shared. This is a
+	// historical artifact from DOS. It is not reliably possible to
+	// differentiate the two as either has boot code where the other has meta-
+	// data and both lack any checksums. Because the MBR partition table is at
+	// the very end of the FAT bootcode section the following code always
+	// assumes that it is dealing with an MBR. This is both more likely and
+	// the 0xEE marker is rarer and thus more specific than FATs 0x00, 0x80 and
+	// 0x02.
+	var bootCode []byte
+	hasDOSBootSig := m.Signature == mbrSignature
+	if hasDOSBootSig {
+		var isGPT bool
+		for _, p := range m.PartitionRecords {
+			if p.Type == 0xEE {
+				isGPT = true
+			}
+		}
+		// Note that there is a small but non-zero chance that isGPT is true
+		// for a raw FAT filesystem if the bootcode contains a "valid" MBR.
+		// The next error message mentions that possibility.
+		if !isGPT {
+			return nil, errors.New("block device contains an MBR table without a GPT marker or a raw FAT filesystem")
+		}
+		// Trim right zeroes away as they are padded back when writing. This
+		// makes BootCode empty when it is all-zeros, making it easier to work
+		// with while still round-tripping correctly.
+		bootCode = bytes.TrimRight(m.BootCode[:], "\x00")
+	}
+	// Read the primary GPT. If it is damaged and/or broken, read the alternate.
+	primaryGPT, err := readSingleGPT(r, blockSize, blockCount, 1)
+	if err != nil {
+		alternateGPT, err2 := readSingleGPT(r, blockSize, blockCount, blockCount-1)
+		if err2 != nil {
+			return nil, fmt.Errorf("failed to read both GPTs: primary GPT (%v), secondary GPT (%v)", err, err2)
+		}
+		alternateGPT.BootCode = bootCode
+		return alternateGPT, nil
+	}
+	primaryGPT.BootCode = bootCode
+	return primaryGPT, nil
+}
+
+func readSingleGPT(r io.ReadSeeker, blockSize int64, blockCount int64, headerBlockPos int64) (*Table, error) {
+	if _, err := r.Seek(blockSize*headerBlockPos, io.SeekStart); err != nil {
+		return nil, fmt.Errorf("failed to seek to block %d: %w", headerBlockPos, err)
+	}
+	hdrBlock := make([]byte, blockSize)
+	if _, err := io.ReadFull(r, hdrBlock); err != nil {
+		return nil, fmt.Errorf("failed to read GPT header block: %w", err)
+	}
+	hdrBlockReader := bytes.NewReader(hdrBlock)
+	var hdr header
+	if err := binary.Read(hdrBlockReader, binary.LittleEndian, &hdr); err != nil {
+		panic(err) // Read from memory with enough bytes, should not fail
+	}
+	if hdr.Signature != gptSignature {
+		return nil, errors.New("no GPT signature found")
+	}
+	if hdr.HeaderSize < uint32(binary.Size(hdr)) {
+		return nil, fmt.Errorf("GPT header size is too small, likely corrupted")
+	}
+	if int64(hdr.HeaderSize) > blockSize {
+		return nil, fmt.Errorf("GPT header size is bigger than block size, likely corrupted")
+	}
+	// Use reserved bytes to hash, but do not expose them to the user.
+	// If someone has a need to process them, they should extend this library
+	// with whatever an updated UEFI specification contains.
+	// It has been considered to store these in the user-exposed GPT struct to
+	// be able to round-trip them cleanly, but there is significant complexity
+	// and risk involved in doing so.
+	reservedBytes := hdrBlock[binary.Size(hdr):hdr.HeaderSize]
+	hdrExpectedCRC := hdr.HeaderCRC32
+	hdr.HeaderCRC32 = 0
+	hdrCRC := crc32.NewIEEE()
+	binary.Write(hdrCRC, binary.LittleEndian, &hdr)
+	hdrCRC.Write(reservedBytes)
+	if hdrCRC.Sum32() != hdrExpectedCRC {
+		return nil, fmt.Errorf("GPT header checksum mismatch, probably corrupted")
+	}
+	if hdr.HeaderBlock != uint64(headerBlockPos) {
+		return nil, errors.New("GPT header indicates wrong block")
+	}
+	if hdr.PartitionEntrySize < uint32(binary.Size(partition{})) {
+		return nil, errors.New("partition entry size too small")
+	}
+	if hdr.PartitionEntriesStartBlock > uint64(blockCount) {
+		return nil, errors.New("partition entry start block is out of range")
+	}
+	// Sanity-check total size of the partition entry area. Otherwise, this is a
+	// trivial DoS as it could cause allocation of gigabytes of memory.
+	// 4MiB is equivalent to around 45k partitions at the current size.
+	// I know of no operating system which would handle even a fraction of this.
+	if uint64(hdr.PartitionEntryCount)*uint64(hdr.PartitionEntrySize) > 4*1024*1024 {
+		return nil, errors.New("partition entry area bigger than 4MiB, refusing to read")
+	}
+	partitionEntryData := make([]byte, hdr.PartitionEntrySize*hdr.PartitionEntryCount)
+	if _, err := r.Seek(blockSize*int64(hdr.PartitionEntriesStartBlock), io.SeekStart); err != nil {
+		return nil, fmt.Errorf("failed to seek to partition entry start block: %w", err)
+	}
+	if _, err := io.ReadFull(r, partitionEntryData); err != nil {
+		return nil, fmt.Errorf("failed to read partition entries: %w", err)
+	}
+	if crc32.ChecksumIEEE(partitionEntryData) != hdr.PartitionEntriesCRC32 {
+		return nil, errors.New("GPT partition entry table checksum mismatch")
+	}
+	var g Table
+	g.ID = unmangleUUID(hdr.ID)
+	g.BlockSize = blockSize
+	g.BlockCount = blockCount
+	for i := uint32(0); i < hdr.PartitionEntryCount; i++ {
+		entryReader := bytes.NewReader(partitionEntryData[i*hdr.PartitionEntrySize : (i+1)*hdr.PartitionEntrySize])
+		var part partition
+		if err := binary.Read(entryReader, binary.LittleEndian, &part); err != nil {
+			panic(err) // Should not happen
+		}
+		// If the partition type is the all-zero UUID, this slot counts as
+		// unused.
+		if part.Type == zeroUUID {
+			g.Partitions = append(g.Partitions, nil)
+			continue
+		}
+		g.Partitions = append(g.Partitions, &Partition{
+			ID:         unmangleUUID(part.ID),
+			Type:       unmangleUUID(part.Type),
+			Name:       strings.TrimRight(string(utf16.Decode(part.Name[:])), "\x00"),
+			FirstBlock: part.FirstBlock,
+			LastBlock:  part.LastBlock,
+			Attributes: Attribute(part.Attributes),
+		})
+	}
+	// Remove long list of nils at the end as it's inconvenient to work with
+	// (append doesn't work, debug prints are very long) and it round-trips
+	// correctly even without it as it gets zero-padded when writing anyway.
+	var maxValidPartition int
+	for i, p := range g.Partitions {
+		if !p.IsUnused() {
+			maxValidPartition = i
+		}
+	}
+	g.Partitions = g.Partitions[:maxValidPartition+1]
+	return &g, nil
+}
+
+var mixedEndianTranspose = []int{3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}
+
+// mangleUUID encodes a normal UUID into a "mixed-endian" UUID. This just means
+// shuffling the bytes around in a specific way. Thank Microsoft for this
+// idiosyncrasy.
+func mangleUUID(u uuid.UUID) (o [16]byte) {
+	for dest, from := range mixedEndianTranspose {
+		o[dest] = u[from]
+	}
+	return
+}
+
+// unmangleUUID does the reverse transformation of mangleUUID
+func unmangleUUID(i [16]byte) (o uuid.UUID) {
+	for from, dest := range mixedEndianTranspose {
+		o[dest] = i[from]
+	}
+	return
+}
