[Samsung Galaxy Note 8 ROMs, Kernels, Recoveries, &] BigCountry907:
Setting Registers and running Arm Binaries

So things have certainly got complex fast. ( Understand that much of this is new to me as well )

In reality the method I have described so far using safestrap to hijack the boot and then load U-boot isn't truly unlocking the bootloader. :crying:

But if accomplished it will allow us to chainload bootloaders from the android user-space. By chainloading U-Boot from userspace we can leverage U-boot to load and execute any code we want. :victory:

At that point for example you could load efidroid using u-boot to have a efidroid multiboot environment.

For a moment I was starting to worry that there were going to be unforeseen limitations that would prevent loading U-Boot.

My biggest concern was how to Load U-Boot into SRAM and start its execution from userspace. There is no situation that exist in a normal circumstance that would require such a function therefore research as much as you like and you will find nothing. Necessity being the mother of invention.

Since our device is locked and we want to run custom systems on them the necessity is persistent and the invention is in process. I'm kind of surprised that samsung or qualcomm or any other device manufacturer has not considered this approach especially considering if it works for us it will work on any device that you can get root access too.

My madness is a low level approach and more of a arm bare metal technique than android development. I'm always stuck in the box trying to use tools that are already written or leverage a binary built for something else.

When you start studying bootloaders and arm processors you kind of end up in a world of ARM Code.

I was referring to registers or cpu registers and the like a couple post back. Where there is an example of someone loading U-Boot to RAM but not having the registers set correctly and seeing U-Boot hang. After pondering this a bit I started looking into how to set registers from userspace and that kinda turned into how to run an arm binary from userspace and the next thing you know I'm sitting here saying to myself "That's the Answer":confused:

I have been reading a book on bare metal programming and seen some simple arm programs then searching the web I came across a pretty basic arm program and then it dawned on me..........:eek:

This is what we need.

At first glance you would think it's all unrelated but if you read into it what is explained is exactly what we want to accomplish.

https://medium.com/@urish/writing-your-first-android-app-in-assembly-30e8e0f8c3fe

in assembly:

.text
.globl _start

_start:
mov %r0, $1	// file descriptor number 1 (stdout)
ldr %r1, =message
mov %r2, $message_len
mov %r7, $4	// syscall 4 (write)
swi $0

mov %r0, $0	// exit status 0 (ok)
mov %r7, $1	// syscall 1 (exit)
swi $0

.data
message:
.ascii "Hello, World\n"
message_len = . - message

If you have never seen assembly code before, this program can be quite intimidating, but don’t worry — we’ll go over it together.

The program is divided into two sections: text , which contains the machine code instructions, and data, starting in line 15, which contains variables, strings and other data. The .text section is usually read-only, whereas the .data section can also be written to.

In line 2, we define a global function called _start. This is the entry point of the program. In other words, the operating system will start running you code from this point. The actual definition of the function is in line number 4.

The function does two things: line 5–9 print the message to the screen, and lines 11–13 terminate the program. You could actually remove lines 11–13 and the program will string print “Hello, World” and exit, but it wouldn’t be a clean exit — it will just crash trying to execute some random invalid instruction which happens to be next in memory.

Printing to the screen is done by calling a system call. A system call is a function provided by the operating system. We call the write() system call, which we indicate by loading the value 4 into a CPU register called r7 (line 8), and then execute the swi $0 instruction (line 9), which jumps right into the Linux kernel running inside Android.

The parameters for the system call are passed through the other registers: r0 indicates the number of the file descriptor we want to print to. We put there the value 1 (line 5), which indicated stdout, the standard output, or in other words — printing to the screen.

r1 indicates the memory address of the data we want to write, so we load there the address of the “Hello, World” string (line 6), and r2 tells Android how many bytes we want to write. We set it to the value of message_len (line 7), which is calculated in line 18 using a special syntax: the dot symbol denotes the current memory address, so . - message means the current memory address minus the address of message. Since we define message_len immediately after message, this evaluates to the length of message

If you fall back to this thread.

https://devtalk.nvidia.com/default/...load-and-boot-from-ram-using-tftpboot-method/

There is some chatter about setting the registers.

Long story short what i see is this.

We need to write in assembly language the loader for the u-boot binary.

It needs to accomplish 3 things.

#1 ) Load the U-Boot.bin (not u-boot.img ) binary to a specific address in RAM.

#2) Reset the cpu registers IF NEEDED.

( I'm thinking we can use the fw_printenv and fw_setenv statically compiled binaries to set the load address of our kernel and our device tree table.

#3) Execute or Jump to the U-Boot.bin.

All in all i am not sure how complicated writing that will be. It seems not very difficult or at least there are very few things than need to happen.

I still have not played with the tftp boot yet to determine if this is a host side command or a target device command.

What you have to really keep in mind is that tftp boot is a function of the U-Boot.bin.

When U-Boot.bin is loaded that function is available but our U-boot.bin is not loaded thats what we want to accomplish.

The question now is how to take the source code from U-boot (specifically the tftp boot function) and write in arm assembly language ( Might already be ) else its written in ( C ).

If we have the tftp boot function written in arm assembly we can ( arm-linux-androideabi-as -o hello.o hello.s ) to make it an ELF binary and then ( arm-linux-androideabi-ld -o hello hello.o ) to compile the executable binary.

Running the binary would take care of the Target side tftp boot and properly handle the U-Boot.bin tftp from the host. :cowboy:

This is a whitepaper describing exactly what im talking about.

However the method is a bit more advanced than what i'm shooting for we dont need a gui and all.

https://www.ijser.org/researchpaper/Ethernet-Boot-loader-for-ARM-Processor.pdf

Maybe this is the way to go. Or something to start with.

https://knowledge.windriver.com/en-...atform_Developer's_Guide,_8.0/050/020/020/000

I would buy this ethernet adapter because it supports PXE Boot.

https://www.amazon.com/Dell-FBA_DBQ...069&sr=1-3&keywords=Ethernet+adapter+PXE+Boot

Then if we can find PXE support for android that'll work.

Im just throwing around a few ideas here.

Cough Cough...... :good:

https://www.safaribooksonline.com/l...60/55d932d9-700b-42ee-81a3-8e605d60cc84.xhtml

And one more link. But i believe there already booted to U-Boot.

https://wiki.linaro.org/Platform/Android/NetbootAndroidKernel