pengutronix / genimage

tool to generate multiple filesystem and flash images from a tree
GNU General Public License v2.0
308 stars 110 forks source link

Add support for Hybrid MBR partitions #96

Closed jameshilliard closed 4 years ago

jameshilliard commented 4 years ago

In order to boot a raspberry pi using GPT one must use a Hybrid MBR partition scheme since the firmware looks for the first available MBR fat32 partition. Example config:

image boot.vfat {
  vfat {
    files = {
      "bcm2710-rpi-3-b.dtb",
      "bcm2710-rpi-3-b-plus.dtb",
      "bcm2837-rpi-3-b.dtb",
      "rpi-firmware/bootcode.bin",
      "rpi-firmware/cmdline.txt",
      "rpi-firmware/config.txt",
      "rpi-firmware/fixup.dat",
      "rpi-firmware/start.elf",
      "rpi-firmware/overlays",
      "Image"
    }
  }
  size = 32M
}

image sdcard.img {
  hdimage {
    gpt = "true"
  }

  partition boot {
    partition-type = 0xC
    partition-type-uuid = c12a7328-f81f-11d2-ba4b-00a0c93ec93b
    bootable = "true"
    image = "boot.vfat"
  }

  partition rootfs {
    partition-uuid = c0932a41-44cf-463b-8152-d43188553ed4
    partition-type-uuid = b921b045-1df0-41c3-af44-4c6f280d3fae
    image = "rootfs.ext4"
  }
}
jameshilliard commented 4 years ago

Also, this is the size, not the position, so I think hd->gpt_location + (GPT_SECTORS - 1) * 512 - 512 is probably correct.

I tried building an image with that change and it doesn't look right as the protective GPT 0xee entry is overflowing and covering part of the first partition entry(in this example it should end at sector 33 like my above example).

$ fdisk -t dos -l rpi3_20200327_162150.img
Disk rpi3_20200327_162150.img: 10.3 GiB, 10771006976 bytes, 21037123 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device                    Boot Start   End Sectors  Size Id Type
rpi3_20200327_162150.img1 *       34 65569   65536   32M  c W95 FAT32 (LBA)
rpi3_20200327_162150.img2          1 16896   16896  8.3M ee GPT

Partition table entries are not in disk order.
michaelolbrich commented 4 years ago

Right, because we need sectors here, not bytes, right? So: hd->gpt_location / 512 + GPT_SECTORS - 2

jameshilliard commented 4 years ago

Yeah, that looks better. Without setting gpt-location:

$ fdisk -t dos -l rpi3_20200327_165924.img
Disk rpi3_20200327_165924.img: 10.3 GiB, 10771006976 bytes, 21037123 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device                    Boot Start   End Sectors  Size Id Type
rpi3_20200327_165924.img1 *       34 65569   65536   32M  c W95 FAT32 (LBA)
rpi3_20200327_165924.img2          1    33      33 16.5K ee GPT

Partition table entries are not in disk order.

With gpt-location = 4096:

$ fdisk -t dos -l rpi3_20200327_171351.img
Disk rpi3_20200327_171351.img: 10.3 GiB, 10771006976 bytes, 21037123 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device                    Boot Start   End Sectors  Size Id Type
rpi3_20200327_171351.img1 *       34 65569   65536   32M  c W95 FAT32 (LBA)
rpi3_20200327_171351.img2          1    39      39 19.5K ee GPT

Partition table entries are not in disk order.
$ fdisk -t gpt -l rpi3_20200327_171351.img
Disk rpi3_20200327_171351.img: 10.3 GiB, 10771006976 bytes, 21037123 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: C4E4865A-51CD-49F1-A59B-66A7AA259A17

Device                    Start      End  Sectors Size Type
rpi3_20200327_171351.img1    34    65569    65536  32M EFI System
rpi3_20200327_171351.img2 65570 21037089 20971520  10G Linux root (ARM-64)

So now the protective MBR partition looks to be correct but when setting gpt-location the fat32 partition is not being pushed back to start at sector 40 like it would need to in this example, I guess #99 should fix that(I'll run another test build with it added).

jameshilliard commented 4 years ago

Test builds with #99 included looks good. With gpt-location = 4096:

$ fdisk -t dos -l rpi3_20200327_172900.img
Disk rpi3_20200327_172900.img: 10.3 GiB, 10771010048 bytes, 21037129 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device                    Boot Start   End Sectors  Size Id Type
rpi3_20200327_172900.img1 *       40 65575   65536   32M  c W95 FAT32 (LBA)
rpi3_20200327_172900.img2          1    39      39 19.5K ee GPT

Partition table entries are not in disk order.
$ fdisk -t gpt -l rpi3_20200327_172900.img
Disk rpi3_20200327_172900.img: 10.3 GiB, 10771010048 bytes, 21037129 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: DEC6907C-1FA2-44E0-A32F-928867B0E247

Device                    Start      End  Sectors Size Type
rpi3_20200327_172900.img1    40    65575    65536  32M EFI System
rpi3_20200327_172900.img2 65576 21037095 20971520  10G Linux root (ARM-64)

Without setting gpt-location:

$ fdisk -t dos -l rpi3_20200327_173728.img
Disk rpi3_20200327_173728.img: 10.3 GiB, 10771006976 bytes, 21037123 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device                    Boot Start   End Sectors  Size Id Type
rpi3_20200327_173728.img1 *       34 65569   65536   32M  c W95 FAT32 (LBA)
rpi3_20200327_173728.img2          1    33      33 16.5K ee GPT

Partition table entries are not in disk order.
$ fdisk -t gpt -l rpi3_20200327_173728.img
Disk rpi3_20200327_173728.img: 10.3 GiB, 10771006976 bytes, 21037123 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1DC632D3-20C5-4B74-98AD-FBA2ED586789

Device                    Start      End  Sectors Size Type
rpi3_20200327_173728.img1    34    65569    65536  32M EFI System
rpi3_20200327_173728.img2 65570 21037089 20971520  10G Linux root (ARM-64)