Customize and Flash MT6589 ROM 8


I have a Lenovo A820T phone, which is based on MT6589, a MTK chip. Recently I want to flash a new ROM, but either the official ROMs or third-party ROMs contain a lot of unnecessary apks. Besides, I would like to enlarge the data partition. With these aims, I decided to customize a third-party ROM to fit my need.

Flash Tool

Installation and Usage

Since we need to re-partition, we need a PC tool named “SP Flash Tool”, there are many variants, and this is the one I use. Follow this post to learn how to install the driver and how to use this tool(although the post is written in Chinese, the pictures inside the post would show you all information needed). The driver package can be found here(the drivers are located in “MTK智能机USB驱动+刷机必备驱动大全by移动叔叔\刷机驱动自动安装版\”).

Additional Notes

If you encounter error message “pmt ready but changed” when downloading images, that’s because the partition table that your phone(might be the stored in the PMT partition) currently uses is different from the partition table you want to flash into(defined in MBR/EBR and MT6589_Android_scatter_emmc.txt). The flash tool might suggest you to use “Firmware->Upgrade” to just flash the images but not alter the partition table. You must double check your purpose, once you confirm that you want to alter the partitions, do any necessary backups and then use “Format” to earse all contents in the phone first. Think twice before you do this, the “format” operation will earse everything, including the nvram(which saves IMEI), and it is unreversable!

Unpack/Repack the Images

The Files

Here is the file list of the factory package that I use:

-rw-r--r-- 1 rex staff       276 Feb 29  2008 Checksum.ini				# checksum file, contains the bytes sum of each image
-rw-r--r-- 1 rex staff       512 Feb 29  2008 EBR1                                  # extended boot record 1
-rw-r--r-- 1 rex staff       512 Feb 29  2008 EBR2					# extended boot record 2
-rw-r--r-- 1 rex staff       512 Feb 29  2008 MBR					# master boot record
-rw-r--r-- 1 rex staff       523 Feb 29  2008 MT6589_Android_scatter_emmc.txt	# partition definition file
-rw-r--r-- 1 rex staff   4669440 Feb 29  2008 boot.img				# boot image, contains kernel and initramfs
-rw-r--r-- 1 rex staff   5886088 Feb 29  2008 cache.img				# Android's cache partition
-rw-r--r-- 1 rex staff   4056648 Feb 29  2008 kernel_lenovo89_td_jb.bin		# ?
-rw-r--r-- 1 rex staff    203428 Feb 29  2008 lk.bin				# bootloader
-rw-r--r-- 1 rex staff    363045 Feb 29  2008 logo.bin                              # logo
-rw-r--r-- 1 rex staff    119472 Feb 29  2008 preloader_lenovo89_td_jb.bin          # ?
-rw-r--r-- 1 rex staff   6051840 Feb 29  2008 recovery.img				# recovery image, similar to boot.img
-rw-r--r-- 1 rex staff     11264 Feb 29  2008 secro.img				# ?
-rw-r--r-- 1 rex staff 434011632 Feb 29  2008 system.img                            # Android's system partition
-rw-r--r-- 1 rex staff  47051548 Feb 29  2008 userdata.img				# Android's data partition
  • MBR/EBR

    Just read Understanding MTK’s MBR/EBR File Format to have an understanding on MBR and EBR.

  • Scatter File

    The MT6589_Android_scatter_emmc.txt defines the partitions. The following is excerpt from the scatter file:

    PRELOADER 0x0
    {
    }
    MBR 0x600000
    {
    }
    EBR1 0x680000
    {
    }
    __NODL_PMT 0x700000
    {
    }
    __NODL_PRO_INFO 0xb00000
    {
    }
    
    • Scatter File Format

      The “_NODL” prefix means you don’t have an image for such partition. Words such as “PRELOADER”, “MBR” are names of the partitions, and the hex value following the partition name is the start address(in bytes) of the partition. So, partition PRELOADER starts from bytes 0x0, MBR starts from 0x600000, EBR1 starts 0x680000, PMT starts from 0x700000 but we don’t have an image to flash into this area.

      I have no sample scatter files that there is any additional info defined inside the curly brace, so I don’t know how to define properties inside the curly brace.

    • Relationship between Scatter File and MBR/EBR

      In the Understanding MTK’s MBR/EBR File Format, I have assumed that the MBR file starts from byte 0x600000, but this value is an actual value, where does it come from? Looking at the excerpt above, you may already have the answer – yes, the vlaue is from the MT6589_Android_scatter_emmc.txt.

      Bear in mind that once you have modified MBR/EBR, you should check and change the scatter file accordingly, and vice versa. For example, if you change one partition’s size, you must change subsequent partition’s start address, either in the MBR/EBR or in the MT6589_Android_scatter_emmc.txt.

    • Example: Enlarge the Data Partition

      The original data partiton definition in the scatter file is:

      LOGO 0x3a00000
      {
      }
      EBR2 0x3d00000
      {
      }
      __NODL_EXPDB 0x3d80000
      {
      }
      ANDROID 0x4780000
      {
      }
      CACHE 0x20980000
      {
      }
      USRDATA 0x26D80000
      {
      }
      __NODL_FAT 0xCED80000
      {
      }
      __NODL_BMTPOOL 0xFFFF00a8
      {
      }
      

      Here are excerpts from MBR, EBR1 and EBR2(not showing the boot code part):

      # MBR
      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
      
      # EBR1
      00001b0: 0000 0000 0000 0000 0000 0000 0000 0000
      00001c0: 0000 8300 0000 0008 0200 0010 0e00 0000
      00001d0: 0000 8300 0000 0018 1000 0020 0300 0000
      00001e0: 0000 8300 0000 0038 1300 0000 5400 0000
      00001f0: 0000 0500 0000 00b4 0100 ffff ffff 55aa
      
      # EBR2
      00001b0: 0000 0000 0000 0000 0000 0000 0000 0000
      00001c0: 0000 8300 0000 0084 6500 ffb7 b5ff 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
      

      We know that the data partition(USRDATA) is the third last partition, with the FAT partition following it. Since my phone has 4GB in total, we can infer that the FAT partition corresponds to the sdcard partition inside Android(the last partition BMTPOOL starts from 4095MB so its capacity is 10MB at max).

      We also know that the data partition starts from byte 0x26d80000 and its size is (0xced80000 – 0x26d80000 = 0xa8000000B = 2688MB). Wow, that’s really large! But I still want to enlarge the partiton to 3GB(0xc0000000 bytes). How?

      • We must decide and change to the new start of partitoin FAT.

        The new value is: 0x26d80000 + 0xc0000000 = 0xe6d80000. So I we change the start value of FAT from 0xced80000 to 0xe6d80000 in the MT6589_Android_scatter_emmc.txt. You must notice that the size of FAT(sdcard) has shrinked, but that’s what I want(I have an external TF card to act as sdcard partition), so there are no further changes in the scatter file.

      • Find out which boot record file contains the data partition.

        First we assume one sector contains 512(0x200) bytes(general case), since the data partition starts from byte 0x26d80000, which is sector (0x26d80000 / 0x200 = 0x136c00). From the scatter file, we know MBR starts from byte 0x600000, which is in sector 0x3000, so the three Linux partitions start from (0x6800 + 0x3000 = 0x9800), (0xb800 + 0x3000 = 0xe800), (0x16c00 + 0x3000 = 0x19c00), respectively. None of them match. EBR1 starts from byte 0x680000(0x3400 in sector), so the Linux partitions start from (0x20800 + 0x3400 = 0x23c00), (0x101800 + 0x3400 = 0x104c00), (0x133800 + 0x3400 = 0x136c00), the last Linux partition in EBR1 matches! Now we know that the data partition is defined in EBR1, and the sector size is 512 bytes.

      • Change the size of the data partition.

        The new size is 3GB, which is 0xc0000000 in bytes, and 0x600000 in sectors. Then we change the third partiton of EBR1 from “8300 0000 0038 1300 0000 5400” to “8300 0000 0038 1300 0000 6000”.

      • Change the start address and/or partition size of the following partition and subsequent partitions if necessary.

        From the scatter file we know that there is only one partition(FAT) following the data partition. The original start address of FAT is in byte 0xced80000, which is 0x676c00 in sector. From the above analyzation, we know the FAT partition neither defined in MBR nor defined in EBR1, so we’ll search EBR2. EBR2 starts from byte 0x3d00000(0x1e800 in sector), so the only partition defined in EBR2 starts from (0x658400 + 0x1e800 = 0x676c00), aha, that’s the FAT partition we are looking for! The new start sector is (absolute start of data + size of data – absolute start of EBR2 = 0x136c00 + 0x600000 – 0x1e800 = 0x718400), the new size of the FAT partition is ((start of BMTPOOL – start of FAT) / (sector size) = (0xffff00a8 – 0xe6d80000)/0x200 = 0xc9380). Because we don’t have any data to write to FAT and BMTPOOL, we can leave the size part of FAT unchanged. The final change is: change the FAT partition info in the EBR2 from “8300 0000 0084 6500 ffb7 b5ff” to “8300 0000 0084 7100 ffb7 b5ff”.

      • DONE!
  • Checksum.ini

    The content of the Checksum.ini:

    [IsEnableChecksum]
    CHECKSUM_SWITCH=1
    [CheckSum]
    PRELOADER=0x000081dd
    UBOOT=0x0000807a
    LOGO=0x0000e886
    BOOTIMG=0x00007ff2
    RECOVERY=0x00007ec2
    SEC_RO=0x00002c83
    ANDROID=0x000016b7
    USRDATA=0x0000605d
    MBR=0x000008ea
    EBR1=0x00000850
    EBR2=0x000005d5
    CACHE=0x0000681f
    
    • The Checksum Switch

      When the “CHECKSUM_SWITCH” is set to 1(shown in above), then the Flash Tool will check if the files’ checksum value. If you don’t want to Flash Tool to check the file sum, just set this to 0. I recommend you to enable the checksum to avoid misuse of images or file corruptions.

    • Checksum Algorithm

      The checksum algorithm is pretty simple and can be summarized as follow:

      1. for each byte in the file, consider is as unsigned char(one byte). Accummulate all the bytes to get a unsigned int(four bytes) sum.
      2. If the file has even bytes(for example, 4 bytes), jump to step 3; otherwise, if the file size is odd(for example, 3 bytes), add 0xff to the sum we got from step 1.
      3. Discard the higher two bytes data from the sum. for example, if the sum is 0x12345678, then the final sum value is 0x00005678, with the higher two bytes data discarded.
    • Checksum Tool

      We must re-generate the Checksum.ini after we change any of the files which are listed in the Checksum.ini. There is a Windows executable tool named CheckSum_Generate.exe that can generate the file, you can download it from here, or if you want to use it in other OS(Linux or OSX), you can checkout and compile my edition from here.

  • The MTK Specified File Header

    MTK adds a file header to several of the image files, here is the list: kernel_lenovo89_td_jb.bin, lk.bin, logo.bin, initrd.img and zImage, the last two is packed into the boot.img and recovery.img. The header is just a simple wrapper to add additional information, the header format is:

    4 bytes header code 4 bytes file length 32 bytes file signature 472 bytes filled data
    0x88, 0x16, 0x88, 0x58 not include this 512 bytes header, “LOGO”, “ROOTFS”, etc. 0xff, 0xff, …
      in little endian format    

    There is a handy tool named mtk-tools to delete or add such kind of header, you can find it here.

  • logo.bin

    Besides the wrapper header, the logo.bin is a special file that is a collection of several image files. We can use the mtk-tools to unpack or repack it either.

Unpack/Repack

Images like boot.img, system.img are standard Android images, so we can unpack these images follow this post: Android: How to Unpack/Pack Factory. Due to the differences from the standard boot image, we’d better use the mtk-tools to unpack/repack the boot images.

To unpack the boot.img(recovery.img), simply run:

unpack-MT65xx.pl boot.img # recovery.img

After the success execution of the unpack-MT65xx.pl command, a file named boot.img-kernel.img and a folder named boot.img-ramdisk will be extracted to current directory. You can make any changes to the ramdisk now.

When you have done your modification, you can use this command to repack a boot image:

repack-MT65xx.pl  -boot boot.img-kernel.img boot.img-ramdisk/ boot.img

Please run “unpack-MT65xx.pl” or “repack-MT65xx.pl” without any options to see all the available options.

P.S. the logo.bin can be unpack and repack via the mtk-tools too.

Conclusions

Let me summarize the total steps:

  1. Unpack the boot images(boot.img and recovery.img) by using unpack-MT65xx.pl, make any changes to the ramdisk and repack the image use repack-MT65xx.pl.
  2. Convert the Android images(system.img, userdata.img, etc.) to ext4 images by using simg2img, then mount it to filesystem and make any changes; re-generate the images using mkuserimg.sh.
  3. Use unpack-MT65xx.pl and repack-MT65xx.pl to unpack and repack logo.bin.
  4. Modify MBR, EBR1, EBR2 and MT6589_Android_scatter_emmc.txt if you want to alter the partition table; you should re-generate the corresponding Android image(system.img, for example) use the updated size value(change the SIZE of mkuserimg.sh) if you have changed the size of a partition.
  5. Re-generate Checksum.ini use CheckSum_Generate.exe or any other tools.
  6. Use the SP Flash Tool to flash the updates images.
  7. You may find this useful if you find you lost your IMEI
  8. Feel free to add comments if you encounter any problems^ ^.

Author: Rex Shen

Created: 2014-09-25 Thu 18:41

Emacs 24.3.1 (Org mode 8.2.7c)

Validate


Leave a comment

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

8 thoughts on “Customize and Flash MT6589 ROM

  • mau

    Hello
    very useful guide. But just to clear, if I change (for example remove app) system.img Ihave to:
    -regenerate system image mkuserimg.sh -s sys/ my-system.img ext4 /system 900m
    -and change scatter file modifing hexadecimal address (linear_start_addr,physical_start_addr)from system.img to last partition
    Thank you

    • Rex
      Rex Post author

      If you don’t change the partition size of system, you don’t have to change scatter file or MBR/EBR. The size of system.img(determined by the actual files size in sys/ in your example) is different from the size of partition system(the “900m” you use in mkuserimg.sh command). If you do change the partition size, then you must re-calculate the addresses of the following partitions. Thanks for reading^_^.

  • mau

    I have some problems to calculate the right size of the image.
    Genuine version:
    sys/ 728316 (712M) system.img 762775300

    Custom version:
    sys/ 728188(712M) system.img ?
    How is it the size value in mkuserimg.sh(900M it was a test)? I tried with
    mkuserimg.sh -s sys/ my-system.img ext4 /system 728188 but not work.
    Thank you

    • Rex
      Rex Post author

      mau,
      The partition size should always larger than the sum of files inside the partition, so you can just allocate a large enough partition size(for example, 800M in your case). Don’t forget to update MBR/EBR and scatter file if you change the partition size. You don’t have to change the size of the partition if the original size is large enough.

      You can get the partition size of the genuine version by running “df” command in your phone/board which has the genuine version installed, or you can calculate the partition size from MBR/EBR files if you have such files(read http://rex-shen.net/understanding-mtks-mbrebr-file-format/ to understand the MBR format). Another way to get the size of a partition is to check the scatter file. Here is an excerpt from my scatter file:
      ANDROID 0x4780000
      {
      }
      CACHE 0x23B80000
      {
      }
      The excerpt defines ANDROID(partition “system”) starts from 0x4780000, and CACHE(partition “cache”) starts from 0x23B80000, then my system partition has the size of 500MiB(0x23B80000 – 0x4780000). Note that this can only work when the two partitions are adjacent, if you not sure about it, you’d better check MBR/EBR first.

  • Robert Sam

    Original
    Preloader
    physical_start_addr: 0x0
    partition_size: 0xC00000

    Modified
    Preloader
    physical_start_addr: 0x0
    partition_size: 0xc00000

    MBR (Both Same values)

    Now the problem is
    EBR1
    linear_start_addr: 0xc80000
    physical_start_addr: 0x0
    partition_size: 0x80000

    Modified EBR1
    linear_start_addr: 0xC80000
    physical_start_addr: 0x80000
    partition_size: 0x80000

    Original Userdata
    linear_start_addr: 0x44540000
    physical_start_addr: 0x43940000
    partition_size: 0x52C00000

    Modified
    User data
    linear_start_addr: 0x50d40000
    physical_start_addr: 0x0
    partition_size: 0x46400000

    Original System.img
    linear_start_addr: 0x4340000
    physical_start_addr: 0x3740000
    partition_size: 0x32000000

    Modified System.img
    linear_start_addr: 0x4340000
    physical_start_addr: 0x0
    partition_size: 0x3e800000

    I downloaded file of the same device which was an update and they changed this onto the original scatter file which I got from my device stock backup through mtk droid tools.

    now my device shows
    /data 8gb
    /system 8gb
    /cache 8gb (all acts same)
    /internal media 1.31gb

    Is this recoverable?

    I tried put my backup stock scatter file onto flash tools, but I get PMT changed error.

    • Robert Sam

      Ok, I managed to get the old stock scatter file and preloader working through firmware upgrade of my original backup. the device boots as well now. but I have same result with the partitions

      storage/sdcard0 is 8gb
      /data 8gb
      /system 8gb
      /cache 8gb
      while external SD mounted at /mnt/media_rw/sdcard0
      is 1.31gb (correction in the first post too)

      I guess that’s the same as stock since I successfully flashed to the original state.(It is a new phone in my hand and I didn’t looked at the partitions before, so I was wrong about it being change)

      but why there is difference in scatter file partitions? I am a little confused here,