Skip to content
View in the app

A better way to browse. Learn more.

Armbian Community Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

How to install armbian in h618?

Featured Replies

@Nick AIs it possible to configure the front display using the Linux header you provided and the pin details I shared above? I know this is a big request, but if it's possible, it would make this setup complete. Since I am not a programmer, I tried using Google's AI, but it just took me in circles and landed me nowhere. If you require any additional log or configuration details please let me know. 

@sr4armbian You could try building your own X98H image and use the kernel headers from your build. Your kernel headers will be in the build/output/debs directory, and the image will be in the build/output/images directory. I would recommend starting with a fresh install with this new image and kernel headers.

 

git clone https://github.com/NickAlilovic/build.git --branch v20250306

cd build

./compile.sh

choose "Do not change kernel configuration"

choose "Show CSC/WIP/EOS/TVB"

choose "I understand and agree"

choose "X98H"

choose "edge"
rest is up to you...

 

I used this method to get my display working. But that was a while ago.

 

 

Edited by Nick A

trying to build armbian image using v20250306 for vontar-h618 but getting error:

 

Could not find package filename for 'base-files' in distro repo [ looking for base-files, found_package_filename is  ]
[🚸] Command failed, retrying in 15s [ apt_find_upstream_package_version_and_download_url base-files ]
[🚸] Command failed 10 times, giving up [ apt_find_upstream_package_version_and_download_url base-files ]
[💥] Cleaning up [ please wait for cleanups to finish ]

 

 

Edited by firepower

will do, 

I also trying official armbian build for tanix-tx6s-axp313 which boots but freezes after few minutes, where as your older build is stable.

any chance of your builds making it into mainline armbian ?

looking forward to a newer build. I see now Radxa Cubie A7A/A7Z is the new favourite.

I been having a break from armbian but want to get back into it again.

 

Edited by firepower

@Kajen Did you get HDMI working? I have a box very similar to yours (Transpeed 6K T98 H616) and i have been trying to get HDMI for a couple days without success. For me the only ARM Linux image that boots is a MiniArch image for pendoo x12 pro that has 7.1.1 kernel. The kernel detects the HDMI TX controller v2.12a after which it reports: sun4i-drm display-engine: [drm] Cannot find any crtc or sizes. I also tried to build custom Armbian image with custom CSC and patch files but i didn't get any of the images to boot the kernel.

My specs:

- AXP305 PMIC
- 2 GB DDR3 Micron D9LGX
- 32 GB eMMC KMR21000BM-B809 

- AW859A Wireless module

Pic of PCB:

https://imgur.com/a/higrm6v

just today I got hdmi signal, I turn on pin PI8, 

 

leds {
		compatible = "gpio-leds";
		status_led {
			label = "blue:pwr";
			gpios = <&pio 7 6 GPIO_ACTIVE_LOW>; /*PH6*/
			linux,default-trigger = "default-on";
		};
		hdmi_pwr_led {
			label = "hdmi-pwr-en";
			gpios = <&pio 8 8 GPIO_ACTIVE_HIGH>; /* Bank I (8), index 8 = PI8 */
			default-state = "on";
		};
	};
	

 

here is my dts, I still need to tune for my board, to get audio, right now I am using https://github.com/jernejsk/linux-1/commits/h616-integration-v1 for my kernel 

Spoiler


/dts-v1/;

#include "sun50i-h616.dtsi"
#include "sun50i-h616-cpu-opp.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/leds/common.h>

/ {
    model = "Transpeed T98 616";
    compatible = "transpeed,t98-616", "allwinner,sun50i-h616";

    aliases {
        mmc0 = &mmc0;
        mmc2 = &mmc2;
        ethernet0 = &emac1;
        ethernet1 = &wlan;
        serial0 = &uart0;
    };

    chosen {
        stdout-path = "serial0:115200n8";
    };
    
    leds {
        compatible = "gpio-leds";
        status_led {
            label = "blue:pwr";
            gpios = <&pio 7 6 GPIO_ACTIVE_LOW>; /*PH6*/
            linux,default-trigger = "default-on";
        };
        hdmi_pwr_led {
            label = "hdmi-pwr-en";
            gpios = <&pio 8 8 GPIO_ACTIVE_HIGH>; /* Bank I (8), index 8 = PI8 */
            default-state = "on";
        };
    };
    
    connector {
        compatible = "hdmi-connector";
        type = "a";

        port {
            hdmi_con_in: endpoint {
                remote-endpoint = <&hdmi_out_con>;
            };
        };
    };

    // Add bit-banged I2C for the FD650 Front Panel Display
    fd650 {
        compatible = "i2c-gpio";
        sda-gpios = <&pio 8 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; /* PI12 (268) */
        scl-gpios = <&pio 8 11 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; /* PI11 (267) */
        i2c-gpio,delay-us = <2>; /* ~100 kHz */
        #address-cells = <1>;
        #size-cells = <0>;

        /* You can map your open-source fd650 / openvfd driver node here if compiled into kernel */
    };
    
    reg_vcc5v: vcc5v {
        /* board wide 5V supply directly from the USB-C socket */
        compatible = "regulator-fixed";
        regulator-name = "vcc-5v";
        regulator-min-microvolt = <5000000>;
        regulator-max-microvolt = <5000000>;
        regulator-always-on;
        regulator-boot-on;
    };

    reg_usb1_vbus: usb1-vbus {
        compatible = "regulator-fixed";
        regulator-name = "usb1-vbus";
        regulator-min-microvolt = <5000000>;
        regulator-max-microvolt = <5000000>;
        vin-supply = <&reg_vcc5v>;
        enable-active-high;
        /* gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; PC16 */
        status = "okay";
    };


    reg_vcc3v3: vcc3v3 {
        /* discrete 3.3V regulator */
        compatible = "regulator-fixed";
        regulator-name = "vcc-3v3";
        regulator-min-microvolt = <3300000>;
        regulator-max-microvolt = <3300000>;
        regulator-always-on;
    };
    
    wifi_pwrseq: wifi_pwrseq {
        compatible = "mmc-pwrseq-simple";
        clocks = <&rtc 1>;
        clock-names = "ext_clock";
        reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
        post-power-on-delay-ms = <200>;
    };
};

&cpu0 {
    cpu-supply = <&reg_dcdca>;
    status = "okay";
};

&gpu {
    mali-supply = <&reg_dcdcc>;
    status = "okay";
};

&de {status = "okay";};

&hdmi_out {
    hdmi_out_con: endpoint {
        remote-endpoint = <&hdmi_con_in>;
    };
};

&hdmi {
    #sound-dai-cells = <0>;
    hvcc-supply = <&bldo1>;
    phy-supply = <&cldo1>;
    status = "okay";
};
&hdmi_phy {
    phy-supply = <&aldo1>;
    hvcc-supply = <&bldo1>;
    status = "okay";
};
&ohci1 {status = "okay";};
&ehci1 {status = "okay";};
&ohci2 {status = "okay";};
&ehci2 {status = "okay";};

&emac1 {
    pinctrl-names = "default";
    pinctrl-0 = <&rmii_pins>;
    phy-mode = "rmii";
    phy-handle = <&rmii_phy>;
    phy-supply = <&aldo1>;
    allwinner,rx-delay-ps = <3100>;
    allwinner,tx-delay-ps = <700>;
    status = "okay";
};

&mdio1 {
    rmii_phy: ethernet-phy@1 {
        compatible = "ethernet-phy-ieee802.3-c22";
        reg = <1>;
    };
};

&mmc0 {
    vmmc-supply = <&reg_dcdce>;
    cd-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>;    /* PI16 */
    disable-wp;
    bus-width = <4>;
    status = "okay";
};

&mmc1 {
    vmmc-supply = <&reg_dcdce>; /* 3.3v */
    vqmmc-supply = <&bldo1>; /* 1.8v */
    mmc-pwrseq = <&wifi_pwrseq>;
    bus-width = <4>;
    non-removable;
    status = "okay";

    wlan: wifi@1 {
        reg = <1>;
    };
};

&mmc2 { 
    vmmc-supply = <&reg_dcdce>;
    vqmmc-supply = <&bldo1>;
    bus-width = <8>;
    non-removable;
    cap-mmc-hw-reset;
    mmc-hs200-1_8v;
    status = "okay";
};

&uart0 {
    pinctrl-names = "default";
    pinctrl-0 = <&uart0_ph_pins>;
    status = "okay";
};

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
    uart-has-rtscts;
    status = "okay";
};

&ir {
    linux,rc-map-name = "rc-beelink-gs1";
    status = "okay";
};

&r_i2c {
    status = "okay";
    clock-frequency = <100000>;

    axp305: pmic@36 {
        compatible = "x-powers,axp305", "x-powers,axp805",
        "x-powers,axp806";
        reg = <0x36>;
        wakeup-source;
        interrupt-controller;
        #interrupt-cells = <1>;

        x-powers,self-working-mode;
        vina-supply = <&reg_vcc5v>;
        vinb-supply = <&reg_vcc5v>;
        vinc-supply = <&reg_vcc5v>;
        vind-supply = <&reg_vcc5v>;
        vine-supply = <&reg_vcc5v>;
        aldoin-supply = <&reg_vcc5v>;
        bldoin-supply = <&reg_vcc5v>;
        cldoin-supply = <&reg_vcc5v>;

        regulators {
            aldo1: aldo1 {
                regulator-always-on;
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-name = "vcc-sys";
            };

            reg_aldo2: aldo2 { /* Enabled by the Android BSP */
                regulator-always-on;
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-name = "vcc3v3-ext";
                status = "okay";
            };

            reg_aldo3: aldo3 { /* Enabled by the Android BSP */
                regulator-always-on;
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-name = "vcc3v3-ext2";
                status = "okay";
            };

            bldo1: bldo1 {
                regulator-always-on;
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
                regulator-name = "vcc1v8";
                status = "okay";
                startup-delay-us = <50000>;
            };

            cldo1: cldo1 {
                regulator-min-microvolt = <2500000>;
                regulator-max-microvolt = <2500000>;
                regulator-name = "vcc2v5";
                regulator-always-on;
                regulator-boot-on;
            };

            reg_dcdca: dcdca {
                regulator-always-on;
                regulator-min-microvolt = <810000>;
                regulator-max-microvolt = <1100000>;
                regulator-name = "vdd-cpu";
            };

            reg_dcdcc: dcdcc {
                regulator-always-on;
                regulator-min-microvolt = <810000>;
                regulator-max-microvolt = <990000>;
                regulator-name = "vdd-gpu-sys";
            };

            reg_dcdcd: dcdcd {
                regulator-always-on;
                regulator-min-microvolt = <1360000>;
                regulator-max-microvolt = <1360000>;
                regulator-name = "vdd-dram";
            };

            reg_dcdce: dcdce {
                regulator-always-on;
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-name = "vcc-eth-mmc";
            };
        };
    };
};

&usbotg {
    dr_mode = "peripheral";
    status = "okay";
};

&usbphy {
    usb1_vbus-supply = <&reg_usb1_vbus>;
    status = "okay";
};

&codec {
    allwinner,audio-routing = "Line Out", "LINEOUT";
    status = "okay";
};

&pio {
    vcc-pa-supply = <&reg_dcdce>;
    phy-io-supply = <&reg_dcdce>;
    vcc-pc-supply = <&aldo1>;
    vcc-pf-supply = <&aldo1>;
    vcc-pg-supply = <&bldo1>;
    vcc-ph-supply = <&aldo1>;
    vcc-pi-supply = <&aldo1>;
    vcc-pl-supply = <&reg_aldo2>;
};


 

@Kuostiyou can also manually turn on its pin with a script that run after boot

 


echo "264" > "/sys/class/gpio/export"
echo "out" > "/sys/class/gpio/gpio264/direction"
echo 1 > "/sys/class/gpio/gpio264/value"

 

I still need to test it to see if it work on other images, in that case maybe you dont need to compile it, as long it boot, like pendoo x12 pro

Ok, i built an Armbian v25.05 image with kernel 6.12.11-edge-sunxi64. I used the 158-add-pendoo-x12pro-defconfig.patch for uboot and @Kajen DTS above for kernel patch. HDMI still doesn't work, but the system is stable, ethernet works and the blue power led works too.

According to H616 datasheet PI0 is SCL, PI1 SDA, and PI2 is CEC for HDMI so i added them to pinctrl node in dtb to claim them

hdmi-pins {
	pins = "PI0\0PI1\0PI2";
	function = "hdmi";
	phandle = <0x90>;
};

And then these to hdmi@6000000

pinctrl-names = "default";
pinctrl-0 = <0x90>;

But i still get "Cannot find any crtc or sizes", and when i force the HDMI on with extraargs=video=HDMI-A-1:1920x1080@60e in /boot/armbianEnv.txt i get "PHY PLL failed to lock". Maybe this board needs some specific kernel fixes? Im a total n00b at tv boxes and Linux kernel so my knowledge is extremely limited...

Also, in /sys/kernel/debug/clk/clk_summary the HDMI clock is apparently 172615385Hz which is too high for 1920x1080@60. It is supposed to be 148500000Hz. I think that would explain why PHY PLL fails to lock but i don't know how to fix this.

you can try this script 

Spoiler

#!/bin/bash

# Script to iterate through unclaimed GPIOs, set them as output,

# toggle them high/low, and test i2cdetect -y 1 for HDMI DDC recovery.

 

SYS_GPIO="/sys/class/gpio"

DELAY=0.2

 

echo "=== Starting GPIO Pin Search and DDC Check ==="

 

# Get lines from gpiochip1 that do NOT have a consumer listed

UNCLAIMED_PINS=$(gpioinfo -c gpiochip1 | grep -E "line +[0-9]+:" | grep -v "consumer=" | awk '{print $2}' | tr -d ':')

 

for pin in $UNCLAIMED_PINS; do

echo "--------------------------------------------------"

echo "[*] Testing GPIO Pin: $pin"

 

# Export GPIO if not already exported

if [ ! -d "$SYS_GPIO/gpio$pin" ]; then

if ! echo "$pin" > "$SYS_GPIO/export" 2>/dev/null; then

echo " └─ [!] Export failed (Resource busy or kernel restricted). Skipping."

continue

fi

fi

 

# Set direction to output

if ! echo "out" > "$SYS_GPIO/gpio$pin/direction" 2>/dev/null; then

echo " └─ [!] Failed to set direction to output. Unexporting and skipping."

echo "$pin" > "$SYS_GPIO/unexport" 2>/dev/null

continue

fi

 

# Toggle HIGH -> LOW -> HIGH

echo 1 > "$SYS_GPIO/gpio$pin/value" 2>/dev/null

sleep $DELAY

echo 0 > "$SYS_GPIO/gpio$pin/value" 2>/dev/null

sleep $DELAY

echo 1 > "$SYS_GPIO/gpio$pin/value" 2>/dev/null

 

# Check i2cdetect output on i2c-1 (HDMI DDC)

# Count how many ACKs (hex addresses) are detected

I2C_COUNT=$(i2cdetect -y 1 | grep -oE " [0-9a-f]{2} " | wc -l)

 

echo " └─ Active addresses on i2c-1: $I2C_COUNT"

 

if [ "$I2C_COUNT" -eq 1 ]; then

echo "=================================================="

echo " SUCCESS! DDC Bus Recovered on GPIO Pin: $pin"

echo "=================================================="

i2cdetect -y 1

# Clean up pin export before exit

echo "$pin" > "$SYS_GPIO/unexport" 2>/dev/null

exit 0

elif [ "$I2C_COUNT" -lt 10 ]; then

echo " └─ [*] Partial bus change detected on GPIO $pin ($I2C_COUNT devices active)."

fi

 

# Unexport to leave sysfs clean

echo "$pin" > "$SYS_GPIO/unexport" 2>/dev/null

done

 

echo "--------------------------------------------------"

echo "Scan complete. No single unclaimed pin cleared the bus ghosting."

 this is from gemini, this helped me find the right pin, check i2cdetect -l for right chip and change line 45, with your count on i2cdetect -y x + 1, you board design is a little different from mine, maybe they use other pin  

Hi @Kajen

I noticed the Jernej h616-integration-v1 branch and had some time today to test it. I’ve been busy with work and other projects lately.

Here’s the Armbian build. It boots, but there are some errors. I’ll have to reconnect the UART pins to see where things went wrong.

 

The build includes Jernej’s patches and the board configuration.  I'm also using Werner's 7.2 Armbian build but with a different patch directory. (jernejsk-7.2)

https://github.com/EvilOlaf/build/tree/sunxi-7.2

 

I haven’t made any modifications to the mainline DTS.

 

I’m not sure when I’ll have more time to work on it, but hopefully I can investigate the issues further when I get a chance.

https://github.com/NickAlilovic/build/tree/sunxi-7.2

Edited by Nick A

Please share your AI skills to translate vendor android DTS into armbian compatible DTS.

The work seems menial and lacks any sort of documentation.

An automated workflow would do wonders, if created by someone who understands it fully.

Hello,

I guess this is the right forum for my topic: I have got a T95zplus H618 TVBox with AW869A. People having this box may know, there exist an armbian image by LYU4662 at github:  https://github.com/LYU4662/t95zplus-h618-build

 

However, after installing it, there is no wifi. I did some analysis with claude, it concluded that there are only some small changes necessary in the dtb  and the wifi is working. These are claude's words: 

"

T95ZPLUS (AW869A / AIC8800) with LYU’s image: fix for mmc1: error -110 whilst initialising SDIO card

Box: T95ZPLUS, H618, AW869A (SDIO 5449:0145, detected as AIC8801). Image: LYU4662’s Armbian build, 6.7.12-edge-sunxi64, with his aic8800 DKMS driver.

Symptom: aic modules load, but modprobe aic8800_fdrv gives “No such device”, /sys/bus/sdio/devices/ is empty, dmesg shows the CIS tuple being read and then mmc1: error -110 whilst initialising SDIO card / Failed to initialize a non-removable card.

I compared LYU’s DTB with the live Android DT. Pins, supplies and power sequence already match (SMHC1 on PG0–PG5, vmmc = DLDO1 3.3 V, vqmmc = ALDO1 1.8 V, 32 kHz clock out on PG10 via &rtc 1, reset PG18 active low). So it’s not a pinning problem.

What fixed it, in the mmc@4021000 node:

max-frequency: 50 MHz -> 25 MHz
removed: cap-sd-highspeed, cap-mmc-highspeed, mmc-ddr-3_3v, mmc-ddr-1_8v
wifi_pwrseq: added post-power-on-delay-ms = <200>

After that both SDIO functions enumerate, firmware loads, wlan0 shows up, nmcli connects, and it comes back after a reboot without the Ethernet cable.

I changed these together and didn’t test them individually, so I don’t know which one is essential. Only tested on this image/kernel and one box; Bluetooth untested. Newer revisions with other chips (e.g. YC8800D) are a different case.

If you use LYU’s image, replacing /boot/dtb/allwinner/T95zPlus-H618.dtb wt95zplus-aw869a-wifi-fix.zipith the patched one and rebooting should be all that’s needed. Happy to share the DTB/DTS if anyone wants it."

 

I tested it at my t95zplus, wifi is working. I attach the dtb and dts claude found out. Simply replace the DTB in /boot/dtb/allwiner/T95zPlus-H618.dtb by the dtb of the zip file.  Here is an instruction according to Claude: 

 

I tested it at my t95zplus, wifi is working. I attach the dtb and dts claude found out. Simply replace the DTB in /boot/dtb/allwiner/T95zPlus-H618.dtb by the dtb of the zip file:

Flash the image at an SD card

unzip the attached file in ~/Downloads

find your SD card sdX1 with lsblk (typically sdX1 is sda1 or sdb1)

then:

sudo mkdir -p /mnt/sd

sudo mount /dev/sdX1 /mnt/sd

ls /mnt/sd/boot/dtb/allwinner/ | grep T95


 

sudo cp /mnt/sd/boot/dtb/allwinner/T95zPlus-H618.dtb /mnt/sd/boot/dtb/allwinner/T95zPlus-H618.dtb.stock

sudo cp ~/Downloads/T95zPlus-H618.dtb /mnt/sd/boot/dtb/allwinner/T95zPlus-H618.dtb


 

sha256sum ~/Downloads//T95zPlus-H618.dtb /mnt/sd/boot/dtb/allwinner/T95zPlus-H618.dtb

sync

sudo umount /mnt/sd


 

Start your t95zplus and do the armbian installation.

Then you can initilize wifi on the box:


 

# 1. Hold kernel packages

sudo apt-mark hold linux-dtb-edge-sunxi64 linux-image-edge-sunxi64 linux-u-boot-t95zplus-h618-edge

apt-mark showhold


 

# 2. Optional: back up /boot

sudo cp -a /boot ~/boot-backup-$(date +%F)


 

# 3. Check WiFi state (rfkill needs sudo)

sudo rfkill list

sudo rfkill unblock wifi


 

# 4. Enable WiFi and scan

sudo nmcli radio wifi on

sudo nmcli device wifi rescan

sleep 5

nmcli device wifi list


 

# 5. Connect WiFi

sudo nmcli device wifi connect 'YOUR_WIFI_NAME' password 'YOUR_PASSWORD'


 

# 6. Verify

ip -br addr

ping -c3 -I wlan0 1.1.1.1


 

# 7. Test auto-connect (unplug the LAN cable first)

nmcli connection show

sudo reboot

 

I had some time to experiment with kernels on my Transpeed TV box which have flapping LAN link. Some results:

1) Armbian have troubles to build on Debian x86-64 host - qemu-user wrapper doesn't called for arm elfs due to missing binfmt symlink (I'll add patch later)
2) for kernel update it'll be enough to just install all packages via dpkg -i, and then call apt upgrade to install dependencies (but maybe it'll be preferrable to install .deb packages via apt)

3) kernel from 7.2 branch boots (build requires to delete some patches already applied to upstream), but no ethernet nor wifi devices is present in system

4) on 6.17.2 kernel I've got same flapping LAN link - maybe something wrong with router's port setup, I'll re-check with separate switch; or probably something wrong with on-board capacitors in tv box.

Here's building environment patch for Armbian assembly in Debian 12/13

diff --git a/lib/functions/rootfs/qemu-static.sh b/lib/functions/rootfs/qemu-static.sh

index d4b8f789e..082fcf1be 100644

--- a/lib/functions/rootfs/qemu-static.sh

+++ b/lib/functions/rootfs/qemu-static.sh

@@ -31,6 +31,12 @@ function deploy_qemu_binary_to_chroot() {

display_alert "Deploying qemu-user-static binary to chroot" "${QEMU_BINARY} during ${caller}" "info"

run_host_command_logged cp -pv "${src_host}" "${dst_target}"

+ qarch="$(echo $QEMU_BINARY | sed 's,qemu-,,;s,-.*,,')"

+ binfmt_target="${chroot_target}/usr/libexec/qemu-binfmt/${qarch}-binfmt-P"

+ if [[ ! -f "${binfmt_target}" ]]; then

+ run_host_command_logged mkdir -p "${chroot_target}/usr/libexec/qemu-binfmt"

+ run_host_command_logged ln -sf "/usr/bin/${QEMU_BINARY}" "${binfmt_target}"

+ fi

return 0

}

@@ -56,6 +62,10 @@ function undeploy_qemu_binary_from_chroot() {

# Remove the binary we deployed, and restore the original if we had to preserve it.

display_alert "Removing qemu-user-static binary from chroot" "${QEMU_BINARY} during ${caller}" "info"

run_host_command_logged rm -fv "${dst_target}"

+ binfmt_target="${chroot_target}/usr/libexec/qemu-binfmt"

+ if [[ -d "${binfmt_target}" ]] && [[ ! -f "${dst_target_bkp}" ]]; then

+ run_host_command_logged rm -rf "${binfmt_target}"

+ fi

if [[ -f "${dst_target_bkp}" ]]; then

display_alert "Restoring original qemu binary" "${QEMU_BINARY} during ${caller}" "info"

Edited by NiTr0

@NiTr0 you can use my fork https://github.com/bk3a12/build/tree/sunxi-7.2 then build for transpeed 8k box. It has included patches for LAN and Wifi from jernejsk for kernel 7.2.

GitHub

build/patch/kernel/archive/jernejsk-7.2/0724-arm64-dts-al...

Armbian Linux build framework generates custom Debian or Ubuntu image for x86, aarch64, riscv64 & armhf - bk3a12/build

Edited by dale

Same board here (SuperBox S6 Pro = Transpeed 8K618-T, RTL8211F). I got the gigabit port working under Android (SlimBOX), write-up below. A few board findings may help Armbian device trees for this box too: the PI pin drive strength was level 0, working delays are tx 5 / rx 6 (with the RTL8211F's own TX delay off), and fd628 holds PI11/PI12. I may not check back often, so everything is in this post.


[FIX] Gigabit Ethernet port working on SuperBox S6 Pro / H618 (Transpeed 8K618-T board, RTL8211F) with SlimBOX Android 12

Short version (for everyone)

The problem: on the SuperBox S6 Pro (and other H618 boxes sold as "1000M Ethernet"), the network port looks alive (the light comes on and your router shows a gigabit link) but no data ever goes through. This happens on every firmware I could find.

Why: the box has a real gigabit network chip (Realtek RTL8211F), but every firmware is copied from a cheaper 100M board and talks to the wrong chip. The driver also has three bugs that crash the box if you just switch the right chip on.

The result: with the fix below, the built-in port runs at about 790 Mbit/s with zero errors, survives reboots, and gets its address from the router normally. You don't need a serial adapter or a new firmware.

Who can do this: you need a rooted box (Magisk), adb over the network or USB, and a PC with Python. If "adb" and "dd" are new to you, ask someone who has done it before. It's easy to undo, though: the box can always be reflashed with PhoenixSuit, because burn mode is built into the chip and can't be erased.

Important: the kernel part of the fix only fits one firmware build: SlimBOX sbx_transpeed_h618_atv_12_16 (kernel 5.4.125, file sbx_transpeed_h618_aosp_12_16.zip). The script checks this and refuses to change anything on a different build. Nothing gets written in that case.


Step by step

What you need: the box with SlimBOX atv_12_16 flashed and rooted with Magisk, adb working (adb connect <box-ip>:5555 or USB), and a PC with python3 and device-tree-compiler (Linux: sudo apt install device-tree-compiler).

1. Back up the two partitions (keep these files safe, they're your undo):

adb shell "su -c 'cat /dev/block/by-name/boot_a'"        > boot_a.img
adb shell "su -c 'cat /dev/block/by-name/vendor_boot_a'" > vendor_boot_a.img
cp boot_a.img boot_a.ORIGINAL.img; cp vendor_boot_a.img vendor_boot_a.ORIGINAL.img

(If your box runs from slot _b, check with adb shell getprop ro.boot.slot_suffix and use _b.)

2. Run the script (below) on your PC:

python3 h618_gigabit_fix.py boot_a.img vendor_boot_a.img

It prints each change and writes boot_a.patched.img and vendor_boot_a.patched.img. If it says STOP, your firmware is a different build. Don't continue.

3. Write them back and reboot:

adb push boot_a.patched.img vendor_boot_a.patched.img /data/local/tmp/
adb shell "su -c 'dd if=/data/local/tmp/boot_a.patched.img of=/dev/block/by-name/boot_a bs=1M; dd if=/data/local/tmp/vendor_boot_a.patched.img of=/dev/block/by-name/vendor_boot_a bs=1M; sync; reboot'"

4. Check it: plug a cable into the box's port. Settings → Network should show Ethernet connected. Or run adb shell ip addr show eth0.

To undo: write the .ORIGINAL.img files back the same way. Or reflash SlimBOX with PhoenixSuit.

Magisk note: if you later re-patch boot with Magisk, run the script on the new boot image again. It skips patches that are already in place.

Optional: port on a network with no internet (for example a cable straight to a PC). Android only sends replies over its "default" network, and a network with no internet never becomes the default. The box then gets an address but answers nothing (ping/adb time out). This script copies the route into the main table every 5 seconds, so it also survives cable replugs. Change NET to your network. You don't need this if the box is plugged into a normal router with internet.

#!/system/bin/sh
# Magisk: put in /data/adb/service.d/eth-local.sh, chmod 755
NET=192.168.50          # first three numbers of your network
( while true; do
  a=$(ip -4 -o addr show eth0 2>/dev/null | grep -o "$NET\.[0-9]*" | head -1)
  if [ -n "$a" ]; then
    ip route replace $NET.0/24 dev eth0 src $a table main 2>/dev/null
    ip rule list | grep -q "from $a lookup main" || ip rule add from $a lookup main pref 97
    ip rule list | grep -q "to $NET.0/24 lookup main" || ip rule add to $NET.0/24 lookup main pref 98
  fi; sleep 5; done ) &

What the fix changes (for the tinkerers)

Six problems, found one by one. A box that hard-freezes with no log line was handled with the trick at the end of this section.

  1. Wrong port enabled. The device tree has eth@5020000 (gmac0, RGMII to the RTL8211F) disabled and eth@5030000 (gmac1, internal AC300 100M PHY) enabled. Swapped.

  2. Wrong pin function name. function = "gmac0" gives unsupported function gmac0 on pin PI0 / gmac pinctrl error! (-22). This kernel calls it emac0.

  3. Front display driver steals RGMII pins. fd628_dev claims PI11/PI12 (pin PI11 already requested ... cannot claim for 5020000.eth). Those are TXCK/TXCTL on this board. Set fd628_dev to status = "fail" (the front LED display goes dark).

  4. Kernel panic in the MAC code. geth_probe() → get_addr_by_name() sprintfs the address from addr_mgt into mac_str, which points at the string literal "00:00:00:00:00:00" in read-only kernel data. Result: Unable to handle kernel write to read-only memory, every time. Fix: NOP the call, and put mac_addr=02:.. on the vendor_boot boot line (__setup("mac_addr=") copies it in before rodata becomes read-only).

  5. PHY scan only accepts the AC300 and crashes on empty addresses. geth_phy_init() calls get_phy_device() on MDIO 0–31 with no IS_ERR check (→ virtual address 00000000000003fd) and only accepts phy_id 0x00441400. Fix: skip get_phy_device (libphy has already registered the RTL8211F at address 0) and accept the first real PHY.

  6. Link up, zero frames. The PI pin drive strength was level 0 (PI_DRV0 = 0; drive-strength = <10> maps to level 0 in this kernel). TX worked at once with level 3 (<40>). The RX delay of 31 was also outside the window. Live sweep: with RTL8211F TX delay off (the driver default), EMAC tx-delay 3–7 and rx-delay 0–12 work. Chosen: tx 5, rx 6.

Kernel patches (VA, _text = 0xffffffc010080000, file offset = VA − _text + 4096 in boot.img):

VA

original

patched

0xffffffc010786a94

bl get_addr_by_name 94d2fe97

nop 1f2003d5

0xffffffc010788f70

bl get_phy_device cbc4ff97

mov x0,xzr e0031faa

0xffffffc010788f30

b.eq a0030054

b 1d000014

The no-serial-adapter debugging trick: this kernel has CONFIG_PSTORE_RAM=y, but the device tree has no ramoops region. Add one to reserved-memory (ramoops@13ab00000, 1 MB) and start the hardware watchdog before each test (busybox watchdog -t 2 -T 16 /dev/watchdog). Every hard freeze then warm-resets after 16 s, and the full panic is waiting in /sys/fs/pstore/console-ramoops-0. Also useful: /sys/class/sunxi_dump (read/write physical registers as root) and the driver's mii_read / mii_write sysfs files (raw PHY registers). Together those let you sweep RGMII delays live with no reboots. The script leaves the ramoops region in (use --no-ramoops to skip it).

Hardware: H618, 4 GB, RTL8211F (25 MHz crystal) + TFS5009 magnetics, Wi-Fi module Cdtech 20AI880-20 (AIC8800, not working yet: aic8800_bsp loads, no wlan0). UART header B/VCC/R/GND at 1500000 baud (not needed).

Not fixed: Wi-Fi. Also, a proper fix would be a rebuilt sunxi-gmac.c (IS_ERR check, no AC300-only ID check, writable mac_str). These binary patches only fit this build. On another build, find get_addr_by_name, geth_probe and geth_phy_init in /proc/kallsyms, disassemble, and look for the same three spots.


The script (h618_gigabit_fix.py)

#!/usr/bin/env python3
"""
h618_gigabit_fix.py - enable the RTL8211F gigabit Ethernet port on H618 TV boxes
(SuperBox S6 Pro / Transpeed 8K618-T board) running SlimBOX Android 12
build "sbx_transpeed_h618_atv_12_16" (from sbx_transpeed_h618_aosp_12_16.zip) (kernel 5.4.125).

It patches two partition images that you pulled off the box:
  boot_a.img        -> 3 four-byte kernel patches (only if the exact original bytes are found)
  vendor_boot_a.img -> device tree + boot line changes

It REFUSES to patch anything that does not match the known build.
Needs: python3, and dtc/fdtget/fdtput (package "device-tree-compiler").

Usage:
  python3 h618_gigabit_fix.py boot_a.img vendor_boot_a.img [--mac 02:xx:xx:xx:xx:xx] [--no-ramoops]
Writes boot_a.patched.img and vendor_boot_a.patched.img next to the originals.
"""
import argparse, hashlib, os, random, struct, subprocess, sys, tempfile

TEXT = 0xffffffc010080000   # kernel _text for this build
KOFF = 4096                 # kernel Image offset inside boot v3 image
KPATCH = [  # (virtual address, original bytes, new bytes, what)
    (0xffffffc010786a94, "94d2fe97", "1f2003d5", "nop: skip get_addr_by_name (writes into read-only memory)"),
    (0xffffffc010788f70, "cbc4ff97", "e0031faa", "mov x0,xzr: skip get_phy_device (unchecked error pointer)"),
    (0xffffffc010788f30, "a0030054", "1d000014", "b: accept the RTL8211F, not only the AC300 100M PHY"),
]
ETH = "/soc@3000000/eth@5020000"
ETH1 = "/soc@3000000/eth@5030000"
PIN = "/soc@3000000/pinctrl@300b000/gmac0@0"
FD628 = "/soc@3000000/fd628_dev"
RAMOOPS = "/reserved-memory/ramoops@13ab00000"
DTB_OFF = 6144              # dtb offset in this vendor_boot (header v3, page 2048)

def die(msg):
    sys.exit("STOP: " + msg)

def run(*a):
    r = subprocess.run(a, capture_output=True, text=True)
    if r.returncode:
        die(f"{' '.join(a)} failed: {r.stderr.strip()}")
    return r.stdout.strip()

def patch_boot(path):
    b = bytearray(open(path, "rb").read())
    if b[:8] != b"ANDROID!" or struct.unpack("<I", b[40:44])[0] != 3:
        die(f"{path} is not an Android boot image v3")
    if b[KOFF + 56:KOFF + 60] != b"ARMd":
        die("no arm64 kernel Image at offset 4096")
    for va, old, new, what in KPATCH:
        o = KOFF + va - TEXT
        cur = b[o:o + 4].hex()
        if cur == new:
            print(f"  already patched: {what}")
            continue
        if cur != old:
            die(f"kernel bytes at {va:#x} are {cur}, expected {old}. "
                "This is a different firmware build - the offsets do not apply. Nothing was written.")
        b[o:o + 4] = bytes.fromhex(new)
        print(f"  patched: {what}")
    return b

def patch_vendor_boot(path, mac, ramoops):
    v = bytearray(open(path, "rb").read())
    if v[:8] != b"VNDRBOOT" or struct.unpack("<I", v[8:12])[0] != 3:
        die(f"{path} is not a vendor_boot v3 image")
    page = struct.unpack("<I", v[12:16])[0]
    dsize = struct.unpack("<I", v[2100:2104])[0]
    if v[DTB_OFF:DTB_OFF + 4] != b"\xd0\x0d\xfe\xed":
        die("device tree not found at offset 6144")
    end_pad = (DTB_OFF + dsize + page - 1) // page * page
    with tempfile.TemporaryDirectory() as t:
        d = os.path.join(t, "vb.dtb")
        open(d, "wb").write(v[DTB_OFF:DTB_OFF + dsize])
        comp = run("fdtget", d, ETH, "compatible")
        if not comp.startswith("allwinner,sunxi-gma"):
            die(f"unexpected gmac0 node: {comp}")
        # gigabit port on, 100M port off
        run("fdtput", "-t", "s", d, ETH, "compatible", "allwinner,sunxi-gmac")
        run("fdtput", "-t", "s", d, ETH, "status", "okay")
        run("fdtput", "-t", "s", d, ETH1, "status", "disabled")
        run("fdtput", "-t", "i", d, ETH, "use_ephy25m", "0")
        run("fdtput", "-t", "x", d, ETH, "tx-delay", "5")
        run("fdtput", "-t", "x", d, ETH, "rx-delay", "6")
        for p in ("phy-rst", "gmac-power0", "gmac-power1", "gmac-power2"):
            subprocess.run(["fdtput", "-d", d, ETH, p], capture_output=True)
        # pins: right function name + full drive strength (10 mA = level 0 in this kernel)
        run("fdtput", "-t", "s", d, PIN, "function", "emac0")
        run("fdtput", "-t", "x", d, PIN, "drive-strength", "0x28")
        # front display driver holds PI11/PI12 (RGMII TXCK/TXCTL)
        run("fdtput", "-t", "s", d, FD628, "status", "fail")
        if ramoops:
            subprocess.run(["fdtput", "-c", d, RAMOOPS], capture_output=True)
            run("fdtput", "-t", "s", d, RAMOOPS, "compatible", "ramoops")
            run("fdtput", "-t", "x", d, RAMOOPS, "reg", "1", "0x3ab00000", "0", "0x100000")
            run("fdtput", "-t", "x", d, RAMOOPS, "console-size", "0x80000")
            run("fdtput", "-t", "x", d, RAMOOPS, "record-size", "0x20000")
            run("fdtput", "-t", "x", d, RAMOOPS, "pmsg-size", "0x0")
            run("fdtput", "-t", "x", d, RAMOOPS, "ecc-size", "0")
        p = os.path.join(t, "vb2.dtb")
        run("dtc", "-q", "-I", "dtb", "-O", "dtb", "-o", p, d)
        nd = open(p, "rb").read()
    if DTB_OFF + len(nd) > end_pad:
        die("new device tree does not fit in the padding")
    v[DTB_OFF:end_pad] = nd + b"\0" * (end_pad - DTB_OFF - len(nd))
    v[2100:2104] = struct.pack("<I", len(nd))
    # boot line: fixed MAC address (driver needs one, u-boot passes an empty one)
    cl = bytes(v[28:28 + 2048]).rstrip(b"\0")
    if b"mac_addr=" not in cl:
        cl += b" mac_addr=" + mac.encode()
    if len(cl) >= 2048:
        die("boot line too long")
    v[28:28 + 2048] = cl.ljust(2048, b"\0")
    return v

def main():
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("boot"); ap.add_argument("vendor_boot")
    ap.add_argument("--mac", help="MAC to use (default: random locally administered 02:..)")
    ap.add_argument("--no-ramoops", action="store_true", help="don't add the crash-log memory region")
    a = ap.parse_args()
    mac = a.mac or "02:" + ":".join(f"{random.randint(0, 255):02x}" for _ in range(5))
    if len(mac) != 17:
        die("MAC must look like 02:11:22:33:44:55")
    print("boot image:")
    b = patch_boot(a.boot)
    print("vendor_boot image:")
    v = patch_vendor_boot(a.vendor_boot, mac, not a.no_ramoops)
    ob = a.boot.rsplit(".img", 1)[0] + ".patched.img"
    ov = a.vendor_boot.rsplit(".img", 1)[0] + ".patched.img"
    open(ob, "wb").write(b); open(ov, "wb").write(v)
    print(f"\nMAC address: {mac}")
    for f in (ob, ov):
        print(f"wrote {f}  md5 {hashlib.md5(open(f, 'rb').read()).hexdigest()}")

if __name__ == "__main__":
    main()

Tested: run on the original SlimBOX atv_12_16 images, the output kernel is byte-identical to the one running on my box. The device tree matches too, apart from two status strings written the standard way. A box with this fix has been running at ~790 Mbit/s with zero errors through reboots.

Questions welcome. If you have a different H618 box with an RTL8211F, the same six problems are probably there.

Am 19.10.2025 um 14:29 schrieb John Taylor:

Seeking SKW (SWT6621 / EA6521) SDIO Wi-Fi driver source or Linux 6.x port

Hi all,

 

I’m running Nick's Armbian-unofficial_25.05.0-trunk_Tanix-tx6s-axp313_bookworm_edge_6.12.11_server.img.xz on a TV box that originally shipped with Android using kernel 5.15

 

AIDA64 run on Android gives:

 

System

 

Device Type: TV
Manufacturer: Oranth
Model: TX68
Brand: ADT-3
Board: exdroid
Device: adt3
Hardware: sun50iw9p1
Platform: apollo
Product: adt3
Installed RAM: 4 GB
Total Memory: 3891 MB
Available Memory: 2512 MB
Internal Storage Total Space: 54.22 GB
Internal Storage Free Space: 52.57 GB
Bluetooth Version: 4+

 

Wi-Fi works perfectly under Android, but not under Armbian — the onboard Wi-Fi chip (connected over SDIO) is a SeekWave SWT6621, also known as SKW or EA6521.

 

From the Android side, I can see the driver is provided in binary form via:

 

/vendor/bin/hw/android.hardware.wifi-service-lazy
/vendor/etc/init/init.wlan.common.rc
/vendor/etc/firmware/SWT6621*_SDIO.bin

and the kernel logs show active skw_scan and skw_dump_survey messages when Android is running.

 

However, when booting Armbian, wlan0 never appears — only eth0 and virtual interfaces.

 

This strongly suggests that the SKW SDIO driver needs to be rebuilt or ported for kernel 6.x.

 

What I’m looking for:

 

Has anyone already ported or rebuilt the SKW (SWT6621 / EA6521) SDIO driver for Linux 6.x / Armbian?

If so, could you please share your source, patches, or build instructions?

If the work is in progress, I’d be very happy to help or test — I have the Android image and full /vendor contents available for reference.

Any leads on SeekWave source releases, OEM SDKs, or community ports would be greatly appreciated.

Thanks in advance for any guidance — I’d rather reuse or help finish existing work than start from scratch if someone has already begun tackling this.

Best Regards

John

@JohnTaylor

Hi, take a lock at https://github.com/joilg/ea6x21-dkms.git

I've played with ethernet on my transpeed box.

When it's connected to switch - no flaps are present.

When it's connected to OpenWRT router - link flaps frequently.

Main difference - switch has disabled flow control; ethtool shows that flow control is disabled

# ethtool -a end0

Pause parameters for end0:

Autonegotiate: on

RX: off

TX: off

RX negotiated: off

TX negotiated: off

but in logs it shows that flow control is enabled

[861094.666812] dwmac-sun8i 5030000.ethernet end0: Link is Down

[861095.680397] dwmac-sun8i 5030000.ethernet end0: Link is Up - 100Mbps/Full - flow control rx/tx

[861096.693534] dwmac-sun8i 5030000.ethernet end0: Link is Down

[861097.707132] dwmac-sun8i 5030000.ethernet end0: Link is Up - 100Mbps/Full - flow control rx/tx

[861098.720210] dwmac-sun8i 5030000.ethernet end0: Link is Down

[861100.747137] dwmac-sun8i 5030000.ethernet end0: Link is Up - 100Mbps/Full - flow control rx/tx

[861101.760236] dwmac-sun8i 5030000.ethernet end0: Link is Down

[861117.977394] dwmac-sun8i 5030000.ethernet end0: Link is Up - 100Mbps/Full - flow control off

also router shows that flow control is disabled, but negotiated as enabled

root@OpenWrt:~# ethtool -a lan1

Pause parameters for lan1:

Autonegotiate: on

RX: off

TX: off

RX negotiated: on

TX negotiated: on

and even if I disable flow control on router link continues to flap

[862550.022827] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control rx/tx

[862550.022852] br-lan: port 1(lan1) entered blocking state

[862550.036320] br-lan: port 1(lan1) entered forwarding state

[862551.669268] br-lan: port 1(lan1) entered disabled state

[862551.669401] mt7530-mdio mdio-bus:1f lan1: Link is Down

[862553.687828] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control rx/tx

[862553.687856] br-lan: port 1(lan1) entered blocking state

[862553.701328] br-lan: port 1(lan1) entered forwarding state

[862561.488710] br-lan: port 1(lan1) entered disabled state

[862561.488816] mt7530-mdio mdio-bus:1f lan1: Link is Down

[862564.469595] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control rx/tx

[862564.469621] br-lan: port 1(lan1) entered blocking state

[862564.483083] br-lan: port 1(lan1) entered forwarding state

[862569.791769] br-lan: port 1(lan1) entered disabled state

[862569.791877] mt7530-mdio mdio-bus:1f lan1: Link is Down

[862571.840395] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control off

[862571.840420] br-lan: port 1(lan1) entered blocking state

[862571.853725] br-lan: port 1(lan1) entered forwarding state

[862573.703305] br-lan: port 1(lan1) entered disabled state

[862573.703429] mt7530-mdio mdio-bus:1f lan1: Link is Down

[862605.355775] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control off

[862605.355802] br-lan: port 1(lan1) entered blocking state

[862605.369094] br-lan: port 1(lan1) entered forwarding state

[862610.322764] br-lan: port 1(lan1) entered disabled state

[862610.322869] mt7530-mdio mdio-bus:1f lan1: Link is Down

[862623.051283] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control off

[862623.051310] br-lan: port 1(lan1) entered blocking state

[862623.064619] br-lan: port 1(lan1) entered forwarding state

[862623.316705] br-lan: port 1(lan1) entered disabled state

[862623.316813] mt7530-mdio mdio-bus:1f lan1: Link is Down

[862631.003378] mt7530-mdio mdio-bus:1f lan1: Link is Up - 100Mbps/Full - flow control off

Edited by NiTr0

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.