Jump to content

Samsung Galaxy S9 (samsung-starqltechn)

From postmarketOS Wiki
Revision as of 19:37, 30 October 2022 by Dsankouski (talk | contribs) (add u-boot in infobox)
Samsung Galaxy S9 (SM-G9600/
DS)
SM-G9600
SM-G9600
Manufacturer Samsung
Name Galaxy S9 (SM-G9600/
DS)
Codename samsung-starqltechn
Released 2018
Hardware
Chipset Qualcomm SDM845 Snapdragon 845
CPU Octa-core (4x 2.8 GHz Kryo 385 Gold & 4x 1.7 GHz Kryo 385 Silver)
GPU Adreno 630
Display 5.8 inch 18.5:9, 2960 x 1440 pixel 568 PPI, capacitive touchscreen, 10 multi-touch points, Super AMOLED, Corning Gorilla Glass 5, glossy: yes
Storage 64 GB
Memory 4 GB
Architecture aarch64
Software
Original software Android 8 - 10
postmarketOS
Category testing
Pre-built images no
Mainline no
Features
Flashing
Broken
USB Networking
Works
Internal storage
No data
SD card
No data
Battery
No data
Screen
Broken
Touchscreen
No data
Multimedia
3D Acceleration
No data
Audio
No data
Camera
No data
Camera Flash
No data
Connectivity
WiFi
Broken
Bluetooth
No data
GPS
No data
NFC
No data
Modem
Calls
No data
SMS
No data
Mobile data
No data
Miscellaneous
FDE
No data
USB OTG
No data
HDMI/DP
No data
Sensors
Accelerometer
No data
Magnetometer
No data
Ambient Light
No data
Proximity
No data
Hall Effect
No data
Haptics
No data
Barometer
No data
U-Boot
Primary Bootloader
Broken
Secondary Bootloader
Works
Mainline
Works
Internal Storage
No data
SD card
No data
USB Host
No data
USB Peripheral
No data
Display
No data
Buttons
Works


Contributors

  • dsankouski

Maintainer(s)

Users owning this device


How to enter flash mode

Installation

Flash boot image from TWRP

adb push $BOOT_IMAGE_PATH /tmp/boot.img && adb -d shell 'dd of=/dev/block/platform/soc/1d84000.ufshc/by-name/boot if=/tmp/boot.img'

Mainline

Mainline kernel can be booted with stock bootloader or u-boot. Logs may be viewed from pstore(ramoops) or simple framebuffer.

Status

  • Green lines - works
  • Blue - in progress
  • Red - backlog

Roadmap

  • boots
  • framebuffer
  • storage, both main and sdcard
  • touchscreen driver (dsankouski)
  • muic driver(max77705), at least detect usb cable
  • assemble firmware package in aports
  • wifi
  • bluetooth
  • display panel driver

Assembling boot image

  • clone mainline sources
  • build kernel. See also Compiling_kernels_with_envkernel.sh
  • append dtb to gzipped kernel image
    • pushd .output/arch/arm64/boot
    • cat Image.gz dts/qcom/sdm845-samsung-starqltechn.dtb > Image.gz-dtb
  • generate initramfs image
  • make android bootimage mkbootimg --base 0x0 --kernel_offset 0x00008000 --ramdisk_offset 0x02000000 --tags_offset 0x01e00000 --pagesize 4096 --second_offset 0x00f00000 --ramdisk "$INITRAMFS" --kernel Image.gz-dtb -o boot.img

Boot

Flash boot image from twrp to boot partition. Reboot to system. Phone will stay on manufacturer logo. Check logs in pstore. If there's only twrp logs in pstore, try to reboot phone with power+volume down one more time.

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 export CROSS_COMPILE=aarch64-linux-gnu- && make starqltechn_defconfig && make
  • build make
  • create payload for SBOOT by gzipping and appending dtb:
gzip -k u-boot.bin
cat u-boot.bin.gz u-boot.dtb > u-boot.gz-dtb

Build kernel

Generate android boot image

  • create bootscript.sh file: bootm $prevbl_initrd_start_addr
  • build ramdisk
  • create boot.its file, describing u-boot's payload:
/dts-v1/;

/ {
        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 = <0x90000000>;
                        entry = <0x90000000>;
                        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 = <0x80000000>;
                        entry = <0x80000000>;
                        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 = <0x82a80000>;
                        entry = <0x82a80000>;
                        hash {
                                algo = "sha1";
                        };
                };
                initrd {
                        description = "Initrd";
                        data = /incbin/("<ramdisk path>");
                        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
    mkimage -f boot.its boot.itb
    
  • make android boot image:
mkbootimg --base 0x0 --kernel_offset 0x00008000 --ramdisk_offset 0x02000000 --tags_offset 0x01e00000 --pagesize 4096 --second_offset 0x00f00000 \
--ramdisk boot.itb \
--kernel u-boot.gz-dtb -o boot.img

Running

Development

See also Initramfs_development

Booting android with u-boot

Assemble FIT image from android boot image

  • Build u-boot with config:
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_DISPLAY_CPUINFO is not set
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_NET is not set
# CONFIG_DM_STDIO is not set
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
  • 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):
echo "##############################################"
echo "##############################################"
echo "searching for sboot load address..."

addr=0x80000038
addr2=0x80000050

setenv arm64 0x644d5241
until itest *$addr == 0x644d5241 && itest *$addr2 == 0x6d3a8; do
    setexpr addr $addr + 0x1000
    setexpr addr2 $addr2 + 0x1000
done
setexpr addr $addr - 0x38
echo "sboot loaded payload at 0x$addr"
setenv bootm_low "0x$addr"
setenv bootm_size 0x5000000

fdt addr $prevbl_initrd_start_addr
fdt set "/images/kernel" "load" "<0x$addr>"
fdt set "/images/kernel" "entry" "<0x$addr>"
fdt addr $prevbl_fdt_addr
fdt print "/chosen"
bootm $image_address#standard $image_address#standard $prevbl_fdt_addr
  • Create a fit image source file using kernel, and ramdisk from android and boot:
/dts-v1/;

/ {
        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 = <0x83000000>;
                        entry = <0x83000000>;
                        hash {
                                algo = "sha1";
                        };
                };
                kernel {
                        description = "Kernel";
                        data = /incbin/("split_img/kernel");
                        type = "kernel";
                        arch = "arm64";
                        os = "linux";
                        compression = "gzip";
                        load = <0x80200000>;
                        entry = <0x80200000>;
                        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:
gzip -c u-boot.bin > u-boot.bin.gz
mkimage -f boot_image.dts boot.itb
cat u-boot.bin.gz split_img/dtbdump_15.dtb > u-boot.gz-dtb

mkbootimg --base 0x0 --kernel_offset 0x00008000 --ramdisk_offset 0x02000000 --tags_offset 0x01e00000 --pagesize 4096 --second_offset 0x00f00000 \
--kernel u-boot.gz-dtb \
--ramdisk boot.itb \
-o boot.img

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
    • source /home/dzmitry/side/pmos/pmbootstrap/helpers/envkernel.sh
    • make defconfig
    • make
  • assemble initramfs
  • TODO TODO: assemble u-boot fit image:

    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)#Notes, 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 /exec.sh 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 loadb 0x90000000
    • in u-boot prompt run bootm 0x90000000 command
    TODO TODO: how to setup initramfs console

    Notes

    Uart

    `/dev/ttyHS8` can be exposed on USB D+D- lines. It's configured in data mover mode by downstream kernel.

    Getting logs from pstore

    Boot to twrp, and check /sys/fs/pstore folder

    Stock bootloader

    Loads payload into ram at random physical address for security reason. Initramfs physical load address is 0xa2000000 both for boot image and recovery image

    See also

    aport MR

    u-boot

    u-boot sdm845 devices docs

    aport fork for SM-G9600

    mainline kernel fork for SM-G9600