Exynos4 Bootrom

Background information

The Replicant project wants to support devices with free software bootloaders, but most/all the smartphones and tablets supported by Replicant do check the signature of the first stage bootloader.

A presentation on the situation of some of the devices supported by Replicant was made at the Replicant contributors meeting in July 2019. The presentation slides and video are available.

Exynos 4 signature check

The Exynos4 bootrom has a strange way to check the signatures:

Attempts

xboot

xboot is an OS that is supposed to run as the BL1 on a board that has the the Exynos 4412.

There is an attempt to port it and run it on the Galaxy SIII but it didn't succeed yet.

func_ptr_BaseAddr

If the xboot attempt doesn't work we could also try to understand with qemu2 or a developement board that has JTAG, if func_ptr_BaseAddr is somehow used by the bootrom when verifying the BL1.

Testing with qemu2 is probably way more easy than using the JTAG.

If it is we might be able to replace the bootrom check function.

1 https://fredericb.info/2018/03/emulating-exynos-4210-bootrom-in-qemu.html

2 https://github.com/frederic/qemu-exynos-bootrom

JTAG, fuses and EMMC RPMB

According to a post on the gsmhosting.com forum :

 Threr are 2 types of devices exist.

1. EXYNOS Devices with JTAG Disabled ( GT-I9300,GT-I9500,GT-N7100 etc.)

    KNOX Warranty bit are stored inside of RPMB area in eMMC
    Downgrade protection byte are stored in RPMB.

So if that's true for most common devices and that we don't find a way to re-enable the JTAG we probably cannot use it to load bootloaders and/or to experiement with the hardware on these devices.

However it's probably still possible to use JTAG on some devboards.

The thing we can learn from this post is also that unlocking the device probably don't change the Exynos 4 fuses. I wonder why it is implemented this way when other devices use fuses. And for the devices that use fuses, what is the fuse bit used for? Is it to prevent the fuses to have all bits be modified to zero or 1 and which would make it easier to compute the private key? Does the Qualcomm SOCs have a more granular approach to fuses? How does the Management Engine which also burn fuses at runtime handle that?

Other tests to attempt

Other

Running the GT-I9100 bootrom in qemu

There has been some work from new Replicant contributor to package a qemu version that can run the Galaxy SII (GT-I9100) bootrom.

It's a docker file based on Ubuntu 16.04 LTS (Xenial Xerus), but it's probably possible to use Trisquel 8.0 LTS (Flidas) instead.

See the Emulating Exynos 4210 BootROM in QEMU for more background information on the topic.

Rebooting to u-boot

On several SOCs families you can override the boot pins through register writes.

For instance on the OMAP 3630 you have a register for that at 0x48002910 which is publicly documented in its technical reference manual.

Not all the system on a chip have something like that.

If registers to do that are found for the Exynos 4412, rebooting directly to u-boot from s-boot should be pretty easy to do.

The i9300_emmc_toolbox project can execute code in s-boot, and we can easily write C code to be executed in it.

Some examples are provided in the shellcode directory.

So it would be trivial to write to a register and use the already provided reboot function.

TODO:

Note that this has not been seen in use yet, including in the Galaxy SIII repair manual , which shorts a resistor to change the boot modes. Though the Samsung branch that does the smartphones and tablets is separate from the branch doing the System on a chip. So for instance the System on a chip branch was providing SOCs to Apple for its Iphones while consumer electronics branch was at (legal) war against Apple.

HOWTO

Loading a bootloader from SD

When booting Parabola with a Replicant 10 kernel on a Galaxy SIII (i9300), it is possible to erase the bootloader to make the device boot from the microSD instead.

This could be used to do some testing, for instance to see if the BL1 signature can somehow be bypassed, however as no free software bootloaders do exist yet (u-boot relies on nonfree and non-redistributable software), this is not very useful yet.

If you really want to erase the bootloader (your device will be broken and will never boot anymore), you could run the following:

# echo 0 > /sys/class/block/mmcblk2boot0/force_ro
# ddrescue -f /dev/zero /dev/mmcblk2boot0
GNU ddrescue 1.24
Press Ctrl-C to interrupt
     ipos:    4194 kB, non-trimmed:        0 B,  current rate:   4194 kB/s
     opos:    4194 kB, non-scraped:        0 B,  average rate:   4194 kB/s
non-tried:    9223 PB,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:    4194 kB,   bad areas:        0,        run time:          0s
pct rescued:    0.00%, read errors:        0,  remaining time:         n/a
                              time since last successful read:         n/a
Copying non-tried blocks... Pass 1 (forwards)
ddrescue: Write error: No space left on device

And then verify that it's erased:

# hexdump -C /dev/mmcblk2boot0
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00400000

Also verify that the following partitions are also erased:

I'm not sure what BOTA0 and BOTA1 are but they were already blank in my case.

Recovering from a bad bootloader

Note that I didn't manage yet to go from u-boot to s-boot.

Requirements: HOWTO:

You then should have u-boot running which can boot Parabola, so you can then easily recover.

Note that to run Parabola you need to make sure that you use an MBR and no gpt as u-boot is to be put at the second 512B block.