4

I've been struggling to figure out a boot problem with the RaspberryPi 3 (I've not tested other models) using a modified Raspbian Jessie Lite image, and finally narrowed down to something to do with the MBR -- but now I'm baffled and curious as to what exactly the problem is.

In short: if I adjust partitions with parted, the Pi doesn't boot. If I do the exact same adjustment with fdisk, it works fine.

Fair warning: this question involves reading hex dumps of the master boot record.


Basically I'm expanding a stock Raspbian image and then resizing the second partition, then writing it to an SD card. However, the same problem happens if I write the stock Raspbian image to an SD card and modify the SD card partition there.

Here's the starting partition layout, for reference:

gregmac:~$ gdisk -l 2017-04-10-raspbian-jessie-lite.img
Disk 2017-04-10-raspbian-jessie-lite.img: 2534888 sectors, 1.2 GiB
Logical sector size: 512 bytes

Number  Start (sector)    End (sector)  Size       Code  Name
  1            8192           92159   41.0 MiB    0700  Microsoft basic data
  2           92160         2534887   1.2 GiB     8300  Linux filesystem

(Note: I removed a bunch of extraneous output from this command for brevity -- this question is long enough)

Using parted

First I add 300MiB, then resize the second partition to end at the last sector:

gregmac:~$ cp 2017-04-10-raspbian-jessie-lite.img test-parted.img
gregmac:~$ truncate -s +300M test-parted.img
gregmac:~$ parted test-parted.img resizepart 2 3149287s

And the resulting layout:

gregmac:~$ gdisk -l test-parted.img
Disk test-parted.img: 3149288 sectors, 1.5 GiB
Logical sector size: 512 bytes

Number  Start (sector)    End (sector)  Size       Code  Name
  1            8192           92159   41.0 MiB    0700  Microsoft basic data
  2           92160         3149287   1.5 GiB     8300  Linux filesystem

The problem is: this image will not boot. The green LED flashes rapidly with activity for a second or two, then the screen just displays 4 raspberries indefinitely while the green LED blinks once every second for several minutes and eventually stops (the screen stays the same).

hung boot after editing partition with parted

Using fdisk

Frustratingly, I eventually figured out that I can do exactly this same modification using fdisk and the Pi boots just fine.

gregmac:~$ cp 2017-04-10-raspbian-jessie-lite.img test-fdisk.img
gregmac:~$ truncate -s +300M test-fdisk.img
gregmac:~$ fdisk test-fdisk.img

Command (m for help): p

Disk test-truncate-fdisk.img: 1612 MB, 1612435456 bytes
255 heads, 63 sectors/track, 196 cylinders, total 3149288 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
Disk identifier: 0x84fa8189

         Device Boot      Start         End      Blocks   Id  System
test-fdisk.img1            8192       92159       41984    c  W95 FAT32 (LBA)
test-fdisk.img2           92160     2534887     1221364   83  Linux

Command (m for help): d
Partition number (1-4): 2

Command (m for help): n
Partition type:
  p   primary (1 primary, 0 extended, 3 free)
  e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (2048-3149287, default 2048): 92160
Last sector, +sectors or +size{K,M,G} (92160-3149287, default 3149287):
Using default value 3149287

Command (m for help): w
The partition table has been altered!

Syncing disks.

And resulting partition layout:

gregmac:~$ gdisk -l test-fdisk.img
Disk test-fdisk.img: 3149288 sectors, 1.5 GiB
Logical sector size: 512 bytes

Number  Start (sector)    End (sector)  Size       Code  Name
  1            8192           92159   41.0 MiB    0700  Microsoft basic data
  2           92160         3149287   1.5 GiB     8300  Linux filesystem

(hint: 100% identical to the parted version!)

MBR differences

So after much messing around (and a couple dozen SD card writes to a few different cards), I eventually resorted to binary diffs of the files.

Quick master boot record primer/refresher: the MBR is 512 bytes:

  • First 446 bytes: "Bootstrap code area"
  • Next 16 bytes: Partition 1
  • Next 16 bytes: Partition 2
  • Next 16 bytes: Partition 3
  • Next 16 bytes: Partition 4
  • Remaining 2 bytes: Boot signature

There are three differences in my images:

1) The stock image is exactly 300 MB smaller

Expected, because I added 300MB to my images.

2) Partition 2 is different

Well, of course, because I explicitly modified it. Notably though, the two images I created are identical, even though parted did one and fdisk did the other.

For reference, dumping the 16-byte partition 2 table:

gregmac:~$ hexdump -C -s $((446+16)) -n 16 2017-04-10-raspbian-jessie-lite.img
000001ce  00 bb 37 05 83 c9 14 9d  00 68 01 00 e8 45 25 00  |..7......h...E%.|

gregmac:~$ hexdump -C -s $((446+16)) -n 16 test-parted.img
000001ce  00 bb 37 05 83 08 2c c4  00 68 01 00 e8 a5 2e 00  |..7...,..h......|

gregmac:~$ hexdump -C -s $((446+16)) -n 16 test-fdisk.img
000001ce  00 bb 37 05 83 08 2c c4  00 68 01 00 e8 a5 2e 00  |..7...,..h......|

3) The bootstrap code area is very different in the parted image

The bootstrap code in my fdisk-created image is identical to the stock Raspbian image, and it looks like this:

gregmac:~$ hexdump -C -n 446 2017-04-10-raspbian-jessie-lite.img
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001b0  00 00 00 00 00 00 00 00  89 81 fa 84 00 00        |..............|

The bootstrap code in the parted-created image, however, is entirely different:

gregmac:~$ hexdump -C -n 446 test-parted.img
00000000  fa b8 00 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |................|
00000010  fb be 00 7c bf 00 06 b9  00 02 f3 a4 ea 21 06 00  |...|.........!..|
00000020  00 be be 07 38 04 75 0b  83 c6 10 81 fe fe 07 75  |....8.u........u|
00000030  f3 eb 16 b4 02 b0 01 bb  00 7c b2 80 8a 74 01 8b  |.........|...t..|
00000040  4c 02 cd 13 ea 00 7c 00  00 eb fe 00 00 00 00 00  |L.....|.........|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001b0  00 00 00 00 00 00 00 00  41 da 04 00 00 00        |........A.....|

Specifically:

  • the disk signature (offset 0x01B8) of the parted image is 41 da 04 00, but in the other two it is 89 81 fa 84
  • The first 75 bytes of bootstrap code in the parted image has some code in it, but is zeroed-out in the other two

I am pretty sure the "disk signature" doesn't have any actual meaning here. For comparison the disk signature in 2016-09-23-raspbian-jessie-lite.img is a1 89 70 5a -- which leads me to believe this value is unimportant.

Question

So my questions:

  • Why is parted doing this? (and what is this bootstrap code doing?)
  • According to NOOBs documentation (and elsewhere): "a Raspberry Pi doesn't use any of the bootstrap code stored in the MBR.". So why is the different bootstrap code causing a failure to boot?
  • Despite my assumption, is the disk signature difference actually causing the problem? In that case, why does the 2016-09-23 Raspbian image work even though it's also different? Why is parted setting it incorrectly and how do I make it not do that?
  • According to raspberrypi.org/forums/viewtopic.php?t=58151 when the raspberries appear this means that the /boot partition could be read as such: "no video without booting". The Pis search the first FAT partition from which it can read the bootcode.bin file, afaik. This also allows booting from USB mass storage devices. And yes, any MBR bootcode is ignored, as it would never work as it is old x86 code and the Raspberry Pis use ARM cores. – TheDiveO Jun 7 '17 at 6:35
  • The real question is WHY you thought you had to fiddle with the image. – Milliways Jun 7 '17 at 7:04
  • @TheDiveO well, definitely doesn't seem like it is being completely ignored... – gregmac Jun 7 '17 at 7:12
  • 2
    Missed the thing Milliways pointed out: disk identifer. Since beginning of April 2017, Raspbian now uses PARTUUIDs (not UUIDs) to reference the / (root) and /boot partitions, both on the kernel command line, and for /etc/fstab. This is a god-send for us who flash new images to USB mass storage devices and boot from there, but in your case it will bite you, as you need to update both kernel command line and fstab. – TheDiveO Jun 7 '17 at 11:41
  • 1
    I can only guess that maybe parted once wanted to signal a disc change to force the partitioning getting reloaded through kind of a fake disk change. But this now has turned against its creators, rendering the modern mount-by-partid schemes dead in the water. Good to know! – TheDiveO Jun 7 '17 at 19:29
3

To summarize the comment section: we don't know why parted changes the disk identity, but can only guess (or rather speculate). Anyway, this change made by parted has the undesired side effect that it renders Raspbian images after beginning of April 2017 unable to boot. The reason is that the partition UUID (PARTUUID) changes, and the kernel boot parameters as well as the /etc/fstab still reference the old PARTUUID. So either don't use parted, or update thr command line parameters and /etc/fstab with the new PARTUUIDs you can retrieve via blkid.

  • I had to use linux (there does not seem to be a way on macOS) to check the PARTUUID, but this did the trick for me. I used gparted to modify the loopback-mounted raspbian image of mine. This question saved my bacon because it showed me the exact same situation I was in. Thanks for describing it so well and even providing a screenshot! – Steven Lu Aug 7 '18 at 23:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.