Skip to main content

Airplay mirroring with HDMI dongles

I was interested in how Apple AirPlay screen mirroring is implemented in this super cheap Chinese HDMI dongles. Apple’s protocol is closed source and was reverse engineered back in in 2004. I couldn’t find an up to date open source project which implements a AirPlay server supporting screen mirroring. So lets see what this HDMI dongles have under the hood.

I purchased a device from ELEGIANT. I think there are also devices, sold under a different brand which are based on the same hardware.

Hardware

Just a quick summery of the found hardware components.

CPU

Rockchip RK3036G
ARM Cortex A7 dual core

RAM

128MB DDR3 SPI
Winbond W691GG6KB

Flash

16MB SPI
Winbond W25Q128BVIG
ID: 0x00ef4018

WiFi

Realtek RTL8188ETV
Connected via USB interface

Serial Console

Fortunately the CPU’s UART is accessible via pads. Couldn’t be easier! I only connected a regular USB-TTL adapter (115200 baud) to the RX/TX pads and powered the system.

Bootlog

The following shows the bootlog of the system. A lot of interesting information can be extracted from this information. You can also find a Gist of the bootlog here.

DDR Version 1.07 20170605_dbg
In
DDR3
456MHz
BW=16 Col=10 Bk=8 Row=13 CS=1 Size=128MB
OUT
0 BUILD: 2017-04-17, version: 1.22
sfc nor id: [ef 40 18]
g_spi_flash_info id 0x00ef4018.
AddrMode: 0
ReadLines: 0
ProgLines: 0
ReadCmd: 3
ProgCmd: 2
blkEraseCmd: d8
secEraseCmd: 20
boot_media = 0x10
flash vendor_storage_init
OK! 19253
loader flag: 0x0
start_linux=====20361
kernel_addr 200, 22 ms
load data done @678 ms
run kernel@0x62000000 =====678 ms
<hit enter to activate fiq debugger>
[    0.000000] Memory policy: ECC disabled, Data cache writealloc
[    0.000000] PERCPU: Embedded 6 pages/cpu @c081b000 s8512 r0 d16064 u32768
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
[    0.000000] Kernel command line: noinitrd console=ttyFIQ0 androidboot.selinux=permissive androidboot.hardware=rk30board init=/init
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Memory: 128MB = 128MB total
[    0.000000] Memory: 114352k/114352k available, 16720k reserved, 0K highmem
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     vmalloc : 0xc8800000 - 0xff000000   ( 872 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc8000000   ( 128 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0581d2c   (5608 kB)
[    0.000000]       .init : 0xc0582000 - 0xc0667140   ( 917 kB)
[    0.000000]       .data : 0xc0668000 - 0xc06bf558   ( 350 kB)
[    0.000000]        .bss : 0xc06bf558 - 0xc06f1af4   ( 202 kB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  RCU dyntick-idle grace-period acceleration is enabled.
[    0.000000]  Dump stacks of tasks blocking RCU-preempt GP.
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] rk_clk_tree_init start!
[    0.000000] rkclk: rkclk_init_gatecon 643:
[    0.000000] rkclk: This clk(g_hclk_mac) has been used,will be overwrited here!
[    0.000000] rk_get_uboot_display_flag: uboot_logo_on = 1
[    0.000000] rkclk_init_clks: cnt_parent = 10
[    0.000000] rkclk_init_clks: cnt_rate = 15
[    0.000000] Architected cp15 timer(s) running at 24.00MHz (phys).
[    0.000000] Switching to timer-based delay loop
[    0.000000] sched_clock: ARM arch timer >56 bits at 24000kHz, resolution 41ns
[    0.000000] process version: 0
[    0.000000] channel:0, lkg:244
[    0.000000] channel:0, lkg:244
[    0.000000] channel:0, lkg:244
[    0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 4294967286ms
[    0.045572] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
[    0.045606] pid_max: default: 32768 minimum: 301
[    0.045885] Mount-cache hash table entries: 512
[    0.046968] CPU: Testing write buffer coherency: ok
[    0.047378] /cpus/cpu@0 missing clock-frequency property
[    0.047408] /cpus/cpu@1 missing clock-frequency property
[    0.047462] CPU0: thread -1, cpu 0, socket 15, mpidr 80000f00
[    0.047516] Setting up static identity map for 0xc04557b8 - 0xc0455810
[    0.047919] last_log: 0x67056000 map to 0xc8804000 and copy to 0xc8807000, size 0x1000 early 0xfe7 (version 3.1)
[    0.122843] CPU1: Booted secondary processor
[    0.122906] CPU1: thread -1, cpu 1, socket 15, mpidr 80000f01
[    0.123071] Brought up 2 CPUs
[    0.123110] SMP: Total of 2 processors activated (96.00 BogoMIPS).
[    0.123128] CPU: All CPU(s) started in SVC mode.
[    0.124112] devtmpfs: initialized
[    0.131422] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
[    0.131981] pinctrl core: initialized pinctrl subsystem
[    0.132518] regulator-dummy: no parameters
[    0.149736] NET: Registered protocol family 16
[    0.151571] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.152422] Registered FIQ tty driver
[    0.154358] console [ttyFIQ0] enabled
[    0.154742] Registered fiq debugger ttyFIQ0
[    0.155574] rockchip_get_bank_data:name=/pinctrl@20008000/gpio0@2007c000 start=0x2007c000,end=0x2007c0ff
[    0.155713] rockchip_get_bank_data:name=/pinctrl@20008000/gpio1@20080000 start=0x20080000,end=0x200800ff
[    0.155813] rockchip_get_bank_data:name=/pinctrl@20008000/gpio2@20084000 start=0x20084000,end=0x200840ff
[    0.155913] rockchip_get_bank_data:name=/pinctrl@20008000/gpio15@20086000 start=0x20086000,end=0x200860ff
[    0.156002] rockchip_pinctrl_probe:name=rk3036-GPIO,type=4
[    0.156033] rockchip_pinctrl_probe:name=base start=0x20008000,end=0x200080a7
[    0.156064] rockchip_pinctrl_probe:name=mux start=0x200080a8,end=0x200080d7
[    0.156097] rockchip_pinctrl_probe:name=pull start=0x20008118,end=0x2000812f
[    0.156126] rockchip_pinctrl_probe:name=drv start=0x20008100,end=0x20008103
[    0.158554] rockchip_pinctrl_probe:init ok
[    0.167556] rk_iommu 10118300.vop_mmu: (vop) Enter
[    0.167677] rk_iommu 10118300.vop_mmu: IOVMM: Created 0x7fff000 B IOVMM from 0x10000000.
[    0.167712] rk_iommu 10118300.vop_mmu: (vop) Initialized
[    0.168080] rk_iommu 1010c440.hevc_mmu: (hevc) Enter
[    0.168190] rk_iommu 1010c440.hevc_mmu: IOVMM: Created 0x7fff000 B IOVMM from 0x10000000.
[    0.168227] rk_iommu 1010c440.hevc_mmu: (hevc) Initialized
[    0.168565] rk_iommu 10108800.vpu_mmu: (vpu) Enter
[    0.168662] rk_iommu 10108800.vpu_mmu: IOVMM: Created 0x7fff000 B IOVMM from 0x10000000.
[    0.168698] rk_iommu 10108800.vpu_mmu: (vpu) Initialized
[    0.170717] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
[    0.170750] hw-breakpoint: maximum watchpoint size is 8 bytes.
[    0.171363] rk3368_init_rockchip_pmu_ops: could not find pmu dt node
[    0.227972] bio: create slab <bio-0> at 0
[    0.228805] Rockchip hdmi driver version 2.0
.
[    0.229426] vdd_arm: 1100 <--> 1150 mV at 1100 mV
[    0.229904] usbcore: registered new interface driver usbfs
[    0.230002] usbcore: registered new interface driver hub
[    0.230244] usbcore: registered new device driver usb
[    0.231051] rk3036-usb-control usb_control.17: invalid host gpio-2
[    0.231105] rk3036-usb-control usb_control.17: invalid otg gpio-2
[    0.233174] rockchip_i2c 20056000.i2c: i2c-1: Rockchip I2C adapter
[    0.233359] RK29 Watchdog Timer, (c) 2011 Rockchip Electronics
[    0.234581] Rockchip ion module is successfully loaded (v1.1)
[    0.234933] Advanced Linux Sound Architecture Driver Initialized.
[    0.236308] cfg80211: Calling CRDA to update world regulatory domain
[    0.237557] rockchip-i2s 10220000.i2s: fail to clear
[    0.238046] Switching to clocksource arch_sys_counter
[    0.238542] fb disp policy is box
[    0.238572] uboot-logo-on:1
[    0.238640] rk-fb rockchip-fb: rk fb ion client create success!
[    0.238670] rk-fb rockchip-fb: rockchip framebuffer driver probe
[    0.239254] rk-screen rk_screen.9: rockchip screen probe success
[    0.239659] rk3036-lcdc lcdc0: can't find power_ctr node for lcdc0
[    0.240144] graphics fb0: rockchip framebuffer registerd:fb0
[    0.240819] graphics fb1: rockchip framebuffer registerd:fb1
[    0.241296] graphics fb2: rockchip framebuffer registerd:fb2
[    0.241742] rk3036-lcdc lcdc0: wakeup from standby!
[    0.250465] alloc_buffer:ion_phy_addr=0x10000000
[    0.255872] fb0:phy:10000000>>vir:c8827000>>len:0x800000
[    0.255919] rk_iommu 10118300.vop_mmu: rockchip_iommu_attach_device: Attached new IOMMU with pgtable 0x67147000
[    0.255955] rk3036-lcdc lcdc0: lcdc probe ok, iommu enabled
[    0.262710] NET: Registered protocol family 2
[    0.264048] TCP established hash table entries: 1024 (order: 1, 8192 bytes)
[    0.264116] TCP bind hash table entries: 1024 (order: 1, 8192 bytes)
[    0.264168] TCP: Hash tables configured (established 1024 bind 1024)
[    0.264263] TCP: reno registered
[    0.264297] UDP hash table entries: 256 (order: 1, 8192 bytes)
[    0.264348] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[    0.264715] NET: Registered protocol family 1
[    0.274834] hw perfevents: enabled with ARMv7_Cortex_A7 PMU driver, 5 counters available
[    0.275653] vcodec_service: No aclk reset resource define
[    0.275679] vcodec_service: No hclk reset resource define
[    0.275701] vcodec_service: No core reset resource define
[    0.275807] vcodec vpu_combo.11: failed on clk_get clk_cabac
[    0.275908] vcodec vpu_combo.11: do not have pd_video
[    0.275996] vcodec_service: probe device 10108400.vpu_service
[    0.276059] vcodec_power_on_rk3036
[    0.276087] vcodec_service: checking hw id 6731
[    0.277037] vcodec_service: probe device 1010c000.hevc_service
[    0.277104] vcodec_power_on_rk3036
[    0.277131] vcodec_service: checking hw id 6867
[    0.278068] vcodec_service: init success
[    0.286917] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.287282] jffs2: version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
[    0.288204] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 250)
[    0.288240] io scheduler noop registered
[    0.288264] io scheduler deadline registered (default)
[    0.347491] rk_battery_charger_detect_cb , battery_charger_detect 1
[    0.395848] rk-hdmi 20034000.hdmi: rockchip_hdmiv1_set_pwr_mode change pwr_mode 0 --> 1
[    0.395888] rk-hdmi 20034000.hdmi: rockchip_hdmiv1_set_pwr_mode change pwr_mode LOWER_PWR
[    0.396202] rk-hdmi 20034000.hdmi: hdmi probe success.
[    0.396960] cvbs connect to lcdc0
[    0.396991] switch:en=1,lcdc_id=0,screen type=5,cur type=5
[    0.397069] rk3036-lcdc lcdc0: lcdc0: dclk:27000000>>fps:52
[    0.397324] rk3036-tve 10118200.tve: rockchip,rk3036-tve tv encoder probe ok
[    0.400002] dma-pl330 20078000.pdma: Loaded driver for PL330 DMAC-2364208
[    0.400047] dma-pl330 20078000.pdma:         DBUFF-64x8bytes Num_Chans-8 Num_Peri-14 Num_Events-16
[    0.400447] rk_serial.c v1.8 2014-03-04
[    0.400819] 20060000.serial: ttyS0 at MMIO 0x20060000 (irq = 52) is a rk29_serial.0
[    0.401347] serial 20060000.serial: membase c907e000
[    0.401701] I : [File] : drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c; [Line] : 389; [Func] : mali_module_init(); svn_rev_string_from_arm of this mali_ko is '-v3.10.92-24848-g115e83a', rk_ko_ver is '5', built at '02:37:56', on 'Jul 18 2017'.
[    0.401961] mali-utgard 10091000.gpu: mali_platform_device->num_resources = 9
[    0.401999] mali-utgard 10091000.gpu: mali_platform_device->resource[0].start = 0x10091000
[    0.402034] mali-utgard 10091000.gpu: mali_platform_device->resource[1].start = 0x10090000
[    0.402066] mali-utgard 10091000.gpu: mali_platform_device->resource[2].start = 0x10093000
[    0.402099] mali-utgard 10091000.gpu: mali_platform_device->resource[3].start = 0x10098000
[    0.402128] mali-utgard 10091000.gpu: mali_platform_device->resource[4].start = 0x10094000
[    0.402159] mali-utgard 10091000.gpu: mali_platform_device->resource[5].start = 0x00000023
[    0.402189] mali-utgard 10091000.gpu: mali_platform_device->resource[6].start = 0x00000024
[    0.402222] mali-utgard 10091000.gpu: mali_platform_device->resource[7].start = 0x00000025
[    0.402251] mali-utgard 10091000.gpu: mali_platform_device->resource[8].start = 0x00000024
[    0.402535] mali-utgard 10091000.gpu: freq: 198000000, min_threshold: 0, max_threshold: 70
[    0.402576] mali-utgard 10091000.gpu: freq: 396000000, min_threshold: 71, max_threshold: 100
[    0.402640] mali-utgard 10091000.gpu: initial freq = 198000000
[    0.405032] Mali: Mali device driver loaded
[    0.406744] brd: module loaded
[    0.408000] rockchip,sfc 10208000.sfc: spi bus clock parent not specified, using clock at index 0 as parent
[    0.408043] rockchip,sfc 10208000.sfc: number of chip select lines not specified, assuming 1 chip select line
[    0.408079] rockchip,sfc 10208000.sfc: fail to get max-freq,default set 24000000HZ
[    0.408128] dws->regs: c909c000
[    0.408151] ===rockchip_spi_probe: pdev->id: -1===
[    0.408260] ===dw_spi_add_host: dws->name: dw_spi0===
[    0.415341] rockchip_spi_probe:num_cs=1,bus_num=0,irq=41,freq=99000000 ok
[    0.415393] dw_spi_setup:line=747
[    0.415670] @@@@@@@JEDEC id ef4018@@@@@@@@@@@ 0xef 0x40 0x18 0x0 0x0
[    0.415721] m25p80 spi0.0: found w25q128, expected s25fl256s1
[    0.415771] [ flash size 16777216, 0x1000000 (0)]
[    0.415804] m25p80 spi0.0: w25q128 (16384 Kbytes)
[    0.415825] flash_vendor_dev_ops_register is ok.
[    0.415852] Creating 5 MTD partitions on "rk29xxnand":
[    0.415883] 0x000000000000-0x000000040000 : "loader"
[    0.417294] 0x000000040000-0x000000440000 : "kernel"
[    0.418646] 0x000000440000-0x000000500000 : "data"
[    0.419978] 0x000000500000-0x000000ffd000 : "system"
[    0.421308] 0x000000ffd000-0x000000ffe000 : "misc"
[    0.422833] Rockchip WiFi SYS interface (V1.00) ...
[    0.422926] usb20_otg: version 3.10a 21-DEC-2012
[    0.425189] c9100040
[    0.425221] Core Release: 2.91a
[    0.425245] Setting default values for core params
[    0.425557] Using Buffer DMA mode
[    0.425582] Periodic Transfer Interrupt Enhancement - disabled
[    0.425605] Multiprocessor Interrupt Enhancement - disabled
[    0.425631] OTG VER PARAM: 0, OTG VER FLAG: 0
[    0.425652] ^^^^^^^^^^^^^^^^^Device Mode
[    0.425681] Dedicated Tx FIFOs mode
[    0.425734] pcd_init otg_dev = c6770200
[    0.426112] usb20_otg 10180000.usb: DWC OTG Controller
[    0.426180] usb20_otg 10180000.usb: new USB bus registered, assigned bus number 1
[    0.426258] usb20_otg 10180000.usb: irq 42, io mem 0x00000000
[    0.426401] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    0.426439] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    0.426469] usb usb1: Product: DWC OTG Controller
[    0.426498] usb usb1: Manufacturer: Linux 3.10.0 dwc_otg_hcd
[    0.426525] usb usb1: SerialNumber: 10180000.usb
[    0.427542] hub 1-0:1.0: USB hub found
[    0.427600] hub 1-0:1.0: 1 port detected
[    0.435244] usb20_host: version 3.10a 21-DEC-2012
[    0.444831] c9180040
[    0.444862] Core Release: 2.91a
[    0.444887] Setting default values for core params
[    0.445206] Using Buffer DMA mode
[    0.445235] Periodic Transfer Interrupt Enhancement - disabled
[    0.445257] Multiprocessor Interrupt Enhancement - disabled
[    0.445283] OTG VER PARAM: 0, OTG VER FLAG: 0
[    0.445305] ^^^^^^^^^^^^^^^^^^Host Mode
[    0.445369] usb20_host 101c0000.usb: DWC OTG Controller
[    0.445432] usb20_host 101c0000.usb: new USB bus registered, assigned bus number 2
[    0.445513] usb20_host 101c0000.usb: irq 43, io mem 0x00000000
[    0.445647] Init: Power Port (0)
[    0.445792] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[    0.445831] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    0.445859] usb usb2: Product: DWC OTG Controller
[    0.445888] usb usb2: Manufacturer: Linux 3.10.0 dwc_otg_hcd
[    0.445918] usb usb2: SerialNumber: 101c0000.usb
[    0.446904] hub 2-0:1.0: USB hub found
[    0.446962] hub 2-0:1.0: 1 port detected
[    0.454949] rk-keypad key.18: no io-channels defined
[    0.455378] input: rk29-keypad as /devices/key.18/input/input0
[    0.456071] btRc_init
[    0.456538] input: virtual_keyboard as /devices/virtual/input/input1
[    0.456571] btRc_open
[    0.456811] virtual_keyboard: registered as input device
[    0.456838] i2c /dev entries driver
[    0.457939] DVFS WARNING:    clk_enable_dvfs: clk(clk_ddr) freq table all value are smaller than default(456000), use default, just enable dvfs
[    0.457994] cpufreq version 1.0, suspend freq 600 MHz
[    0.458499] cpuidle: using governor ladder
[    0.458530] cpuidle: using governor menu
[    0.458622] Synopsys Designware Multimedia Card Interface Driver
[    0.458649] MHSC version = Ver 2.00 2015-06-10
[    0.459375] dwmmc_rockchip 10218000.rksdmmc: Version ID is 270a
[    0.459423] dwmmc_rockchip 10218000.rksdmmc: failed to get mmc_ahb reset.
[    0.459479] dwmmc_rockchip 10218000.rksdmmc: failed to get hpclk_mmc
[    0.532538] Using Buffer DMA mode
[    0.532571] Periodic Transfer Interrupt Enhancement - disabled
[    0.532595] Multiprocessor Interrupt Enhancement - disabled
[    0.532620] OTG VER PARAM: 0, OTG VER FLAG: 0
[    0.532643] ^^^^^^^^^^^^^^^^^^Host Mode
[    0.532916] dwmmc_rockchip 10218000.rksdmmc: Using external DMA controller.
[    0.533370] dwmmc_rockchip 10218000.rksdmmc: dw_mci_init_slot: fmin=200000, fmax=37500000 [mmc0]
[    0.533728] dwmmc_rockchip 10218000.rksdmmc: dw_mci_set_ios:  no card. [mmc0]
[    0.553040] dwmmc_rockchip 10218000.rksdmmc: dw_mci_set_ios:  no card. [mmc0]
[    0.572813] Init: Power Port (0)
[    0.572842] rk_battery_charger_detect_cb , battery_charger_detect 5
[    0.572972] dwmmc_rockchip 10218000.rksdmmc: DW MMC controller at irq 47, 32 bit host data width, 256 deep fifo
[    0.573007] dwmmc_rockchip 10218000.rksdmmc: 1 slots initialized
[    0.574262] dwmmc_rockchip 10218000.rksdmmc: dw_mci_set_ios:  no card. [mmc0]
[    0.575391] ashmem: initialized
[    0.575547] 10180000.usb resume, HPRT0:0x1000
[    0.575738] logger: created 32K log 'log_main'
[    0.575992] logger: created 4K log 'log_events'
[    0.576138] 10180000.usb suspend, HPRT0:0x1000
[    0.576275] logger: created 4K log 'log_radio'
[    0.576491] logger: created 4K log 'log_system'
[    0.578633] rockchip-pinctrl 20008000.pinctrl: pin gpio1-2 already requested by 20050000.pwm; cannot claim for 20030000.codec
[    0.578688] rockchip-pinctrl 20008000.pinctrl: pin-34 (20030000.codec) status -22
[    0.578723] rockchip-pinctrl 20008000.pinctrl: could not request pin 34 on device rockchip-pinctrl
[    0.578757] rk3036-codec 20030000.codec: Error applying setting, reverse things back
[    0.838205] rk3036-audio rockchip-audio.22:  rk3036-voice <-> 10220000.i2s mapping ok
[    0.839831] u32 classifier
[    0.839858]     Actions configured
[    0.839886] Netfilter messages via NETLINK v0.30.
[    0.840028] nf_conntrack version 0.5.0 (1914 buckets, 7656 max)
[    0.840648] ctnetlink v0.93: registering with nfnetlink.
[    0.841229] ip_tables: (C) 2000-2006 Netfilter Core Team
[    0.841497] TCP: cubic registered
[    0.841525] Initializing XFRM netlink socket
[    0.842302] NET: Registered protocol family 10
[    0.843451] ip6_tables: (C) 2000-2006 Netfilter Core Team
[    0.843759] sit: IPv6 over IPv4 tunneling driver
[    0.844758] NET: Registered protocol family 17
[    0.844828] NET: Registered protocol family 15
[    0.844853] [WLAN_RFKILL]: Enter rfkill_wlan_init
[    0.845105] [WLAN_RFKILL]: Enter rfkill_wlan_probe
[    0.845138] [WLAN_RFKILL]: can't find rockchip,grf property
[    0.845166] [WLAN_RFKILL]: wlan_platdata_parse_dt: wifi_chip_type = rtl8188eu
[    0.845192] [WLAN_RFKILL]: wlan_platdata_parse_dt: enable wifi power control.
[    0.845221] [WLAN_RFKILL]: wlan_platdata_parse_dt: disable wifi io reference voltage control.
[    0.845247] [WLAN_RFKILL]: wlan_platdata_parse_dt: wifi power controled by gpio.
[    0.845329] [WLAN_RFKILL]: wlan_platdata_parse_dt: get property: WIFI,poweren_gpio = 94, flags = 1.
[    0.845407] [WLAN_RFKILL]: wlan_platdata_parse_dt: get property: WIFI,host_wake_irq = 84, flags = 0.
[    0.845433] [WLAN_RFKILL]: rfkill_wlan_probe: init gpio
[    0.845491] [WLAN_RFKILL]: Exit rfkill_wlan_probe
[    0.845597] [BT_RFKILL]: Enter rfkill_rk_init
[    0.845941] flash vendor_init_thread!
[    0.845974] vendor_sfc_read from 0x00001000, len 4096
[    0.846758] g_vendor->tag: 0x524b5644, ver: 2 : 2.
[    0.846780] vendor_sfc_read from 0x00002000, len 4096
[    0.847546] g_vendor->tag: 0x524b5644, ver: 3 : 3.
[    0.847573] vendor_sfc_read from 0x00003000, len 4096
[    0.848376] g_vendor->tag: 0x524b5644, ver: 4 : 4.
[    0.848404] vendor_sfc_read from 0x00004000, len 4096
[    0.849162] g_vendor->tag: 0x524b5644, ver: 5 : 5.
[    0.849193] vendor_sfc_read from 0x00004000, len 4096
[    0.849956] max_ver: 5, max_index: 3.
[    0.849970] rk3036_init_suspend
[    0.849990] rk3036_suspend_init enter
[    0.850082] rk3036_suspend_init: pm_ctrbits =1102e
[    0.850298] flash vendor storage:20170308 ret = 0
[    0.850327] Registering SWP/SWPB emulation handler
[    0.858157] ddrfreq: verion 1.2 20140526
[    0.858198] ddrfreq: normal 456MHz video_1080p 0MHz video_4k 0MHz dualview 0MHz idle 0MHz suspend 0MHz reboot 456MHz video_4k_10b 0MHz
[    0.858226] ddrfreq: auto-freq=0
[    0.858245] ddrfreq: auto-freq-table epmty!
[    0.859503] vdd_arm: disabling
[    0.859536] regulator-dummy: disabling
[    0.859724]
[    0.859748] =======================================================
[    0.859772] ==== Launching Wi-Fi driver! (Powered by Rockchip) ====
[    0.859791] =======================================================
[    0.859813] Realtek 8188EU USB WiFi driver (Powered by Rockchip) init.
[    0.859836] [WLAN_RFKILL]: rockchip_wifi_power: 1
[    0.859860] [BT_RFKILL]: rfkill_get_bt_power_state: rfkill-bt driver has not Successful initialized
[    0.859886] [WLAN_RFKILL]: rockchip_wifi_ref_voltage: 1
[    0.859911] [WLAN_RFKILL]: rockchip_wifi_ref_voltage: wifi io reference voltage control is disabled.
[    0.966306] [WLAN_RFKILL]: wifi turn on power. 94
[    0.966335] RTW: module init start
[    0.966357] RTW: rtl8188eu v5.2.2_19960.20161226
[    0.966378] RTW: build time: Jun 27 2017 21:47:23
[    0.966580] usbcore: registered new interface driver rtl8188eu
[    0.966605] RTW: module init ret=0
[    0.966916] pcd_pullup, is_on 0
[    0.966964] WARN::dwc_otg_handle_mode_mismatch_intr:69: Mode Mismatch Interrupt: currently in Host mode
[    0.966964]
[    0.967065] file system registered
[    0.968658] android_usb gadget: Mass Storage Function, version: 2009/09/11
[    0.968695] android_usb gadget: Number of LUNs=2
[    0.968722]  lun0: LUN: removable file: (no medium)
[    0.968745]  lun1: LUN: removable file: (no medium)
[    0.968819] android_usb gadget: android_usb ready
[    0.969119] ALSA device list:
[    0.969147]   #0: RK_RK3036
[    0.969324] Warning: unable to open an initial console.
[    0.971979] Freeing unused kernel memory: 916K (c0582000 - c0667000)
[    0.981553] init: could not import file 'init.box.samba.rc' from '/init.rk30board.rc'
[    0.987265] init: invalid gid 'trace'
[    1.113348] init: /dev/hw_random not found
[    1.113470] init: could not open /dev/keychord
[    1.118351] init: /dev/hw_random not found
[    1.120099] fs_mgr: =================fstab->num_entries: 2=======================
[    1.120167] fs_mgr: =====index: 0, mount_point = /system======
[    1.124776] fs_mgr: [xiaoyao] __mount(source=/dev/block/mtdblock3,target=/system,type=squashfs)=0
[    1.124864] fs_mgr: =====index: 1, mount_point = /data======
[    1.124951] fs_mgr: =======reset userdata start =======
[    1.125063] fs_mgr: open /dev/block/mtdblock4 ok!
[    1.125110] fs_mgr: /dev/block/mtdblock4 cur pos: 0.
[    1.126698] fs_mgr: ===reset_flag: 0.===
[    1.126749] fs_mgr: ========= reset userdata ok==============
[    1.170291] fs_mgr: [xiaoyao] __mount(source=/dev/block/mtdblock2,target=/data,type=jffs2)=0
[    1.554257] init: property 'ro.serialno' doesn't exist while expanding '${ro.serialno}'
[    1.554320] init: cannot expand '${ro.serialno}' while writing to '/sys/class/android_usb/android0/iSerial'
[    1.555009] init: using deprecated syntax for specifying property 'ro.product.usbfactory', use ${name} instead
[    1.853925] android_usb: already disabled
[    1.872192] read descriptors
[    1.872238] read strings
[    1.872335] pcd_pullup, is_on 1
[    2.434464] dwc_otg_hcd_enable, enable host controller
[    2.618860] Using Buffer DMA mode
[    2.618911] Periodic Transfer Interrupt Enhancement - disabled
[    2.618937] Multiprocessor Interrupt Enhancement - disabled
[    2.618959] OTG VER PARAM: 0, OTG VER FLAG: 0
[    2.618978] ^^^^^^^^^^^^^^^^^^Host Mode
[    2.688513] Init: Power Port (0)
[    2.691798] 101c0000.usb resume, HPRT0:0x21401
[    2.865130] Indeed it is in host mode hprt0 = 00021501
[    3.100116] usb 2-1: new high-speed USB device number 2 using usb20_host
[    3.106835] Indeed it is in host mode hprt0 = 00001101
[    3.323651] logd.auditd: start
[    3.339947] usb 2-1: New USB device found, idVendor=0bda, idProduct=0179
[    3.339998] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    3.340027] usb 2-1: Product: 802.11n NIC
[    3.340056] usb 2-1: Manufacturer: Realtek
[    3.351969] bFWReady == _FALSE call reset 8051...
[    3.426856] RTW: 0x000: 29 81 00 6C 0B 00 00 00    00 0C 00 00 00 00 00 00
[    3.426953] RTW: 0x010: 2E 2E 2E 2E 2E 2E 2E 2D    2C 2C 2B 01 FF FF FF FF
[    3.427033] RTW: 0x020: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427108] RTW: 0x030: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427184] RTW: 0x040: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427266] RTW: 0x050: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427341] RTW: 0x060: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427426] RTW: 0x070: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427505] RTW: 0x080: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427583] RTW: 0x090: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427659] RTW: 0x0a0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.427737] RTW: 0x0b0: FF FF FF FF FF FF FF FF    20 21 1A 00 00 00 00 00
[    3.427816] RTW: 0x0c0: 00 00 00 10 00 00 00 00    00 03 FF FF FF FF FF FF
[    3.427928] RTW: 0x0d0: DA 0B 79 01 43 66 00 28    F3 66 9C 04 63 0A 03 52
[    3.428023] RTW: 0x0e0: 65 61 6C 74 65 6B 0D 0D    03 38 30 32 2E 31 31 6E
[    3.428116] RTW: 0x0f0: 20 4E 49 43 FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428202] RTW: 0x100: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428278] RTW: 0x110: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428355] RTW: 0x120: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428433] RTW: 0x130: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428509] RTW: 0x140: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428593] RTW: 0x150: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428671] RTW: 0x160: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428756] RTW: 0x170: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428832] RTW: 0x180: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428912] RTW: 0x190: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.428990] RTW: 0x1a0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.429068] RTW: 0x1b0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.429145] RTW: 0x1c0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.429222] RTW: 0x1d0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.429304] RTW: 0x1e0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.429381] RTW: 0x1f0: FF FF FF FF FF FF FF FF    FF FF FF FF FF FF FF FF
[    3.429464]
[    3.429509] RTW: hal_com_config_channel_plan chplan:0x20
[    3.430520] RTW: rtw_regsty_chk_target_tx_power_valid return _FALSE for band:0, path:0, rs:0, t:-1
[    3.430662] [WLAN_RFKILL]: rockchip_wifi_mac_addr: enter.
[    3.434670] RTW: rtw_ndev_init(wlan0) if1 mac_addr=28:f3:66:9c:04:63
[    3.440101] RTW: rtw_ndev_init(p2p0) if2 mac_addr=2a:f3:66:9c:04:63
root@rk3036:/ # [    4.857291] rk3036-lcdc lcdc0: blank mode:0
[    8.297192] [otg id chg] last id -1 current id 2048
[   14.670059] Current WiFi chip is RTL8188EU.
[   14.670337] Current WiFi chip is RTL8188EU.
[   14.998872] ==> rtl8188e_iol_efuse_patch
[   15.418089] RTW: wlan0- hw port(0) mac_addr =28:f3:66:9c:04:63
[   15.418769] RTW: p2p0- hw port(1) mac_addr =2a:f3:66:9c:04:63
[   15.424155] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[   15.424463] IPv6: ADDRCONF(NETDEV_UP): p2p0: link is not ready
[   15.424641] Current WiFi chip is RTL8188EU.
[   15.747972] warning: `wpa_supplicant' uses 32-bit capabilities (legacy support in use)
[   16.034537] Current WiFi chip is RTL8188EU.
[   17.398626] RTW: nolinked power save enter
[   18.231443] Current WiFi chip is RTL8188EU.
[   18.767631] ==> rtl8188e_iol_efuse_patch
[   19.105571] RTW: wlan0- hw port(0) mac_addr =28:f3:66:9c:04:63
[   19.106228] RTW: p2p0- hw port(1) mac_addr =2a:f3:66:9c:04:63
[   19.110838] RTW: nolinked power save leave
[   19.110926] RTW: ERROR rtw_release_macid(p2p0) if2, hwaddr:ff:ff:ff:ff:ff:ff with macid:1
[   19.111871] IPv6: ADDRCONF(NETDEV_UP): p2p0: link is not ready
[   19.135100] RTW: port switch - port0(p2p0), port1(wlan0)
[   19.274257] RTW: assoc success
[   19.281669] IPv6: ADDRCONF(NETDEV_CHANGE): p2p0: link becomes ready
[   19.289561] RTW: set group key camid:0, addr:2a:f3:66:9c:04:63, kid:1, type:AES
[   20.561074] flash_vendor_ioctl cmd=40047601 ret = 0
[   21.527836] flash_vendor_ioctl cmd=40047601 ret = 0

Now we can confirm that the flash chip is a w25q128.

[    0.415341] rockchip_spi_probe:num_cs=1,bus_num=0,irq=41,freq=99000000 ok
[    0.415393] dw_spi_setup:line=747
[    0.415670] @@@@@@@JEDEC id ef4018@@@@@@@@@@@ 0xef 0x40 0x18 0x0 0x0
[    0.415721] m25p80 spi0.0: found w25q128, expected s25fl256s1
[    0.415771] [ flash size 16777216, 0x1000000 (0)]
[    0.415804] m25p80 spi0.0: w25q128 (16384 Kbytes)

And know the exact flash layout.

[    0.415852] Creating 5 MTD partitions on "rk29xxnand":
[    0.415883] 0x000000000000-0x000000040000 : "loader"
[    0.417294] 0x000000040000-0x000000440000 : "kernel"
[    0.418646] 0x000000440000-0x000000500000 : "data"
[    0.419978] 0x000000500000-0x000000ffd000 : "system"
[    0.421308] 0x000000ffd000-0x000000ffe000 : "misc"

Get an image of the processes, running on the system.

root@rk3036:/ # ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC        NAME
root      1     0     724    348   c00b45d8 000355d0 S /init
root      2     0     0      0     c0043ba0 00000000 S kthreadd
root      3     2     0      0     c004a1dc 00000000 S ksoftirqd/0
root      5     2     0      0     c003e394 00000000 S kworker/0:0H
root      6     2     0      0     c003e394 00000000 S kworker/u4:0
root      7     2     0      0     c004a1dc 00000000 S migration/0
root      8     2     0      0     c006e778 00000000 S rcu_preempt
root      9     2     0      0     c006e778 00000000 S rcu_bh
root      10    2     0      0     c006e778 00000000 S rcu_sched
root      11    2     0      0     c004a1dc 00000000 S watchdog/0
root      12    2     0      0     c004a1dc 00000000 S watchdog/1
root      13    2     0      0     c004a1dc 00000000 S migration/1
root      14    2     0      0     c004a1dc 00000000 S ksoftirqd/1
root      16    2     0      0     c003e394 00000000 S kworker/1:0H
root      17    2     0      0     c003e608 00000000 S khelper
root      18    2     0      0     c01ac488 00000000 S kdevtmpfs
root      19    2     0      0     c003e394 00000000 S kworker/0:1
root      20    2     0      0     c003e394 00000000 S kworker/1:1
root      21    2     0      0     c001ea94 00000000 S kconsole
root      22    2     0      0     c003e608 00000000 S writeback
root      23    2     0      0     c003e608 00000000 S bioset
root      24    2     0      0     c003e394 00000000 S kworker/u5:0
root      25    2     0      0     c003e608 00000000 S kblockd
root      26    2     0      0     c028de00 00000000 S khubd
root      27    2     0      0     c030b08c 00000000 S vmalloc
root      28    2     0      0     c003e608 00000000 S cfg80211
root      29    2     0      0     c01573d0 00000000 S fb-vsync
root      30    2     0      0     c0043d10 00000000 S rk-fb
root      31    2     0      0     c02e123c 00000000 S cfinteractive
root      32    2     0      0     c0066e74 00000000 S irq/39-10108400
root      33    2     0      0     c0066e74 00000000 S irq/89-1010c000
root      34    2     0      0     c00656cc 00000000 S khungtaskd
root      35    2     0      0     c0087f84 00000000 S kswapd0
root      36    2     0      0     c00d80cc 00000000 S fsnotify_mark
root      37    2     0      0     c003e608 00000000 S hdmi-20034000.h
root      38    2     0      0     c003e394 00000000 S kworker/u4:1
root      39    2     0      0     c0043d10 00000000 S spi0
root      40    2     0      0     c003e608 00000000 S dwc_otg
root      41    2     0      0     c003e608 00000000 S dwc_otg
root      42    2     0      0     c003e608 00000000 S uether
root      43    2     0      0     c003e608 00000000 S dw-mci-card
root      44    2     0      0     c003e608 00000000 S binder
root      46    2     0      0     c001c6e8 00000000 S ddrfreqd
root      47    2     0      0     c003e608 00000000 S workqueue_cpu_u
root      48    2     0      0     c003e608 00000000 S workqueue_cpu_u
root      49    2     0      0     c003e608 00000000 S deferwq
root      50    2     0      0     c02c9958 00000000 S file-storage
root      51    1     668    256   c00b45d8 000355d0 S /sbin/ueventd
root      53    2     0      0     c010c12c 00000000 S jffs2_gcd_mtd2
logd      54    1     5048   580   ffffffff b6fa690c S /system/bin/logd
root      55    1     1120   412   c003893c b6f0190c S /system/bin/sh
system    56    1     1200   248   c032360c b6ee1d48 S /system/bin/servicemanager
system    57    1     41204  2240  ffffffff b6f70808 S /system/bin/surfaceflinger
root      58    2     0      0     c003e394 00000000 S kworker/0:2
root      59    1     10384  588   ffffffff b6f1c1fc S /system/bin/netd
root      60    1     1804   304   c035586c b6ee14ac S /system/bin/debuggerd
root      61    1     28432  3152  ffffffff b6e7ed48 S /system/bin/mediaserver
root      62    1     11340  1008  ffffffff b6f911fc S /system/bin/lollipop
root      63    1     3928   520   ffffffff b6f681fc S /system/bin/lollipop_lamp
root      64    1     4632   212   ffffffff 00025f1c S /sbin/adbd
root      65    2     0      0     c003e394 00000000 S kworker/1:2
root      144   1     22176  2364  ffffffff b6edd1fc S /system/bin/lollipop_softap
root      252   2     0      0     c00480cc 00000000 S RTW_CMD_THREAD
wifi      253   1     3732   552   c00b45d8 b6e5cfa0 S /system/bin/wpa_supplicant
wifi      257   59    3412   700   c00b45d8 b6eb2fa0 S /system/bin/hostapd
root      264   1     1276   360   c00b45d8 b6eedfa0 S /system/bin/boa
root      265   144   1888   388   c00b45d8 b6efdfa0 S /system/bin/dnsmasq
root      272   1     1756   280   c002d2a8 b6ec0c3c S /system/bin/none_stop_service
root      273   272   12636  1068  ffffffff b6eced48 S /system/bin/MediaDaemon
root      278   1     1756   280   c002d2a8 b6fa9c3c S /system/bin/none_stop_service
root      279   278   18220  1540  ffffffff b6f801fc S /system/bin/rk_dlna_dmr
root      280   1     1756   280   c002d2a8 b6f60c3c S /system/bin/none_stop_service
root      281   280   52888  7456  ffffffff b65151fc S /system/bin/airplayprog
root      318   264   0      0     c002dc6c 00000000 Z key.cgi
root      346   2     0      0     c003e394 00000000 S kworker/u4:2
root      347   2     0      0     c003e394 00000000 S kworker/u4:3
root      356   2     0      0     c003e394 00000000 S kworker/0:0
root      357   2     0      0     c003e394 00000000 S kworker/1:0
root      362   55    2432   896   00000000 b6f0df50 R ps

And a quick overview of the root filesystem.

root@rk3036:/ # ls -la
__bionic_open_tzdata: couldn't find any tzdata when looking for localtime!
__bionic_open_tzdata: couldn't find any tzdata when looking for GMT!
__bionic_open_tzdata: couldn't find any tzdata when looking for posixrules!
drwxr-xr-x root     root              1970-01-01 00:00 acct
lrwxrwxrwx system   system            2017-09-24 03:36 charger -> /sbin/healthd
lrwxrwxrwx root     root              1970-01-01 00:00 d -> /sys/kernel/debug
drwxrwx--x system   system            1970-01-01 00:03 data
-rw-rw-r-- system   system        311 2017-09-24 03:36 default.prop
drwxr-xr-x root     root              1970-01-01 00:00 dev
lrwxrwxrwx root     root              1970-01-01 00:00 etc -> /system/etc
-rw-rw-r-- system   system      16813 2017-09-24 03:36 file_contexts
lrwxrwxrwx root     root              1970-01-01 00:00 fstab.rk30board -> /fstab.rk30board.bootmode.unknown
-rw-rw-r-- system   system       2590 2017-09-24 03:36 fstab.rk30board.bootmode.emmc
-rw-rw-r-- system   system       2615 2017-09-24 03:36 fstab.rk30board.bootmode.unknown
-rwxrwxr-x system   system     309836 2017-09-24 03:36 init
-rwxrwxr-x system   system       5812 2017-09-24 03:36 init.connectivity.rc
-rw-rw-r-- system   system        944 2017-09-24 03:36 init.environ.rc
-rwxrwxr-x system   system      21851 2017-09-24 03:36 init.rc
-rw-rw-r-- system   system        556 2017-09-24 03:36 init.rk30board.bootmode.emmc.rc
-rw-rw-r-- system   system        454 2017-09-24 03:36 init.rk30board.bootmode.unknown.rc
-rw-rw-r-- system   system        156 2017-09-24 03:36 init.rk30board.environment.rc
-rwxrwxr-x system   system       5929 2017-09-24 03:36 init.rk30board.rc
-rw-rw-r-- system   system       6333 2017-09-24 03:36 init.rk30board.usb.rc
-rwxr--r-- system   system       9499 2017-09-24 03:36 init.rockchip.rc
-rwxr--r-- system   system       9501 2017-09-24 03:36 init.rockchip.rc.bak
-rw-rw-r-- system   system       1927 2017-09-24 03:36 init.trace.rc
-rw-rw-r-- system   system       3885 2017-09-24 03:36 init.usb.rc
-rw-rw-r-- system   system        301 2017-09-24 03:36 init.zygote32.rc
drwxrwxr-x root     system            1970-01-01 00:00 mnt
dr-xr-xr-x root     root              1970-01-01 00:00 proc
-rw-rw-r-- system   system       2771 2017-09-24 03:36 property_contexts
drwxrwxr-x system   system            2017-09-24 03:36 res
drwxrwxr-x system   system            2017-09-24 03:36 sbin
-rw-rw-r-- system   system        550 2017-09-24 03:36 seapp_contexts
-rw-rw-r-- system   system         62 2017-09-24 03:36 selinux_version
dr-xr-xr-x root     root              1970-01-01 00:00 sys
drwxrwxrwx root     root              2017-09-23 10:17 system
-rw-rw-r-- system   system       4464 2017-09-24 03:36 ueventd.rc
-rwxrwxr-x system   system       4299 2017-09-24 03:36 ueventd.rk30board.rc
lrwxrwxrwx root     root              1970-01-01 00:00 vendor -> /system/vendor

Firmware

In the next step we will try to dump the firmware by reading the flash chip. Unfortunately there are no ways to read the mtd partitions from the running system, due to the fact that no required binaries like dd are available.

Dumping the Firmware

First we need to get physically exclusive access to the flash chip, to dump the contained firmware. To get the pin configuration of the flash chip, I took a look at the Winbond w25q128 datasheet.

I probed all exposed pads, available on the pcb to support different chip footprints, and soldered wires to VCC, GND, DO, DI, CLK, CS, WP and HOLD.

To get exclusive access to the SPI interface, we have to ensure that the main processor doesn’t access the SPI interface. This is often quite complicated, since we have to keep the system offline while the chip needs to be powered.
One solution is to find the cpu’s reset pin and pull it down to keep it in the reset state while the system is powered. For me this didn’t worked, so I finally ended in desoldering the complete flash chip.

To get this done, you will definitely need a hot air rework station. Afterwards I soldered copper wires to the chip and connected it to a Raspberry Pi, acting as SPI master in this setup.

On the Raspberry Pi the pins 17,19,21,23,24 and 25 are used.

Wiring between Raspberry Pi and w25q128.

Raspberry Pi w25q128
17 VCC, WP, HOLD
19 DI
21 DO
23 CLK
24 CS
25 GND

To read the content of the chip, a program called flashrom was used. It’s acting as SPI master, supports the most common flash chips and runs unter Linux.

To use the SPI interface on the Raspberry Pi, we have to enable it first.

sudo raspi-config

Install the required packages, needed by flashrom.

sudo apt-get install git build-essential
sudo apt-get install pciutils
sudo apt-get install zlib1g-dev
sudo apt-get install libftdi
sudo apt-get install libftdi-dev
sudo apt-get install libusb-1.0-0-dev

Clone the lates available flashrom sources and build it.

git clone https://github.com/flashrom/flashrom.git
cd flashrom
make

And finally dump the content of the flash.

./flashrom -p linux_spi:dev=/dev/spidev0.0 -r flash.dump

I repeated this step multiple times and compared the hash of the dumped file to ensure the reading was consistent.

shasum flash*.dump
56662ce86bef39d870fe8bcf000d3bde186f11e8  flash1.dump
56662ce86bef39d870fe8bcf000d3bde186f11e8  flash2.dump
56662ce86bef39d870fe8bcf000d3bde186f11e8  flash3.dump
56662ce86bef39d870fe8bcf000d3bde186f11e8  flash4.dump

The extracted firmware dump is available here.

Analyzing the Firmware

Let’s do a binary analysis of the extracted firmware. Binwalk is the perfect tool for this job.

binwalk flash.dump

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
269948        0x41E7C         LZO compressed data
270273        0x41FC1         LZO compressed data
3229560       0x314778        xz compressed data
3737425       0x390751        Unix path: /proc/sys/kernel/domainname0l
3751985       0x394031        SHA256 hash constants, little endian
3989552       0x3CE030        SHA256 hash constants, little endian
4456448       0x440000        JFFS2 filesystem, little endian
5242880       0x500000        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 11450084 bytes, 416 inodes, blocksize: 131072 bytes, created: 2017-09-24 03:36:29

The results of binwalk perfectly matches the already known flash layout, we know from the bootlog. The data partition has a JFFS2 filesystem and the system partition is a xz compressed Squashfs filesystem.

[    0.415852] Creating 5 MTD partitions on "rk29xxnand":
[    0.415883] 0x000000000000-0x000000040000 : "loader"
[    0.417294] 0x000000040000-0x000000440000 : "kernel"
[    0.418646] 0x000000440000-0x000000500000 : "data"
[    0.419978] 0x000000500000-0x000000ffd000 : "system"
[    0.421308] 0x000000ffd000-0x000000ffe000 : "misc"

It’s easy to split the firmware dump in it’s mtd partitions.

dd if=flash.dump of=bootloader.bin bs=1 count=$((0x040000))
dd if=flash.dump of=kernel.bin bs=1 count=$((0x0440000-0x040000)) skip=$((0x040000))
dd if=flash.dump of=data.bin bs=1 count=$((0x500000-0x440000)) skip=$((0x440000))
dd if=flash.dump of=system.bin bs=1 count=$((0xffd000-0x500000)) skip=$((0x500000))
dd if=flash.dump of=misc.bin bs=1 count=$((0xffe000-0xffd000)) skip=$((0xffd000))

Now let’s mount the filesystem of the extracted data and system partition.

sudo modprobe mtdram
sudo mknod /dev/mtdblock0 b 31 0
sudo dd if=data.bin of=/dev/mtdblock0
sudo mount -t jffs2 -o ro /dev/mtdblock0 /mnt/data
sudo mount -t squashfs -o ro system.bin /mnt/system

At this point we have access to the firmware filesystem. I will stop my investigations here. Feel free to dig further in the firmware. Feedback is always welcome.

3 thoughts to “Airplay mirroring with HDMI dongles”

  1. Can you convert your flash.dump to binary? I have TL866 programmer for spi flash.. Thanks

    1. The firmware dump (flash.dump) is in binary format. flashrom has no specific export format.

Leave a Reply to Nikola Cancel reply

Your email address will not be published. Required fields are marked *