xc-racer99 / u-boot-aries

U-boot port for first-gen Galaxy S devices. Flashed in place of kernel with stock IBL/PBL/SBL. Kernel read from OneNAND/MMC/SD/Serial.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use u-boot's SPL in place of stock PBL/SBL

MYEUHD opened this issue · comments

Since the internal UART is relatively hard to set up. Does the following make any sense:
We somehow get panel support then reuse it to display debugging info during u-boot bringup as a PBL/SBL? (then get USB serial support?)

If you're planning on getting u-boot as a PBL, you'll need the signed first-stage shim bootloader that's used in the Humming Bird Interceptor Bootloader unless you feel like hacking the encryption.

Personally, making it work as a PBL is very, very low on my priority list, and I think internal UART would be much easier than trying to get the panel working first. If you go through the history on Goni there are remnants of a PBL there (onenand_ipl), plus Odroid-T bootloader source (originally u-boot based but with so many changes that it's only worth it as a reference).

I'm aware that I'll need an IBL that doesn't check the signature of the next stage. But I didn't know that there was another way; What do you mean by hacking the encryption?

I'm interested in getting u-boot as a PBL/SBL.But, to be honest, I'm a total newbie at C programming (I know some Java though...)
Any good book recommendations to learn C?

Theoretically, there was a bit of a discussion on doing that for the i9100 as there's no PBL that drops it for exynos 4210, see oranav/i9300_emmc_toolbox#2 at around April 8, 2018

I'm kind of the wrong person to ask about books, as I'm self-taught. However, I have heard that https://en.wikipedia.org/wiki/The_C_Programming_Language is the book to read. I think it's available online somewhere but I'm not sure.

@MYEUHD
dmarszk/hummingbird-hibl#6
But currently our uboot is missing many things - for example it don't charge battery.
Also having stock bootloader (with download mode), could be nice "backup" plan.
If we mess something with uboot we can just use it to reflash, but if uboot replaces stock bootloaders, then it would be much harder to fix device.

If hacking the encryption makes it possible to replace the IBL with u-boot spl, we could make it look for the next stage in sdcard then emmc then oneNAND.(the opposite of the iROM behaviour)
That way, when you mess up your phone i.e if any stage of the bootloader gets corrupted, you can simply put u-boot in an sdcard and boot from it. (without the need for the unbrickable mod)

I agree that it's not a high priority right now. Working on the mainline kernel is much more rewarding. But it's a nice thing to have in the future.

Alright, I've been playing around with this a bit since my working theory on the reason that suspend doesn't work on mainline kernels is related to something that the bootloader is doing on resume (there is a similar issue with stock kernels if URT2 is enabled and/or FIQ debugger is disabled).

I've created a branch at https://github.com/xc-racer99/u-boot-galaxys4g/tree/hibl-poc which is a reimplementation of dmarszk/hummingbird-hibl#6 - after building, you need to use cat to connect the signed shim with the aries-spl.bin output (however, the total size of the first stage bootloader should be 8192 bytes, so you should run cat signed_bl1 signed_bl1 aries-spl.bin > HIBL.bin). Note you will also need to adjust the path to init_by_rebell.bin as I have hardcoded it in board/samsung/aries/lowlevel_init.S

I've learned a little bit from my testing, namely:

  • Where the stack addresses and entrypoints should be
  • That PS_HOLD_CTRL needs to be or'ed with 0x301 to prevent power off when the usb cable is unplugged
  • Some of the bits of the original HIBL weren't needed on my variant (the cleaning of the USB ep ptr for one as well as backup and restore of the uart ptr - although I don't have internal serial so that may affet things)
  • Booting from SD is impossible without OM resistor changes, so we will need to work on getting OneNAND to boot (assuming the signed shim works from OneNAND as well...)
  • Based on the goni lowlevel_init.S/mem_setup.S, the HWREV GPIOs (GPJ0) are for what MCP revision each device is and thus how much ram is present.

Future steps (in no particular order) include

  • Seeing if we can use the OneNAND SPL to boot the modified HIBL SBL that goes into download mode
  • Seeing if we can boot the stock SBL with u-boot's OneNAND SPL
  • Seeing if we can boot u-boot directly from this setup (ie in place of the SBL)
  • Trying to replace init_by_rebell.bin with an open-source equivalent. From dumping registers on my device, it appears that the goni mem_setup.S sets things up differently from the stock PBL. Clocks are different too, but that's not surprising.

Alright, I've worked a little bit more, here are my findings:

  • DMC1's MEMCONFIG1 (0xF140000C) is different for different variants. Based on iFixit teardowns, some objdumps of bootloaders (stock boot.bin), and some supposition, anything containing KB100L00WM (those with 1GB of OneNAND, notably SGH-T959P/V/W, Sidekick, Epic) should have 0x50F81222 while everything else that has KB100D00WM (i9000, SGH-T959, SCH-i500, Nexus S, etc) should have 0x50f81312. This appears to be the only difference in RAM setup.
  • The default Goni memsetup does sort-of appear to work, but I'm not sure what it's missing (RAM or otherwise). I've been testing with it loading the stock SBL - using the init_by_rebell.bin (which appears to be a lightly modified IBL) it works, but I just get a slight but recognizable flicker of the charging loading symbol on the screen before an instant reboot.
  • The signed shim does work with OneNAND and the stock boot.bin. If you replace the first 4096kb of the stock boot.bin with the signed shim, it will work just fine. This means that there is still the secure boot header before BL1 stage2 (ie second part of boot.bin or IBL). However, this identical shim is also used on the Odroid-7/Odroid-T and based on a dump of an image for it, the secure boot header is not present (nor is it present in u-boot source). So obviously there is some variable that I am missing here - or else it tries secure boot first, and failing that, tries booting again without the header. What the entrypoint would be as well is unknown (could be 0xD0020800 based on https://forum.xda-developers.com/showthread.php?t=1233273).
  • Because of the unknown entrypoint above, I haven't been able to use a custom IBL from OneNAND yet.

Ok, I have finally managed to boot a custom binary from something other than USB. However, this something is an SD card :)

I've created a branch at https://github.com/xc-racer99/u-boot-galaxys4g/tree/sdcard-spl with all the necessary bits. The entrypoint is 0xd0021000. You do need an IBL/PBL brick, so I've added a bootmenu entry to do this (note that by default it won't show up as I've replaced the fastboot entry). By creating an IBL/PBL brick, you can also using the Hummingbird Interceptor bootloader (HIBL) without needing the unbrickable mod applied.

I'm theorizing that this entrypoint should also be the same for OneNAND, but that for some reason the IROM loads in the second page of the onenand on my test device. This might be because I screwed up making the unbrickable mod and have the OM_STAT of a demux OneNAND as opposed to a mux OneNAND device.

There is still a bunch of work to do, notably the battery charging, getting the ram timings all working, porting the assembly code to c code. This however is a good first step.

Not sure if this is helpful, but it looks like xboot might have written their own libre BL1 for the Exynos4412: https://github.com/xboot/xboot/tree/master/src/arch/arm32/mach-exynos4412

Replicant is trying to get it working: xboot/xboot#21

We already have mainline U-Boot running in BL2 with only a few patches on top.

Not sure if this is helpful, but it looks like xboot might have written their own libre BL1 for the Exynos4412: https://github.com/xboot/xboot/tree/master/src/arch/arm32/mach-exynos4412

Replicant is trying to get it working: xboot/xboot#21

We already have mainline U-Boot running in BL2 with only a few patches on top.

Yeah, I have a BL1* using u-boot's SPL at #31 - it works great with Linux, not quite perfectly with Android kernel (probably not resuming all needed clocks/clock settings). Was suppposedly having some issues on an i9000 with the volume keys not detecting in u-boot proper, but I think that might have been resolved.

  • Using the signed first-stage shim that was released with the Odroid-T/S/7, among other various vendor u-boot releases. I don't think there's a way around this though - if there is, please let me know :) I did notice xboot/xboot#19 - but I'm guessing the mk4412 tool is the BL1 blob for 4412.

It seems as though the Origen Board doesn't require any signed first-stage shim. This blog post suggests that u-boot at the time was able to build a BL1 (called u-boot-mmc-spl.bin at the time) in 2011: https://ssvb.github.io/2011/07/30/origenboard-early-adopter.html

The Origen Board uses the same SoC as the i9100. Here's the current code that generates the unsigned BL1 in upstream u-boot: https://gitlab.denx.de/u-boot/u-boot/blob/master/board/samsung/origen/tools/mkorigenspl.c

I've found a number of downstream exynos4412 u-boot implemenations that attempt to mimick this same strategy to get rid of the signed first-stage shim, but we haven't tested any of them on a Replicant device yet.

https://github.com/abcamus/uboot/blob/master/board/samsung/landrover/tools/mklandroverspl.c
https://github.com/X-Project-FriendlyARMTiny4412/u-boot/blob/u-boot-v2017.03-tiny4412/board/samsung/tiny4412/tools/mktiny4412spl.c
https://github.com/chasinglulu/u-boot/blob/exynos4x12-uboot/board/samsung/itop4412/tools/mkitop4412spl.c

xboot, which i linked to above, seems to be doing the same thing outside of uboot. @GNUtoo is doing some tests to try to get this to work on a Replicant phone but we haven't gotten any output yet to confirm that it is booting.

@HerbsM Remember that on i9000 we have s5pv210, not like exynos4412 in i9100 :). Not sure if bl1 are similar on those soc.

exynos4412 is on the i9300 not the i9100. I am aware that the SoC is different on the i9000. I was simply just updating you on the research I've been doing on the matter because I figured it perhaps would be relevant.

@herbsmn And thanks for this!!. I just thought that someone mistaken i9000 with i9100 :)

Yeah, you're very welcome! :-)

It seems as though the Origen Board doesn't require any signed first-stage shim. This blog post suggests that u-boot at the time was able to build a BL1 (called u-boot-mmc-spl.bin at the time) in 2011: https://ssvb.github.io/2011/07/30/origenboard-early-adopter.html

The Origen Board uses the same SoC as the i9100. Here's the current code that generates the unsigned BL1 in upstream u-boot: https://gitlab.denx.de/u-boot/u-boot/blob/master/board/samsung/origen/tools/mkorigenspl.c

I've found a number of downstream exynos4412 u-boot implemenations that attempt to mimick this same strategy to get rid of the signed first-stage shim, but we haven't tested any of them on a Replicant device yet.

https://github.com/abcamus/uboot/blob/master/board/samsung/landrover/tools/mklandroverspl.c
https://github.com/X-Project-FriendlyARMTiny4412/u-boot/blob/u-boot-v2017.03-tiny4412/board/samsung/tiny4412/tools/mktiny4412spl.c
https://github.com/chasinglulu/u-boot/blob/exynos4x12-uboot/board/samsung/itop4412/tools/mkitop4412spl.c

xboot, which i linked to above, seems to be doing the same thing outside of uboot. @GNUtoo is doing some tests to try to get this to work on a Replicant phone but we haven't gotten any output yet to confirm that it is booting.

Interesting, I will try and investigate if this is the case on s5pv210 as well. I do wonder if even if it does boot, if things like suspend/resume no longer work (this is the case when booting from a "fallback" SD card on s5pv210 - ie when the OM resistors say something, that fails, so it falls back to the SD)

Hmm, doesn't appear to work on the SGH-T959P :( With a quick from the shimmed SPL of

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 81edec01bf32..fe050093d284 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -66,7 +66,7 @@ switch_to_hypervisor_ret:
  * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
  * Continue to use ROM code vector only in OMAP4 spl)
  */
-#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
+#if !defined(CONFIG_SPL_BUILD)
 	/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
 	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTLR Register
 	bic	r0, #CR_V		@ V = 0
diff --git a/board/samsung/aries/tools/mkariesspl.c b/board/samsung/aries/tools/mkariesspl.c
index c68fc1fff380..6a1ba20eb1a9 100644
--- a/board/samsung/aries/tools/mkariesspl.c
+++ b/board/samsung/aries/tools/mkariesspl.c
@@ -5,9 +5,62 @@
  *	djpark (2009.08.10)
  */
 #include <stdio.h>
-#include "BL1_stage1_bin.h"
 
-#define BL1_PAD_LENGTH	0x2000
+//#define DEBUG_MSG
+
+#define DEFAULT_IN_FILE		"BL1.bin"
+#define DEFAULT_OUT_FILE	"BL1.bin.padding"
+
+
+#define BL1_LENGTH			(8*1024)
+#define BL1_PAD_LENGTH		BL1_LENGTH
+
+
+int get_info(char* file, unsigned int* size, unsigned int* cs)
+{
+	FILE *fp_read = NULL;
+	int ret = -1;
+	unsigned int data = 0;
+	unsigned int length = 0;
+	unsigned int checksum = 0;
+	int i;
+
+	fp_read = fopen(file, "rb");
+	if (fp_read == NULL)
+	{
+		printf("File open error! - %s\n", file);
+		goto err;
+	}
+
+	while (ret = fread(&data, sizeof(unsigned int), 1, fp_read))
+	{
+		length += 4;
+
+		checksum += ((data >> 0) & 0xff);
+		checksum += ((data >> 8) & 0xff);
+		checksum += ((data >> 16) & 0xff);
+		checksum += ((data >> 24) & 0xff);
+	}
+
+	printf("Input File Length: %d Bytes\n", length);
+
+	if (length > BL1_LENGTH)
+	{
+		printf("Error: Length of %s SHOULD not be larger than %d bytes.\n", file, BL1_LENGTH);
+		goto err;
+	}
+
+	printf("Checksum: 0x%08X\n", checksum);
+
+	*size = length;
+	*cs = checksum;
+
+	ret = 0;
+err:
+	if (fp_read != NULL)	fclose(fp_read);
+
+	return ret;
+}
 
 int make_image(char* input_file, char* output_file)
 {
@@ -16,6 +69,13 @@ int make_image(char* input_file, char* output_file)
 	int ret = 0;
 	unsigned int data = 0;
 	unsigned int length = 0;
+	unsigned int checksum = 0;
+
+	if (get_info(input_file, &length, &checksum))
+	{
+		printf("Error: Unable to get file informations!\n");
+		goto err;
+	}
 
 	fp_read = fopen(input_file, "rb");
 	if (fp_read == NULL)
@@ -31,17 +91,23 @@ int make_image(char* input_file, char* output_file)
 		goto err;
 	}
 
-	/* Signed shim */
-	fwrite(BL1_stage1_bin, sizeof(unsigned char), BL1_stage1_bin_len, fp_write);
+	data = 0;
+	length = BL1_LENGTH;
+	fwrite(&length, sizeof(unsigned int), 1, fp_write);
+	fwrite(&data, sizeof(unsigned int), 1, fp_write);
+	fwrite(&checksum, sizeof(unsigned int), 1, fp_write);
+	fwrite(&data, sizeof(unsigned int), 1, fp_write);
+
+	length = 16;
 
-	while ((ret = fread(&data, sizeof(unsigned int), 1, fp_read)))
+	while (ret = fread(&data, sizeof(unsigned int), 1, fp_read))
 	{
 		length += 4;
 		fwrite(&data, sizeof(unsigned int), 1, fp_write);
 	}
 
 	data = 0;
-	for (; length < BL1_PAD_LENGTH; length += 4)
+	for (; length < (BL1_PAD_LENGTH-4); length += 4)
 	{
 		fwrite(&data, sizeof(unsigned int), 1, fp_write);
 	}
@@ -55,7 +121,12 @@ err:
 
 int main(int argc, char* argv[])
 {
-	if (argc == 3)
+	if (argc == 1)
+	{
+		printf("Default input/output files are used!\n");
+		return make_image(DEFAULT_IN_FILE, DEFAULT_OUT_FILE);
+	}
+	else if (argc == 3)
 	{
 		return make_image(argv[1], argv[2]);
 	}
diff --git a/include/configs/s5p_aries.h b/include/configs/s5p_aries.h
index af5aee58f852..a8b781241f9a 100644
--- a/include/configs/s5p_aries.h
+++ b/include/configs/s5p_aries.h
@@ -30,7 +30,7 @@
 /* DRAM Base */
 #define CONFIG_SYS_SDRAM_BASE		0x30000000
 
-#define CONFIG_SPL_TEXT_BASE		0xD0021000
+#define CONFIG_SPL_TEXT_BASE		0xD0020010
 #define CONFIG_SPL_MAX_FOOTPRINT	0x2000
 #define CONFIG_SPL_STACK		0xD0036000

applied I get nothing on the screen. So if it does exist there must be some other "magic" header other than the typical s5pc110 header generated by the odroid mkbl1.c code. Looking at the shim, it appears the second byte of data (0xd0020914) is the end of the non-zero/non-signature code in BL1. I don't know what the last the header bytes (0x000004ec) would be.

@herbsmn Maybe You have something also for exynos8890 ;) ?

Yes, I'm aware that one exists. Unfortunately, it says "Samsung Confidential and Proprietary" on the front page so I've been trying to avoid using it as IANAL. It is in most s5pv210 dev boards info packages that are freely available though, so who knows. The earlier revisions of the s5pc110 manual don't have this proprietary marking, but the later ones do. Chapter 6 of this manual contains the booting sequence and says

The iROM loads the first boot loader image from a specific booting device to internal 96KB SRAM. The booting device is selected by Operating Mode (OM) pins. According to the secure boot key values, the iROM code may do an integrity check on the first boot loader image.

As well, in the flowchart there it says that if the secure boot check fails, then booting stops. To me, the "secure boot key values" are probably the SECKEY registers and if the values are not 0 (which they aren't), then the iROM will validate the BL1. That's echoed in https://forum.xda-developers.com/showthread.php?t=1233273 where it says

This enabled Adam to load various data through iROM download mode straight into iRAM. And here comes disappointment - all data we tried to load were validated by iROM code against SECKEY and rejected with "Secure Fail Error", BL1 code loaded by iROM must contain 512 bytes of e-sign, consist of 2 public rsa keys and few sha-1 hashes.

The Odroid s5pv210 devices also use the signed shim, and apparently have the seckey registers set as well.

In short, while I wish it were possible to remove the shim, I don't think there's any way of doing it, at least on s5pv210 :( I wish you guys the best of luck on 4412!

Sorry for posting that link without mentioning the fact that it says confidential on it. It very well might be public now, but since Samsung doesn't provide a list of all currently public documents in an easy to search location it is hard to know.

We are able to boot u-boot and gnu+linux without trustzone. Do you think that this gives us the ability to extract anything from the secure area that might be helpful for us to look at? I assume all it will do is give us some public keys that we would then need to brute force, right?

Based on our analysis of the xboot code and accompanying documentation, it seems like they got around things another way though. I'll make sure to keep you updated if we figure something out.

We are able to boot u-boot and gnu+linux without trustzone. Do you think that this gives us the ability to extract anything from the secure area that might be helpful for us to look at? I assume all it will do is give us some public keys that we would then need to brute force, right?

I don't think it will help on s5pv210. The public keys on s5pv210 are already available and the entire IROM has been successfully dumped. I definitely don't have a computer good enough to brute force the keys :) s5pv210 also doesn't have a trustzone implementation, so we're lucky that way.

Based on our analysis of the xboot code and accompanying documentation, it seems like they got around things another way though. I'll make sure to keep you updated if we figure something out.

Ok, good to know. Please do let me know if you guys do figure out something that might be useful!

Ah, I didn't know you didn't have TZ on the device you are working on. That's good to know. Yeah, if they implemented the crypto correctly we almost certainly would have to use a side channel attack rather than brute force attack. Either way though, I'm not sure if anyone has dumped the entire irom on the 4412 yet or not. I should look into that.