Samsung Galaxy S9 (samsung-starqltechn)/u-boot

U-boot can be used as a second stage bootloader, and also a tool to experiment with uart on usb.

Using u-boot as a second stage bootloader involves packing u-boot instead of linux kernel, and u-boot's payload instead of initramfs in android boot image.

Second stage bootloader
In this section, we'll generate an android boot image with u-boot as second stage bootloader for linux kernel in FIT image format.

Build u-boot

 * clone u-boot repo
 * prepare default config
 * build
 * create payload for SBOOT by gzipping and appending dtb:

Build kernel

 * build starqltechn kernel with envkernel.sh

Generate android boot image
/dts-v1/;
 * create bootscript.sh file:
 * build ramdisk
 * create boot.its file, describing u-boot's payload:

/ {       description = "Samsung S9 SM-G9600 starqltechn FIT Image"; #address-cells = <1>; images { bootscript { description = "Boot script"; data = /incbin/("bootscript.sh"); type = "script"; compression = "none"; load = ; entry = ; hash { algo = "sha1"; };               };                kernel { description = "Kernel"; //data = /incbin/("Image.gz"); data = /incbin/(".output/arch/arm64/boot/Image.gz"); type = "kernel"; arch = "arm64"; os = "linux"; compression = "gzip"; load = ; entry = ; hash { algo = "sha1"; };               };                fdt { description = "DTB"; data = /incbin/(".output/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dtb"); type = "flat_dt"; arch = "arm64"; compression = "none"; load = ; entry = ; hash { algo = "sha1"; };               };                initrd { description = "Initrd"; data = /incbin/(" "); type = "ramdisk"; arch = "arm64"; os = "linux"; compression = "none"; hash { algo = "sha1"; };               };        };        configurations { default = "standard"; standard { description = "Standard Boot"; kernel = "kernel"; fdt = "fdt"; ramdisk = "initrd"; hash { algo = "sha1"; };               };        }; };


 * build u-boot payload
 * make android boot image:

Running

 * flash android boot image.
 * Reboot to system, give it some time to boot
 * Read logs. See Getting logs from pstore''

Development
See also Initramfs_development

Assemble FIT image from android boot image
CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=19000000 CONFIG_POSITION_INDEPENDENT=y CONFIG_ARCH_SNAPDRAGON=y CONFIG_DEFAULT_DEVICE_TREE="starqltechn" CONFIG_TARGET_STARQLTECHN=y CONFIG_IDENT_STRING="\nSamsung S9 SM-G9600" CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_BOOTDELAY=5 CONFIG_USE_PREBOOT=y CONFIG_SAVE_PREV_BL_FDT_ADDR=y CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y CONFIG_HUSH_PARSER=y CONFIG_SYS_MAXARGS=64 CONFIG_SYS_CBSIZE=512 CONFIG_SYS_PBSIZE=532 CONFIG_CMD_GPIO=y CONFIG_CMD_BMP=y CONFIG_CLK=y CONFIG_MSM_GPIO=y CONFIG_PM8916_GPIO=y CONFIG_PINCTRL=y CONFIG_DM_PMIC=y CONFIG_PMIC_PM8916=y CONFIG_REQUIRE_SERIAL_CONSOLE=y CONFIG_MSM_GENI_SERIAL=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_MSM=y CONFIG_CMD_MMC=y CONFIG_SPMI_MSM=y CONFIG_FS_FAT=y CONFIG_DM_VIDEO=y CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_VIDEO_SIMPLE=y CONFIG_LMB_MAX_REGIONS=64 CONFIG_BAUDRATE=921600
 * Build u-boot with config:
 * 1) CONFIG_DISPLAY_CPUINFO is not set
 * 1) CONFIG_NET is not set
 * 2) CONFIG_DM_STDIO is not set
 * Disassemble android image(use android kitchen)
 * Split kernel and dtb image; disassemble dtb image into separate files
 * Find correct dtb file(check msm-id and board id properties on running android)
 * Copy kernel commandline from running android
 * Create a bootscript.sh (it searches kaslr address and adjusts kernel load address):

/dts-v1/;
 * Create a fit image source file using kernel, and ramdisk from android and boot:

/ {       description = "Samsung S9 SM-G9600 starqltechn FIT Image"; #address-cells = <1>;

images { prebootscript { description = "pre Boot script"; data = /incbin/("bootscript.sh"); type = "script"; compression = "none"; load = ; entry = ; hash { algo = "sha1"; };               };                kernel { description = "Kernel"; data = /incbin/("split_img/kernel"); type = "kernel"; arch = "arm64"; os = "linux"; compression = "gzip"; load = ; entry = ; hash { algo = "sha1"; };               };                initrd { description = "Initrd"; compression = "none"; data = /incbin/("split_img/boot.img-ramdisk.cpio.gz"); type = "ramdisk"; arch = "arm64"; os = "linux"; hash { algo = "sha1"; };               };        };

configurations { default = "standard"; standard { description = "Standard Boot"; kernel = "kernel"; ramdisk = "initrd"; hash { algo = "sha1"; };               };        };

};


 * assemble boot image:

Android quirks

 * boot image should be reassembled from android boot image (because it contains os version and patch level). Failure to provide version and patch level leads to qseecom encryption key update failure.
 * linux kernel should be loaded at stock bootloader kaslr address. qseecom trusted app reads memory map from physical address, so if kernel loaded at arbitrary address, it fails

Experimenting: procedure with usb-uart cable
This intendent for getting uart console at u-boot stage, with ability to load and boot kernel to RAM via uart. Initramfs console in possible. This way also allows you to use phone as daily driver during development, since storage is not touched

Building

 * build u-boot.bin file. Follow u-boot docs installation section
 * build mainline kernel
 * clone sources
 * assemble initramfs
 * assemble initramfs
 * assemble initramfs
 * assemble initramfs

Installing
This section is useless for now, because currently there's no way to tell if something is alive, when you boot from the flash. See next section.

Booting kernel and getting console
Is performed with kexec-similar stuff for now. See guide for that method. Remember, you should have a cable from in `UART USB-debug cable schematic` section of Samsung_Galaxy_A5_2017_(samsung-a5y17lte), and 1.8V compatible uart adapter


 * Download prebuilt twrp image, with kexec and manual muic switching support
 * Boot into twrp
 * Connect uart-usb cable
 * Switch muic uart on usb, and run u-boot.
 * go to Advanced -> Terminal
 * run  command. It will switch uart on usb, load u-boot(it's included in twrp image) in RAM, and run it.
 * You are in u-boot console now ;)
 * Load u-boot payload via kermit (you may use my high speed version for linux at 921600bps)
 * in u-boot prompt run
 * in u-boot prompt run  command