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.
Can you convert your flash.dump to binary? I have TL866 programmer for spi flash.. Thanks
The firmware dump (flash.dump) is in binary format. flashrom has no specific export format.
My (almost identical) device “ATETION WiFi Wireless Display Dongle” downloads firmware updates from http://47.254.159.158/rk3036g/rk2e_p011/ (web server directory listings are enabled, you can even walk up/down the dir tree). With this https://github.com/linux-rockchip/rkflashtool/pull/12 patch you can decode the firmware file.
Superb posts! Have a look at my page Webemail24 where I also put in extra effort to create quality information about Social Media Marketing.
Hey there, I love all the points you made on that topic. There is definitely a great deal to know about this subject, and with that said, feel free to visit my blog Seoranko to learn more about PR Marketing.
Hey, if you are looking for more resources, check out my website 85N as I cover topics about Webdesign. By the way, you have impressive design and layout, plus interesting content, you deserve a high five!
Hey there, I love all the points you made on that topic. There is definitely a great deal to know about this subject, and with that said, feel free to visit my blog QU5 to learn more about Thai-Massage.
Sharing is caring the say, and you’ve done a fantastic job in sharing your knowledge on your blog. It would be great if you check out my page, too, at YQ9 about Airport Transfer.
You absolutely know how to keep your readers interest with your witty thoughts on that topic. I was looking for additional resources, and I am glad I came across your site. Feel free to check my website 59N about Cosmetics.
I came across your site wanting to learn more and you did not disappoint. Keep up the terrific work, and just so you know, I have bookmarked your page to stay in the loop of your future posts. Here is mine at 71N about Thai-Massage. Have a wonderful day!
Sharing is caring the say, and you’ve done a fantastic job in sharing your knowledge on your blog. It would be great if you check out my page, too, at FQ7 about Car Purchase.
Your blog has really piqued my interest on this topic. Feel free to drop by my website YH9 about Entrepreneurs.
The way you put together the information on your posts is commendable. I would highly recommend this site. You might also want to check my page UQ5 for some noteworthy inputs about Affiliate Marketing.
You made some really good points on your post. Definitely worth bookmarking for revisiting. Also, visit my website FQ6 for content about Cosmetics.
Superb and well-thought-out content! If you need some information about Cosmetic Treatment, then have a look at UQ8