I recently found my Nexus 4 after the move and wanted to get it usable again. It was running the last official version of Android, 5.1.1, for the device from November 2014. LineageOS dropped support for it several years ago, the device was released in 2012, so I hoped to find either the last nightly build or an unofficial build of something more recent. I found an install guide for the device that I used when installing LineageOS.

Partitioning

First however, I needed to repartition /system because the original partition size was no longer large enough. There were scripts out there to manage the partitioning but as an experienced Linux sysadmin I opted to do it myself. I also didn’t search hard and realize the scripts existed before trying.

I installed android-tools from Fedora’s repositories, plugged in the phone, and got it work. I could adb reboot and adb shell all I wanted but fastboot and adb sideload refused to work. The install guide mentioned this so I connected through a USB 3.0 hub and that fixed all of the sideload and fastboot problems.

With fastboot working, I booted the latest TWRP image for the Nexus 4.

# adb reboot bootloader
# fastboot boot /path/to/tmp/lineageos/twrp-3.5.2_9-0-mako.img
Sending 'boot.img' (10528 KB)                      OKAY [  0.431s]
Booting                                            OKAY [  0.030s]
Finished. Total time: 0.486s

From an unofficial image thread, I knew I needed /system to be at least 1272 MB. I ran adb shell, mounted /system, and checked its size to see it was only 827 MB. Following an answer on Android StackExchange on repartitioning a different device, I set out to increase /system.

I pushed a statically linked parted (I didn’t need gdisk but pushed it anyway).

# adb push /path/to/tmp/lineageos/parted /
/path/to/tmp/lineageos/parted: 1 file pushed, 0 skipped. 591.9 MB/s (464372 bytes in 0.001s)

Now shell in, mark /parted as executable for later, and check the partition layout.

# adb shell
~ # chmod +x /parted
~ # fdisk -l /dev/block/mmcblk0
Found valid GPT with protective MBR; using GPT

Disk /dev/block/mmcblk0: 30777344 sectors, 2740M
Logical sector size: 512
Disk identifier (GUID): 98101b32-bbe2-4bf2-a06e-2bb33d000c20
Partition table holds up to 28 entries
First usable sector is 34, last usable sector is 30777310

Number  Start (sector)    End (sector)  Size       Code  Name
   1            1024          132095       64.0M   0700  modem
   2          132096          133119        512K   0700  sbl1
   3          133120          134143        512K   0700  sbl2
   4          134144          138239       2048K   0700  sbl3
   5          138240          139263        512K   0700  tz
   6          139264          184319       22.0M   0700  boot
   7          184320          229375       22.0M   0700  recovery
   8          229376          230935        780K   0700  m9kefs1
   9          230936          232495        780K   0700  m9kefs2
  10          232496          234055        780K   0700  m9kefs3
  11          234496          235519        512K   0700  rpm
  12          235520          236543        512K   0700  aboot
  13          236544          237567        512K   0700  sbl2b
  14          237568          241663       2048K   0700  sbl3b
  15          241664          242687        512K   0700  abootb
  16          242688          243711        512K   0700  rpmb
  17          243712          244735        512K   0700  tzb
  18          244736          245759        512K   0700  metadata
  19          245760          278527       16.0M   0700  misc
  20          278528          311295       16.0M   0700  persist
  21          311296         2031615        840M   0700  system
  22         2031616         3178495        560M   0700  cache
  23         3178496        30775295       13.1G   0700  userdata
  24        30775296        30776319        512K   0700  DDR
  25        30776320        30777310        495K   0700  grow

/system is partition 21. In order to resize it, I need to move at least the next partition. /cache is next but at 560 MB, it was not large enough and I would also need to shrink userdata (or /data).

I saved the above layout in case I needed to redo it exactly. NOTE, I already unlocked the bootloader and wiped everything but if you haven’t, this will reformat and lose everything and you must start from scratch.

Unmount partitions 21, 22, and 23 if mounted.

~ # df -h
Filesystem                Size      Used Available Use% Mounted on
tmpfs                   935.1M     20.0K    935.1M   0% /dev
tmpfs                   935.1M     16.0K    935.1M   0% /tmp
/dev/block/mmcblk0p23
                         12.9G    129.6M     12.8G   1% /data
/dev/block/mmcblk0p23
                         12.9G    129.6M     12.8G   1% /sdcard
/dev/block/mmcblk0p22
                        551.7M      9.8M    541.9M   2% /cache
~ # umount /sdcard /data /cache

Delete partitions 21, 22, and 23.

~ # /parted /dev/block/mmcblk0
GNU Parted 3.2
Using /dev/block/mmcblk0
...
(parted) print
Error: The backup GPT table is corrupt, but the primary appears OK, so that will
be used.
OK/Cancel? ok

The backup GPT being corrupt was disconcerting but I couldn’t do anything about it so accepted and continued onward. The StackExchange answer used parted’s resizepart but that only works if there’s space after the partition. There is zero free space here so must delete and recreate.

Model: MMC 016G92 (sd/mmc)
Disk /dev/block/mmcblk0: 15.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name      Flags
 1      524kB   67.6MB  67.1MB  fat16        modem     msftdata
 2      67.6MB  68.2MB  524kB                sbl1
 3      68.2MB  68.7MB  524kB                sbl2
 4      68.7MB  70.8MB  2097kB               sbl3
 5      70.8MB  71.3MB  524kB                tz
 6      71.3MB  94.4MB  23.1MB               boot
 7      94.4MB  117MB   23.1MB               recovery
 8      117MB   118MB   799kB                m9kefs1
 9      118MB   119MB   799kB                m9kefs2
10      119MB   120MB   799kB                m9kefs3
11      120MB   121MB   524kB                rpm
12      121MB   121MB   524kB                aboot
13      121MB   122MB   524kB                sbl2b
14      122MB   124MB   2097kB               sbl3b
15      124MB   124MB   524kB                abootb
16      124MB   125MB   524kB                rpmb
17      125MB   125MB   524kB                tzb
18      125MB   126MB   524kB                metadata
19      126MB   143MB   16.8MB               misc
20      143MB   159MB   16.8MB  ext4         persist
21      159MB   1040MB  881MB   ext4         system
22      1040MB  1627MB  587MB   ext4         cache
23      1627MB  15.8GB  14.1GB  ext4         userdata
24      15.8GB  15.8GB  524kB                DDR
25      15.8GB  15.8GB  507kB                grow

(parted) rm 21
(parted) rm 22
(parted) rm 23

I switched the units to sectors to get the partition math exactly correct. I did not think using MB, or anything other than only B(ytes), would be precise enough and using bytes could cause a partition to not end on a sector boundary. parted warned if I did not end on a good boundary, I think every 2 MB? When doing the sector math, I ensured the three partitions ended on a 2 MB boundary and parted was satisfied.

(parted) unit S
(parted) print
Model: MMC 016G92 (sd/mmc)
Disk /dev/block/mmcblk0: 30777344s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start      End        Size      File system  Name      Flags
 1      1024s      132095s    131072s   fat16        modem     msftdata
 2      132096s    133119s    1024s                  sbl1
 3      133120s    134143s    1024s                  sbl2
 4      134144s    138239s    4096s                  sbl3
 5      138240s    139263s    1024s                  tz
 6      139264s    184319s    45056s                 boot
 7      184320s    229375s    45056s                 recovery
 8      229376s    230935s    1560s                  m9kefs1
 9      230936s    232495s    1560s                  m9kefs2
10      232496s    234055s    1560s                  m9kefs3
11      234496s    235519s    1024s                  rpm
12      235520s    236543s    1024s                  aboot
13      236544s    237567s    1024s                  sbl2b
14      237568s    241663s    4096s                  sbl3b
15      241664s    242687s    1024s                  abootb
16      242688s    243711s    1024s                  rpmb
17      243712s    244735s    1024s                  tzb
18      244736s    245759s    1024s                  metadata
19      245760s    278527s    32768s                 misc
20      278528s    311295s    32768s    ext4         persist
21      311296s    2811295s   2500000s  ext4         system
24      30775296s  30776319s  1024s                  DDR
25      30776320s  30777310s  991s                   grow

(parted) mkpart primary ext4 311296s 3178495s
(parted) mkpart primary ext4 3178496s 4202495s
(parted) mkpart primary ext4 4202496s 30775295s
(parted) print
Model: MMC 016G92 (sd/mmc)
Disk /dev/block/mmcblk0: 30777344s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start      End        Size       File system  Name      Flags
 1      1024s      132095s    131072s    fat16        modem     msftdata
 2      132096s    133119s    1024s                   sbl1
 3      133120s    134143s    1024s                   sbl2
 4      134144s    138239s    4096s                   sbl3
 5      138240s    139263s    1024s                   tz
 6      139264s    184319s    45056s                  boot
 7      184320s    229375s    45056s                  recovery
 8      229376s    230935s    1560s                   m9kefs1
 9      230936s    232495s    1560s                   m9kefs2
10      232496s    234055s    1560s                   m9kefs3
11      234496s    235519s    1024s                   rpm
12      235520s    236543s    1024s                   aboot
13      236544s    237567s    1024s                   sbl2b
14      237568s    241663s    4096s                   sbl3b
15      241664s    242687s    1024s                   abootb
16      242688s    243711s    1024s                   rpmb
17      243712s    244735s    1024s                   tzb
18      244736s    245759s    1024s                   metadata
19      245760s    278527s    32768s                  misc
20      278528s    311295s    32768s     ext4         persist
21      311296s    3178495s   2867200s   ext4
22      3178496s   4202495s   1024000s   ext4
23      4202496s   30775295s  26572800s  ext4
24      30775296s  30776319s  1024s                   DDR
25      30776320s  30777310s  991s                    grow

(parted) name 21 system
(parted) name 22 cache
(parted) name 23 userdata
(parted) unit MB
(parted) print
Model: MMC 016G92 (sd/mmc)
Disk /dev/block/mmcblk0: 15758MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start    End      Size     File system  Name      Flags
 1      0.52MB   67.6MB   67.1MB   fat16        modem     msftdata
 2      67.6MB   68.2MB   0.52MB                sbl1
 3      68.2MB   68.7MB   0.52MB                sbl2
 4      68.7MB   70.8MB   2.10MB                sbl3
 5      70.8MB   71.3MB   0.52MB                tz
 6      71.3MB   94.4MB   23.1MB                boot
 7      94.4MB   117MB    23.1MB                recovery
 8      117MB    118MB    0.80MB                m9kefs1
 9      118MB    119MB    0.80MB                m9kefs2
10      119MB    120MB    0.80MB                m9kefs3
11      120MB    121MB    0.52MB                rpm
12      121MB    121MB    0.52MB                aboot
13      121MB    122MB    0.52MB                sbl2b
14      122MB    124MB    2.10MB                sbl3b
15      124MB    124MB    0.52MB                abootb
16      124MB    125MB    0.52MB                rpmb
17      125MB    125MB    0.52MB                tzb
18      125MB    126MB    0.52MB                metadata
19      126MB    143MB    16.8MB                misc
20      143MB    159MB    16.8MB   ext4         persist
21      159MB    1627MB   1468MB   ext4         system
22      1627MB   2152MB   524MB    ext4         cache
23      2152MB   15757MB  13605MB  ext4         userdata
24      15757MB  15757MB  0.52MB                DDR
25      15757MB  15758MB  0.51MB                grow

Partitions created. I shrunk /cache from 587 MB to 524 MB and /data from 14.1 GB to 13.6 GB. /system went from 881 MB to 1468 MB.

Creating File Systems

Next re-created the ext4 file system for the three partitions.

~ # make_ext4fs /dev/block/mmcblk0p21
Creating filesystem with parameters:
    Size: 1468006400
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8160
    Inode size: 256
    Journal blocks: 5600
    Label:
    Blocks: 358400
    Block groups: 11
    Reserved block group size: 87
Created filesystem with 11/89760 inodes and 11769/358400 blocks
~ # make_ext4fs /dev/block/mmcblk0p22
Creating filesystem with parameters:
    Size: 524288000
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8000
    Inode size: 256
    Journal blocks: 2000
    Label:
    Blocks: 128000
    Block groups: 4
    Reserved block group size: 31
Created filesystem with 11/32000 inodes and 4110/128000 blocks
~ # make_ext4fs /dev/block/mmcblk0p23
Creating filesystem with parameters:
    Size: 13605273600
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8144
    Inode size: 256
    Journal blocks: 32768
    Label:
    Blocks: 3321600
    Block groups: 102
    Reserved block group size: 815
Created filesystem with 11/830688 inodes and 93063/3321600 blocks
~ # e2fsck -f /dev/block/mmcblk0p21
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
system: 2563/53760 files (0.0% non-contiguous), 176829/215040 blocks
~ # resize2fs /dev/block/mmcblk0p21
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/block/mmcblk0p21 to 358400 (4k) blocks.
The filesystem on /dev/block/mmcblk0p21 is now 358400 blocks long.

I forgot to verify if /system was created as a 1.4 GB file system or as 827 MB but resize2fs grew the file system so I assume it was too small. One last check that /etc/fstab will function

~ # cat /etc/fstab
/dev/block/mmcblk0p21 /system ext4 rw 0 0
/dev/block/mmcblk0p23 /data ext4 rw 0 0
/dev/block/mmcblk0p22 /cache ext4 rw 0 0
~ # mount /system
~ # mount /data
~ # mount /cache
~ # df -h
Filesystem                Size      Used Available Use% Mounted on
tmpfs                   935.1M     20.0K    935.1M   0% /dev
tmpfs                   935.1M     16.0K    935.1M   0% /tmp
/dev/block/mmcblk0p21
                          1.3G     26.2M      1.3G   2% /system
/dev/block/mmcblk0p23
                         12.4G    129.5M     12.3G   1% /data
/dev/block/mmcblk0p22
                        492.6M      8.6M    483.9M   2% /cache

Installing LineageOS

I tried to sideload the image now but there were errors about unable to detect filesystem for /dev/block/platform/msm_sdcc.1/by-name/system. I rebooted, skipped through the warning about no OS, and booted the recovery image again from fastboot.

I had numerous issues when trying to sideload the last nightly LineageOS 15.1 image for the Nexus 4 along with the matching Open GApps. That image resized /system back to 827 MB each time. After growing it again to sideload Open GApps, rebooting would load LineageOS only for it to reboot into the recovery image.

What did work was the unofficial image created by voron00 and the matching Open GApps for Android 9.0, micro version. The LineageOS 15.1 image also shrunk /system a small amount that I grew back to its maximum size before sideloading Open GApps.

# adb sideload /path/to/tmp/lineageos/lineage-16.0-20210311-UNOFFICIAL-mako-signed.zip
Total xfer: 1.00x
# adb shell
# ...resizing again...
# adb sideload /path/to/tmp/lineageos/open_gapps-arm-9.0-micro-20210409.zip
Total xfer: 1.07x
# adb reboot

I watched the LineageOS boot screen for a long time and then the Android 9.0 startup screen appeared. I breezed through the setup and the device was ready.

I also have the Nexus 7 from 2012 (code name grouper) that suffers from the same problem. Next up, moving that to something newer than the CyanogenMod 12.1 install.