Understanding MTK’s MBR/EBR File Format 2


According to wikipedia, MBR is short for Master Boot Record, and EBR means Extended Boot Record. MBR was introduced in 1983 and was previously intended to be used for IBM PC. Aside from partition info, MBR file can also contain bootstrap code, and there are some variants of MBR file format due to the limitation of the original format.

Thank goodness! We don’t have to concern about all the complexity of the MBR file format in our case(the MTK’s MBR), we only focus on the simplest things, no bootstrap code, no extended data fields. Here is a sample MBR file(opened by a hex editor) along with a MTK factory package:

0000000: 0000 0000 0000 0000 0000 0000 0000 0000
0000010: 0000 0000 0000 0000 0000 0000 0000 0000
0000020: 0000 0000 0000 0000 0000 0000 0000 0000
0000030: 0000 0000 0000 0000 0000 0000 0000 0000
0000040: 0000 0000 0000 0000 0000 0000 0000 0000
0000050: 0000 0000 0000 0000 0000 0000 0000 0000
0000060: 0000 0000 0000 0000 0000 0000 0000 0000
0000070: 0000 0000 0000 0000 0000 0000 0000 0000
0000080: 0000 0000 0000 0000 0000 0000 0000 0000
0000090: 0000 0000 0000 0000 0000 0000 0000 0000
00000a0: 0000 0000 0000 0000 0000 0000 0000 0000
00000b0: 0000 0000 0000 0000 0000 0000 0000 0000
00000c0: 0000 0000 0000 0000 0000 0000 0000 0000
00000d0: 0000 0000 0000 0000 0000 0000 0000 0000
00000e0: 0000 0000 0000 0000 0000 0000 0000 0000
00000f0: 0000 0000 0000 0000 0000 0000 0000 0000
0000100: 0000 0000 0000 0000 0000 0000 0000 0000
0000110: 0000 0000 0000 0000 0000 0000 0000 0000
0000120: 0000 0000 0000 0000 0000 0000 0000 0000
0000130: 0000 0000 0000 0000 0000 0000 0000 0000
0000140: 0000 0000 0000 0000 0000 0000 0000 0000
0000150: 0000 0000 0000 0000 0000 0000 0000 0000
0000160: 0000 0000 0000 0000 0000 0000 0000 0000
0000170: 0000 0000 0000 0000 0000 0000 0000 0000
0000180: 0000 0000 0000 0000 0000 0000 0000 0000
0000190: 0000 0000 0000 0000 0000 0000 0000 0000
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000
00001b0: 0000 0000 0000 0000 0000 0000 0000 0000
00001c0: 0000 0500 0000 0004 0000 ffff ffff 0000
00001d0: 0000 8300 0000 0068 0000 0050 0000 0000
00001e0: 0000 8300 0000 00b8 0000 0050 0000 0000
00001f0: 0000 8300 0000 006c 0100 0030 0000 55aa

The size of this MBR file is 512 bytes. As we can see, the file is almost filled by 0, and ends with 0xaa55(little endian). Here’ the file format:

   Address	Description						Size
                                                                        (bytes)
Hex	Dec
+000h	+0	Bootstrap code area					446
+1BEh	+446	Partition entry #1	Partition table			16
+1CEh	+462	Partition entry #2					16
+1DEh	+478	Partition entry #3	(for primary partitions)	16
+1EEh	+494	Partition entry #4					16
+1FEh	+510	55h			Boot signature			2
+1FFh	+511	AAh
Total size: 446 + 4×16 + 2	512

From the table above, we can learn that addresses from 0 to 0x1bd store the bootstrap code, which is empty(all 0s) in our case. Data start from 0x1be to 0x1cd, 16 bytes in total, is partition entry #1; 0x1ce to 0x1dd is entry #2, 0x1de to 0x1ed is #3, and 0x1ee to 0x1fd is #4. Now let’s dig into the detail of a partition entry.

First of all, we must know the representation of these 16 bytes:

0 1 – 3 4 5 – 7 8 – 11 12 – 15
Boot indicator. CHS address: partition type. CHS address: start address of size of this
0x80 for activate, partition start. 0x05 for MBR/EBR, partition end. this partition. partition.
0x00 otherwise.   0x83 for Linux      
    filesystem.      

Note:

  1. The data order in the MBR file could be big endian or little endian, depends on the endian that the target device uses. The chip is configured to use little endian in my case(MT6589).
  2. The address or size value defined in the MBR is not represented in bytes, it is represented in sectors. For example, the size of the partition #2 is 0x5000(00500000, little endian), its real size is 0x5000*0x200=0xa00000 bytes, which is 10MB. The 0x200 is 512 in decimal, it presents how many bytes in a sector, which it 512 in most cases(but not all).
  3. The value of the partition’s start address(byte 8 to 11) does not represent the absolute offset(in sectors) from 0, it represents the offset(in sectors) from current MBR/EBR file. For example, the fourth partition in the sample MBR is start from 0x16c00, that means this partition is 0x16c00 sectors away from this MBR file, assume the address of this MBR file is sector 0x3000(byte 0x600000), then the real start address of partition #4 is (0x16c00 + 0x3000)*0x200 (bytes), which is byte 0x3380000.

With the byte representation in mind, we’ll look into the partitions in the sample MBR file.

The first partition is a MBR/EBR(EBR1 here, in fact) partition(byte 4 is 0x05). It starts from sector 0x400 and has 0xffffffff sectors.

00001b0:                                    0000
00001c0: 0000 0500 0000 0004 0000 ffff ffff

The section partition is a Linux filesystem partition. It starts from sector 0x6800 and has 0x5000 sectors.

00001c0:                                    0000
00001d0: 0000 8300 0000 0068 0000 0050 0000

The third partition is a Linux filesystem partition. It starts from sector 0xb800 and has 0x5000 sectors.

00001d0:                                    0000
00001e0: 0000 8300 0000 00b8 0000 0050 0000

The fourth partition is also a Linux filesystem partition. It starts from sector 0x16c00 and has 0x3000 sectors.

00001e0:                                    0000
00001f0: 0000 8300 0000 006c 0100 0030 0000

We can infer to the fact that partition #3 is next to partition #2, because the sum of the start address of partition #2 and the size of partition #2(0x6800+0x5000) is 0xb800, which is the start address of partition #3.

We also can know that partition #4 is a bit far away from partition #3, because there are (0x16c00-0x5000-0xb800=0x6400) sectors between the two partitions.

You might be wondering why such “hole” exists? Well, in fact there are several partitions reside the “hole”(defined in MT6589_Android_scatter_emmc.txt, for example), but they are not stated in the MBR or EBR(I don’t know why).

We’ve done interpreted the MBR file. It’s quite simple, isn’t it? Let’s move on to have a look at EBR.

An EBR file is quite similar to a MBR file, with some subtle differences:

  1. The first 446 bytes(from 0x0 to 0x1bd) are generally unused and filled with 0.
  2. The EBR file must contain reference to the next EBR(if there is any) to form a EBR chain. In my case, the fourth partition entry of EBR1 contains information(start address) of EBR2.

Here is the EBR1 along with the MBR shown above:

0000000: 0000 0000 0000 0000 0000 0000 0000 0000
0000010: 0000 0000 0000 0000 0000 0000 0000 0000
0000020: 0000 0000 0000 0000 0000 0000 0000 0000
0000030: 0000 0000 0000 0000 0000 0000 0000 0000
0000040: 0000 0000 0000 0000 0000 0000 0000 0000
0000050: 0000 0000 0000 0000 0000 0000 0000 0000
0000060: 0000 0000 0000 0000 0000 0000 0000 0000
0000070: 0000 0000 0000 0000 0000 0000 0000 0000
0000080: 0000 0000 0000 0000 0000 0000 0000 0000
0000090: 0000 0000 0000 0000 0000 0000 0000 0000
00000a0: 0000 0000 0000 0000 0000 0000 0000 0000
00000b0: 0000 0000 0000 0000 0000 0000 0000 0000
00000c0: 0000 0000 0000 0000 0000 0000 0000 0000
00000d0: 0000 0000 0000 0000 0000 0000 0000 0000
00000e0: 0000 0000 0000 0000 0000 0000 0000 0000
00000f0: 0000 0000 0000 0000 0000 0000 0000 0000
0000100: 0000 0000 0000 0000 0000 0000 0000 0000
0000110: 0000 0000 0000 0000 0000 0000 0000 0000
0000120: 0000 0000 0000 0000 0000 0000 0000 0000
0000130: 0000 0000 0000 0000 0000 0000 0000 0000
0000140: 0000 0000 0000 0000 0000 0000 0000 0000
0000150: 0000 0000 0000 0000 0000 0000 0000 0000
0000160: 0000 0000 0000 0000 0000 0000 0000 0000
0000170: 0000 0000 0000 0000 0000 0000 0000 0000
0000180: 0000 0000 0000 0000 0000 0000 0000 0000
0000190: 0000 0000 0000 0000 0000 0000 0000 0000
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000
00001b0: 0000 0000 0000 0000 0000 0000 0000 0000
00001c0: 0000 8300 0000 0008 0200 00a0 0f00 0000
00001d0: 0000 8300 0000 00a8 1100 0020 0300 0000
00001e0: 0000 8300 0000 00c8 1400 0070 5200 0000
00001f0: 0000 0500 0000 00b4 0100 ffff ffff 55aa

There are thress Linux partition entries and one EBR entry in this file. Assume the start sector of this EBR file is sector 0x3400. Similar to entries in MBR, the absolute start sector of the first partition entry is 0x20800 + 0x3400 = 0x23c00, which is 0x4780000 in bytes.

The fourth entry is an EBR entry, which is starts from sector (0x1b400 + 0x3400 = 0x1e800), its size is 0xffffffff(I consider it a convention, but suspect that any value wouble be OK).

Finally, the EBR2(the last EBR file):

0000000: 0000 0000 0000 0000 0000 0000 0000 0000
0000010: 0000 0000 0000 0000 0000 0000 0000 0000
0000020: 0000 0000 0000 0000 0000 0000 0000 0000
0000030: 0000 0000 0000 0000 0000 0000 0000 0000
0000040: 0000 0000 0000 0000 0000 0000 0000 0000
0000050: 0000 0000 0000 0000 0000 0000 0000 0000
0000060: 0000 0000 0000 0000 0000 0000 0000 0000
0000070: 0000 0000 0000 0000 0000 0000 0000 0000
0000080: 0000 0000 0000 0000 0000 0000 0000 0000
0000090: 0000 0000 0000 0000 0000 0000 0000 0000
00000a0: 0000 0000 0000 0000 0000 0000 0000 0000
00000b0: 0000 0000 0000 0000 0000 0000 0000 0000
00000c0: 0000 0000 0000 0000 0000 0000 0000 0000
00000d0: 0000 0000 0000 0000 0000 0000 0000 0000
00000e0: 0000 0000 0000 0000 0000 0000 0000 0000
00000f0: 0000 0000 0000 0000 0000 0000 0000 0000
0000100: 0000 0000 0000 0000 0000 0000 0000 0000
0000110: 0000 0000 0000 0000 0000 0000 0000 0000
0000120: 0000 0000 0000 0000 0000 0000 0000 0000
0000130: 0000 0000 0000 0000 0000 0000 0000 0000
0000140: 0000 0000 0000 0000 0000 0000 0000 0000
0000150: 0000 0000 0000 0000 0000 0000 0000 0000
0000160: 0000 0000 0000 0000 0000 0000 0000 0000
0000170: 0000 0000 0000 0000 0000 0000 0000 0000
0000180: 0000 0000 0000 0000 0000 0000 0000 0000
0000190: 0000 0000 0000 0000 0000 0000 0000 0000
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000
00001b0: 0000 0000 0000 0000 0000 0000 0000 0000
00001c0: 0000 8300 0000 0084 6500 ffc7 98ff 0000
00001d0: 0000 0000 0000 0000 0000 0000 0000 0000
00001e0: 0000 0000 0000 0000 0000 0000 0000 0000
00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa

From EBR1 we know that EBR2 starts from 0x1e800(start sectors of EBR1: 0x3400 + offset from EBR1: 0x1b400). There is only one entry in this EBR2 file, since EBR2 is the last EBR file, the entry defines the last partition(still, there might be partitions after this partition, which are defined in file like MT6589_Android_scatter_emmc.txt). The last partition is of no difference from other partitions except that the partition size of the last partition is super large(0xff98c7ff in this EBR2). I suspect the partition size could be any value that is large enough(larger than the remained unused sectors).

P.S.

  1. Here is another good post that explains the MTK MBR/EBR: MIUI系统的MBR、EBR、scatter、800M的关系.
  2. You can calculate the sector size(how many bytes in a sector) by: divide partition size by partition sector count. For example, the capacity of your system partition is 500MB(use “adb shell df” command can give you partition info), the partition size is 0xfa000 sectors(partition #1 of EBR1), then the sector size is (500 * 1024 * 1024 / 0xfa000 = 512).

Author: Rex Shen

Created: 2014-09-24 Wed 13:55

Emacs 24.3.1 (Org mode 8.2.7c)

Validate


Leave a comment

Your email address will not be published. Required fields are marked *

2 thoughts on “Understanding MTK’s MBR/EBR File Format

  • PBHillBilly

    Hello,

    I wanted to know if you were familiar.with “TEE” files. These are used in place of “EBR” files on a couple of tablets. One in particular is the Cube T9 using the MT8752 cpu. I’m trying to resize the internal storage but I’m shooting blind without any “TEE” file specifics. Any ideas?

    PB