Wednesday, 9 March 2016

PIT file template

My Phone

I bought a Samsung Galaxy Note Tab (GT-N7000) about 4 or 5 years ago and I love it. I especially like the screen size (and resolution) as it makes it easy to read PDF files on the train. Some people think it's too big for a pocket but on the contrary I have always had problems with narrower phones falling out of my pocket when I run for the train. The N7000 is my dream phone.

However, it has been getting a bit slow so I thought I should do a factory reset. "Why not upgrade to a later version of Android at the same time" I thought. (Samsung never upgraded it past Jellybean but there are unofficial ROMs for Lollipop and even Marshmallow.) So I installed a version of Lollipop (from CyanogenMod). This worked fine except that afterwards I did not seem to have any space on my "internal SD card" and I quickly ran out of space on my /data partition. (Samsung stupidly only make the Android /data partition 2Gb!!?)  This basically was wasting about 11Gb of the 16Gb in the phone.

I tried lots of things, including buying a new (64Gb) SD card but I could not manage to free enough space on my /data partition to install all the apps I need (let alone music and photos), or move them to the SD card. I looked at modifying the Linux partition table myself but then I found that Samsung have a "leaked" utility to change (among other things) the partition table.  This utility is called Odin - but there is also a superior open-source alternative to Odin called Heimdall.

PIT Files

To use Odin/Hemdall to modify partitions you need a PIT (partition information table) file. I managed to generate my current PIT file but had trouble finding out how to modify if to enlarge the /data partition (called "DATAFS" in the PIT file). Now someone has even written a utility called "PIT Magic" to modify PIT files. The trouble is that I could not work out how to use it and there were some obvious mistakes (such as the fact for each table entry it calls the partition starting block the "block size" field whereas it is obviously the number of the first block of the partition not the size.

Anyway, to get to the point I created a template for HexEdit that I found useful for viewing and editing PIT files. I used the source code for Heimdall to work out what some of the fields in PIT files are for. Though I am not sure of the purpose of all the fields, the important ones are the start_block and num_blocks fields which you can modify to adjust the size of the partitions.  (I would not try adding, deleting or renaming partitions using this template as I am not sure how dependent Android is on these things.)

HexEdit PIT File Template

The advantages of the HexEdit template over the PIT magic program are:

1. Quick to create and modify. (It only took me < 2 hours to create it.)
2. Much easier to understand what's happening.
3. Easier to see and modify the partiton fields in the template.
4. Easy to see what bytes are modified in the HexEdit main window.
5. Warns if any of the partitions overlap. (This can avoid a very nasty situation.)

Here is the code for the template:
<?xml version="1.0"?>
<!DOCTYPE binary_file_format SYSTEM "BinaryFileFormat.dtd">
<binary_file_format name="PIT" type_name="struct PIT" comment="Partition Info Table"
                    expr="({this.NumEntries} Entries)">
   <data type="int" name="MagicNumber" format="unsigned" len="4" domain="this == 0x12349876" display="hex"/>
   <data type="int" name="NumEntries" format="unsigned" len="4"/>
   <data type="none" len="20"/>
   <eval expr="curr_entry = 0" display_error="false" display_result="false" comment="init loop var"/>
   <for name="Entry" count="NumEntries">
      <struct type_name="struct Entry" comment="one partition in the table"
              expr="{this.name} {this.num_blocks; dec} blocks" name="">
        <data type="int" format="unsigned" len="4" comment="Binary Type?"/>
        <data type="int" name="device_type" format="unsigned" len="4" domain="{FAT=1,MMC,}" bits="2"
              direction="up"/>
        <data type="int" name="id" format="unsigned" len="4" display=""/>
        <data type="int" name="attr" format="unsigned" len="4" domain="{RO, RW, }" bits="1" direction="up"/>
        <data type="int" name="update_attr" format="unsigned" len="4" display="hex"/>
        <data type="int" name="start_block" format="unsigned" len="4" display="dec"/>
        <data type="int" name="num_blocks" format="unsigned" len="4" display="dec"/>
        <data type="int" format="unsigned" len="4" comment="File Offset?"/>
        <data type="int" format="unsigned" len="4" comment="File Size?"/>
        <data type="string" name="name" len="32"/>
        <data type="string" name="flash_file_name" len="32"/>
        <data type="string" name="fota_file_name" len="32"/>
        <if test="curr_entry &gt; 0 &amp;&amp; num_blocks &gt; 0">
           <eval expr="start_block <= Entry[curr_entry - 1].start_block + Entry[curr_entry - 1].num_blocks"
                 display_error="true" comment="check that this partn starts after end of previous"/>
        </if>
        <eval expr="++curr_entry" comment="inc loop var"/>
      </struct>
   </for>
</binary_file_format>

Paste this text into an XML file (eg _PIT.XML) and put it in your HexEdit app-data folder (eg C:\Users\andrew\AppData\Roaming\ECSoftware\HexEdit). Then open a PIT file in HexEdit and then open the template (Template -> File Type -> PIT file). In the Template view on the left there is a
grid-tree, so right-click the column header and turn on the Data column. (You might like to turn on others columns like Hex Address, Size, Comments, etc.)

Now expand the tree view (PIT) then expand the table (Entries). The 11th table entry (DATAFS) is for the /data partition, so expand that and inspect the start_block and num_blocks fields. If you want to increase the size of the partition then double-click the Data column for num_blocks and enter a larger number. Of course, you must adjust the starting block and number of blocks of the following partition (UMS) correspondingly.

I used this to modify the partition table on my phone and now I have a 8GB /data partition rather than the pathetic (default) 2GB. (I could have made increased it to 12GB but did not want to be greedy.) I have installed 41 extra apps on the phone and still have 5.21GB free.

1 comment:

  1. Hi Andrew!
    I'm very interested in your procedure. I extracted the current PIT-file of my Samsung Galaxy S2 currently corresponding to a custom ROM (Neat-ROM), which I would like to modify for a new installation.
    On ubuntu 16.10 I prepared the /usr/share/appdata/PIT_Andrew.xml with your script. After opening my extracted PIT-file with GHex I tried to open your PIT_Andrew.xml as well (with GHex or as xml?). Unfortunately in no case I can't find the grid-tree on the left.
    So I would be very glad to have some more instructions. It would also be very useful to see your practical example of modifying the blocks for increasing a partition and the blocks of the following partition.
    I'll start this modification only when being sure of all steps for avoiding to brick my phone. You can choose the procedure on Windows or Linux, as you like.
    Nice to hear you, have a nice day!
    ubunti

    ReplyDelete