2018/6/15

Google Pixel modem.img mod for Chinese carriers

Carriers in China like China Telecom was stuck on CSFB mode of 4G NOT globally popular VOLTE mode, so most cell-phones not selling in China are probably incompatible here. Google Pixel is the particular one.

We must believe that Qualcomm's modern SoC surely support numerous LTE bands and modes, for it's hard to put different specs of SoC to a large production line.
It's a matter of software.

I've experienced diag mode hacks on LG, Samsung devices. With Qualcomm's QPST you can tune a lot of radio stuff.

The main idea is:
  1. enable diag mode (setprop sys.usb.config diag,adb) with AOSP self-built firmware (actually you can just simply flash vendor.img fetched from here https://developers.google.com/android/drivers)
  2. patch carrier_policy.xml to support CSFB
However, there is a setback: this patch will be reverted by OTA or a SIM card reload.
Then you need to backup and restore the patched EFS (/dev/block/platform/soc/624000.ufshc/by-name/modemst(1or2)).

Another solution is to patch the modem.img, details introduced here:

The modem.img contains radio firmware and carrier configs etc.
Pixel's modem.img is a FAT system image.
After "mount -t vfat modem.img -o rw,umask=0000,shortname=lower modem", you can find all carrier configs at modem_pr/mcfg/configs/mcfg_sw.
The config mcfg_sw.mbn is an ELF compiled by ARM Compiler based on the vendor's config set. Likely it is running in the radio modem processor.

What if we copy configs from other devices that natively support more carriers?
OnePlus 3T is one choice, same Snapdragon 821 SoC. The modem firmware is located in NON-HLOS.img.
Much richer config set here:
├── apac
│   ├── airtel
│   ├── dcm
│   ├── kddi
│   ├── reliance
│   └── sbm
├── china
│   ├── cmcc
│   ├── ct
│   └── cu
├── common
│   ├── default
│   ├── row
│   └── w_one
├── eu
│   ├── dt
│   ├── ee
│   ├── h3g
│   ├── orange
│   ├── telefoni
│   └── vodafone
├── korea
│   ├── lgu
│   ├── skt
│   └── tta
├── na
│   ├── amx
│   ├── att
│   ├── sprint
│   ├── tmo
│   ├── uscc
│   └── verizon
├── oem
│   └── overseas
├── russia
│   ├── beeline
│   └── megafon
├── sa
│   └── brazil
└── sea
    ├── 3hk
    ├── ais
    ├── dtac
    ├── hkt
    ├── smartfre
    ├── smartone
    ├── trumove
    └── ytl

Now the problem is that modem.img in Pixel is truncated to real data size, we don't have enough spaces to add more configs.

Two ways to go:

1, extend the original modem.img

Firstly file modem.img:
DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "MSDOS5.0", Bytes/sector 4096, sectors/cluster 4, root entries 512, Media descriptor 0xf8, sectors/FAT 3, sectors/track 63, heads 255, sectors 16384 (volumes > 32 MB), reserved 0x1, serial number 0xbc614e, unlabeled, FAT (16 bit)

The real filesystem is 4096*16384=67108864, but the modem.img size is lower, which means some tool compact the image to the actually used size. We can append the "lost" bytes, and do fsck:
dd if=/dev/zero  bs=1  count=8421376 >> modem.img
fsck.vfat -v -y modem.img

2, mkfs a new image (I actually have not tested, you may try):
truncate -s 67108864 modem.img
mkfs.vfat -S 4096 -F 16 modem.img

After the config set replaced, we have a brand new modem.img, let's flash it:
fastboot flash modem modem.img (only flash the active slot)

Another problem came, by far modemst/EFS still was configured with old modem.img, how to manually trigger the modemst/EFS update?
I've tested OTA or a SIM card reload mentioned before, the chance is pretty low.
Finally I find a way: remove /data/misc/radio

Network connected.

You're welcomed to comment if you come to any question.

Google Pixel modem.img mod for Chinese carriers

Carriers in China like China Telecom was stuck on CSFB mode of 4G NOT globally popular VOLTE mode, so most cell-phones not selling in China ...