Безымянный одноплатник с али

разделы: Интернет вещей , дата: 16 мая 2025г.

Я долгое время избегал темы OpenWRT, опасаясь деструктивных последствий статей по перепрошивке домашней техники. Однако плата про которую речь пойдет ниже, не является домашней техникой, это модуль от повербанка, который продется без какого-либо описания, характеристик и обещаний, что он у вас заработает. В моем случае одна плата пришла с неработоспособной прошивкой, а вторая запароленная. Модуль выполнен на чипе RT5350F компании Ralink (сейчас подразделение тайваньской Mediatek), который был популярным лет десять назад, главным образом благодаря миниатюрному роутеру HAME MPR-A1 включая его всевозможные клоны. Главным образом в плате меня привлек форм-фактор, т.е. миниатюрный размер, 8 МБ флеш-памяти и 32 МБ ОЗУ. Кроме того, хотелось поковыряться в железке, чему-то научиться, подержать в руках на чип о котором когда-то много читал, составить свое мнение (в начале я вообще думал, что у него архитектура ARM).

Данная статья - это ворклог, о превращению платы без какого - либо описания в маломощный одноплатник. Целевое применение такого модуля, на мой взгляд - это веб-интерфейс какого-либо сложного устройства, например для музыкального центра вместо пульта ДУ. В данном случае подразумевается работа данного модуля в связке с микроконтроллером, связь с которым осуществляется посредством либо UART, либо USB (в зависимости от объема передаваемых данных).

ВНИМАНИЕ! Статья не является рекламной, я не даю ссылок, где приобретался модуль, я НЕ(!) рекомендую эту плату к покупке, так же как и любого другого старого барахла для OpenWRT. В лотах продавцов данных модулей НЕ указаны характеристики устройств, могут прислать с 16 МБ ОЗУ и 4 МБ флеш-памяти, и вы не получите никакой компенсации открывая спор. В настоящее время можно прибрести новый одноплатник на любой бюджет, и он будет в сто раз лучше, чем RT5350F с SDRAM(!) памятью и рабочей температурой в 60(!!) градусов. Будьте благоразумны.

Содержание:

  1. Обзор платы YB-628
  2. Снятие дампа стоковой прошивки
  3. Прошивка в OpenWRT 15.05
  4. Первичная настройка OpenWRT
  5. Вторая плата
  6. Обновление OpenWRT до версии 19.07
  7. Использование эмулятора QEMU

1) Обзор платы YB-628

Итак, перед нами плата от повербанка YOOBAO YB-628. На ней это не написано, но в недрах родной прошивки имеется такая информация. К плате продавцом не предоставляется никакой информации, к счастью, в комментарии на али один из покупателей выложил распиновку модуля:

Здесь написана модель YB-658. Возможно в одном лоте продаются платы от разных моделей, и они могут быть с разными характеристиками. В частности на esp8266.ru выкладывали такой лог:

Здесь и флешка другая и оперативки всего 16 МБ, что на мой взгляд делает ее непригодной для использования. Но вернемся к распиновке платы:


Фото покупателя с али

Спустя полтора года, тот же покупатель добавил полную распиновку штыревого коннектора:


Фото покупателя с али

Штыревой коннектор имеет шаг два(!) миллиметра, поэтому не следует рассчитывать, что плату можно будет поставить в макетку.


Вид сверху

Плата имеет на борту флеш-память 8 МБ на чипе MX25L6406E с питанием 3.3 вольт, SDRAM память 32 МБ на чипе EtronTech EM63A165TS-6G, процессор Ralink RT5350F с архитектурой MISP 24KEc работает на частоте 360 МГц, поддерживается WiFi версии IEEE 802.11n с частотой 2.4 Ггц и пропускной способностью ДО(ключевое слово) 150 Мбит/с (теоретически, т.к. из-за керамической антены связь так себе).

Компоновка элементов на плате следующая:


Вид сверху

Есть пара нюансов. Первое - это использование медленной SDRAM памяти, она работает на частоте 133 МГц. Лично для меня это не критично, но компьютер с SDRAM памятью я покупал 25(!) лет назад. Второе - чип RT5350F очень прилично греется. Пирометром я замерил температуру в 59 градуса, и по ощущениям как-то так и есть (палец не держит). Впоследствии я поставил на чип процессора небольшой радиатор, температура опустилась до 49 градусов:

Я замерил ток потребления устройства, оно вышло на уровне 0.25A. Для сравнения, не менее древный Orange Pi Zero с 4-х ядерным 1.2 ГГц процессором Allwinner H2 потребляет 0.2 А и греется совсем чуть-чуть.

На 4pda я нашел пост с фотографиями внутренностей повербанка. В сообщении указано, что это повербанк именно YB-628, и изнутри он выглядит следующим образом:


Фото с сайта 4pda

На фото видно, что флешка другая winbond, а чип оперативки тот же EM63A165TS-6G. Если мы захотим вывести разъем USB и Ethernet, то придется воссоздать по фото нижнюю плату:


Фото с сайта 4pda

Чип RT5350F выполнен в корпусе TFBGA192B, имеет размер 12 на 12 миллиметров, и 14х14 = 192 контактных площадок. Нумерация идёт от ключа:


из даташита

Соответственно при виде сверху нумерация контактных площадок будет следующая:

Пины обозначаются как: A1, B3, N7, G10 и т.д. В интернете я нашел фото платы HAME MPR-A1 со снятым чипом:

Здесь в центре можно увидеть регион земли(выделено желтым), а справа сгруппированы контактные площадки ведующие на чип SDRAM.

Я взял распиновку процессора и цветом выделил контактные площадки: питание (серые), Ethernet (желтые), SDRAM (бирюзовый)

Что нами остается в сухом остатке? Интерфейсы: USB, JTAG, один SPI в котором есть CS0 и CS1, возможно для переключения на резервную флешку, два UART, один I2C, один GPIO. Есть еще несколько пинов которые можно использовать как GPIO, в частности RIN и DSR_N, это часть UART интерфейса, но даже если они не обрезаны, их следует еще обнаружить.

В заключение приведу схему RT53350F из даташита:

Скажем так, в 2025 году все эти характеристики не сильно впечатляют, но я и не гнался за топовым железом. В принципе, мое совпадает со следующим комментартем из обсуждения VoCore, первая версия которого была как раз на RT5350F:

2) Снятие дампа стоковой прошивки

UART здесь работает на скорости 57600, и подключившись через UART-USB конвертор, я получил длинный лог, который можно открыть под сройлером:


U-Boot 1.1.3 (Nov  6 2012 - 19:35:17)

Board: Ralink APSoC DRAM:  32 MB
relocate_code Pointer at: 81fb4000
spi_wait_nsec: 42
spi device id: c2 20 17 c2 20 (2017c220)
find flash: MX25L6405D
raspi_read: from:30000 len:1000
.*** Warning - bad CRC, using default environment

============================================
Ralink UBoot Version: 3.6.0.0
--------------------------------------------
ASIC 5350_MP (Port5<->None)
DRAM_CONF_FROM: Boot-Strapping
DRAM_TYPE: SDRAM
DRAM_SIZE: 256 Mbits
DRAM_WIDTH: 16 bits
DRAM_TOTAL_WIDTH: 16 bits
TOTAL_MEMORY_SIZE: 32 MBytes
Flash component: SPI Flash
Date:Nov  6 2012  Time:19:35:17
============================================
icache: sets:256, ways:4, linesz:32 ,total:32768
dcache: sets:128, ways:4, linesz:32 ,total:16384

 ##### The CPU freq = 360 MHZ ####
 estimate memory size =32 Mbytes

Please choose the operation:
   1: Load system code to SDRAM via TFTP.
   2: Load system code then write to Flash via TFTP.
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.                                                                                                              0


============================================================

3: System Boot system code via Flash.
## Booting image at bc050000 ...
raspi_read: from:50000 len:40
.   Image Name:   Linux Kernel Image
   Created:      2014-02-18   2:16:14 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Dat


3: System Boot system code via Flash.
## Booting image at bc050000 ...
raspi_read: from:50000 len:40
.   Image Name:   Linux Kernel Image
   Created:      2014-02-18   2:16:14 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    4400875 Bytes =  4.2 MB
   Load Address: 80000000
   Entry Point:  803bd000
raspi_read: from:50040 len:4326eb
....................................................................   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 803bd000) ...
## Giving linux memsize in MB, 32

Starting kernel ...


LINUX started...

 THIS IS ASIC
Linux version 2.6.21 (root@ubuntu) (gcc version 3.4.2) #393 Mon Feb 17 19:29:18 CST 2014

 The CPU frequency set to 360 MHz
CPU revision is: 0001964c
Determined physical RAM map:
 memory: 02000000 @ 00000000 (usable)
Built 1 zonelists.  Total pages: 8128
Kernel command line: console=ttyS1,57600n8 root=/dev/mtdblock5
Primary instruction cache 32kB, physically tagged, 4-way, linesize 32 bytes.
Primary data cache 16kB, 4-way, linesize 32 bytes.
Synthesized TLB refill handler (20 instructions).
Synthesized TLB load handler fastpath (32 instructions).
Synthesized TLB store handler fastpath (32 instructions).
Synthesized TLB modify handler fastpath (31 instructions).
Cache parity protection disabled
cause = 4080805c, status = 11000000
PID hash table entries: 128 (order: 7, 512 bytes)
calculating r4koff... 0015f900(1440000)
CPU frequency 360.00 MHz
Using 0.050 MHz high precision timer.
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 28440k/32768k available (3065k kernel code, 4328k reserved, 758k data, 112k init, 0k highmem)
Mount-cache hash table entries: 512
NET: Registered protocol family 16
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
Time: MIPS clocksource has been installed.
proc_init_hx_interface
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
deice id : c2 20 17 c2 20 (2017c220)
MX25L6405D(c2 2017c220) (8192 Kbytes)
mtd .name = raspi, .size = 0x00800000 (8M) .erasesize = 0x00010000 (64K) .numeraseregions = 0
Creating 7 MTD partitions on "raspi":
0x00000000-0x00800000 : "ALL"
0x00000000-0x00020000 : "Bootloader"
0x00020000-0x00040000 : "Config"
0x00040000-0x00050000 : "Factory"
0x00050000-0x0018372b : "Kernel"
mtd: partition "Kernel" doesn't end on an erase block -- force read-only
0x0018372b-0x00800000 : "RootFS"
mtd: partition "RootFS" doesn't start on an erase block boundary -- force read-only
0x00050000-0x00800000 : "Kernel_RootFS"
RT3xxx EHCI/OHCI init.
squashfs: version 3.2-r2 (2007/01/15) Phillip Lougher
squashfs: LZMA suppport for slax.org by jro
NTFS driver 2.1.28 [Flags: R/W].
fuse init (API version 7.8)
io scheduler noop registered (default)
++++++++++++gpio11+++++++++++Ralink gpio driver initialized
HDLC line discipline: version $Revision: 1.1.1.1 $, maxframe=4096
N_HDLC line discipline registered.
Serial: 8250/16550 driver $Revision: 1.8 $ 2 ports, IRQ sharing disabled
serial8250: ttyS0 at I/O 0xb0000500 (irq = 37) is a 16550A
serial8250: ttyS1 at I/O 0xb0000c00 (irq = 12) is a 16550A
loop: loaded (max 8 devices)
usbcore: registered new interface driver ub
rdm_major = 253

eth2 mii.o query= phy_id:0, address:1 retval:7849
Ralink APSoC Ethernet Driver Initilization. v2.1  256 rx/tx descriptors allocated, mtu = 1500!
MAC_ADRH -- : 0x0000000c
MAC_ADRL -- : 0x05076ce4
PROC INIT OK!
PPP generic driver version 2.4.2
PPP BSD Compression module registered
NET: Registered protocol family 24


=== pAd = c0019000, size = 474896 ===

<-- RTMPAllocAdapterBlock, Status=0
block2mtd: version $Revision: 1.1.1.1 $
rt3xxx-ehci rt3xxx-ehci: Ralink EHCI Host Controller
rt3xxx-ehci rt3xxx-ehci: new USB bus registered, assigned bus number 1
rt3xxx-ehci rt3xxx-ehci: irq 18, io mem 0x101c0000
rt3xxx-ehci rt3xxx-ehci: USB 0.0 started, EHCI 1.00, driver 10 Dec 2004
call_usermodehelper:  /usr/sbin/usb_link_change up
usb usb1: Product: Ralink EHCI Host Controller
usb usb1: Manufacturer: Linux 2.6.21 ehci_hcd
usb usb1: SerialNumber: rt3xxx
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
rt3xxx-ohci rt3xxx-ohci: RT3xxx OHCI Controller
rt3xxx-ohci rt3xxx-ohci: new USB bus registered, assigned bus number 2
rt3xxx-ohci rt3xxx-ohci: irq 18, io mem 0x101c1000
call_usermodehelper:  /usr/sbin/usb_link_change up
usb usb2: Product: RT3xxx OHCI Controller
usb usb2: Manufacturer: Linux 2.6.21 ohci_hcd
usb usb2: SerialNumber: rt3xxx-ohci
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
usbcore: registered new interface driver cdc_acm
drivers/usb/class/cdc-acm.c: v0.25:USB Abstract Control Model driver for USB modems and ISDN adapters
usbcore: registered new interface driver libusual
usbcore: registered new interface driver usbserial
drivers/usb/serial/usb-serial.c: USB Serial Driver core
drivers/usb/serial/usb-serial.c: USB Serial support registered for GSM modem (1-port)
usbcore: registered new interface driver option
drivers/usb/serial/option.c: USB Driver for GSM modems: Macroinfo: v0.7.1
drivers/usb/serial/usb-serial.c: USB Serial support registered for Sierra USB modem (1 port)
drivers/usb/serial/usb-serial.c: USB Serial support registered for Sierra USB modem (3 port)
usbcore: registered new interface driver sierra
drivers/usb/serial/sierra.c: USB Driver for Sierra Wireless USB modems: v.1.0.6
hso: drivers/usb/serial/hso.c: 1.6.1-Option Option Wireless Macroinfo
usbcore: registered new interface driver hso
nf_conntrack version 0.5.0 (256 buckets, 2048 max)
ip_tables: (C) 2000-2006 Netfilter Core Team, Type=Restricted Cone
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>
All bugs added by David S. Miller <davem@redhat.com>
VFS: Mounted root (squashfs filesystem) readonly.
Freeing unused kernel memory: 112k freed
init started: BusyBox v1.12.1 (2014-02-13 16:28:03 CST)
starting pid 640, tty '': '/etc_ro/rcS'
Algorithmics/MIPS FPU Emulator v1.5
devpts: called with bogus options
Welcome to
 ____     _____  _______   _______   _______   ________   __   ____   _   ________   ________
|     \  /     ||   __  | |  _____| |  ___  \ |  ___   | |__| |    \ | | |   _____| |  ___   |
|  |\  \/  /|  ||  |__| | |  |      | |___| | |  |  |  |  __  |     \| | |  |_____  |  |  |  |
|  | \    / |  ||   _   | |  |____  |   _   / |  |__|  | |  | | |\     | |   _____| |  |__|  |
|__|  \__/  |__||__| |__| |_______| |__| \__\ |________| |__| |_| \____| |__|       |________|

                                         www.macroinfo.com.cn

2860:yuxw  wapi:yuxw
rm: cannot remove '/var/run/2860_config': No such file or directory
crc = a617a30b
rm: cannot remove '/var/run/wapi_config': No such file or directory
crc = a617a30b
nothing to do
mknod: /dev/nvram: File exists
cat: can't open '/var/run/TestMode': No such file or directory
Start ssid modify, default SSID is YOOBAO_
Ver1: YB_3.0 Ver2: YB_3.0
<daemon.c> at 130, in main()
<daemon.c> at 191, in main()
starting pid 783, tty '/dev/ttyS1': '/bin/login'
(none) login: ssid = YOOBAO_
in internet.sh -----------------start
###########################################
############internet.sh start##############
############00:00:08######
############internet.sh start##############
###########################################
Password for 'hongxun' changed
Password for 'admin' changed
ssid = YOOBAO_
ls: /dev/sd*: No such file or directory
ls: /dev/ttyACM*: No such file or directory
ls: /dev/ttyUSB*: No such file or directory
ssid = YOOBAO_
rmmod: ralink_wdt: No such file or directory
rmmod: cls: No such file or directory
rmmod: hw_nat: No such file or directory
rmmod: raeth: No such file or directory
insmod: bridge.ko: module not found
insmod: mii.ko: module not found
insmod: raeth.ko: module not found

phy_tx_ring = 0x01937000, tx_ring = 0xa1937000

phy_rx_ring0 = 0x01938000, rx_ring0 = 0xa1938000
MAC_ADRH -- : 0x0000000c
MAC_ADRL -- : 0x05076ce4
RT305x_ESW: Link Status Changed
esw_link_status_changed_event_set entered
esw_link_status_changed_cb entered
call_usermodehelper:  /usr/sbin/eth_state_check down

##### disable 1st wireless interface #####
rmmod: rt2860v2_ap_net: No such file or directory
rmmod: rt2860v2_ap: No such file or directory
rmmod: rt2860v2_ap_util: No such file or directory
rmmod: rt2860v2_sta_net: No such file or directory
rmmod: rt2860v2_sta: No such file or directory
rmmod: rt2860v2_sta_util: No such file or directory
+++++++++++ Channel = 1insmod: rt2860v2_ap_util.ko: module not found
insmod: rt2860v2_ap.ko: module not found
insmod: rt2860v2_ap_net.ko: module not found
/sbin/internet.sh: line 420: vpn-passthru.sh: not found
br0-IP:192.168.89.1

RX DESC a1961000  size = 2048
<-- RTMPAllocTxRxRingMemory, Status=0
Key1Str is Invalid key length(0) or Type(0)
Key2Str is Invalid key length(0) or Type(0)
Key3Str is Invalid key length(0) or Type(0)
Key4Str is Invalid key length(0) or Type(0)
2a:0d:84:fc:10:36:fa:6b:62:39:15:fb:2f:7a:46:c3:
6f:59:87:f4:32:fc:9d:c5:14:aa:01:5d:16:d0:3a:73:

I/F(apcli0) Key1Str is Invalid key length!
1. Phy Mode = 9
2. Phy Mode = 9
TXALC> bInternalTxALC = 0
3. Phy Mode = 9
NICInitAsicFromEEPROM: pAd->TxPowerCtrl.bInternalTxALC = 0
MCS Set = ff 00 00 00 00
Main bssid = 00:0c:05:07:6c:e6
<==== rt28xx_init, Status=0
0x1300 = 00064380
vconfig: ioctl error for rem: Invalid argument
vconfig: ioctl error for rem: Invalid argument
ssid = YOOBAO_6CE6
rmmod: 8021q: No such file or directory
insmod: 8021q.ko: module not found
--- WiFi SSID is:YOOBAO_6CE6
Set ssid to feel1945 by nvram.
eth2.2: Setting MAC address to  00 0c 05 07 6c e3.
device eth2 entered promiscuous mode
VLAN (eth2.2):  Setting underlying device (eth2) to promiscious mode.
ifconfig: ioctl 0x8913 failed: No such device
brctl: bridge br0: No such device or address
iptables v1.4.0rc1: can't initialize iptables table `mangle': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
##### config Ralink ESW vlan partition (WLLLL) #####
done.
device ra0 entered promiscuous mode

eth2 mii.o query= phy_id:1, address:4 retval:5e1

eth2 mii.o query= phy_id:1, address:0 retval:3900

eth2 mii.o query= phy_id:1, address:5 retval:0
eth2.1: dev_set_promiscuity(master, 1)
device eth2.1 entered promiscuous mode
WAN is WiFi
brctl: bridge br0: Invalid argument
br0: port 2(eth2.1) entering learning state
br0: port 1(ra0) entering learning state
ifconfig: ioctl 0x8914 failed: Cannot assign requested address
ifconfig: ioctl 0x8914 failed: Cannot assign requested address
/sbin/lan.sh: line 63: hostname: not found
br0: topology change detected, propagating
br0: port 2(eth2.1) entering forwarding state
br0: topology change detected, propagating
br0: port 1(ra0) entering forwarding state
killall: udhcpd: no process killed
Port0 is up. Skip.
ifconfig: ioctl 0x8913 failed: No such device
/sbin/lan.sh: line 163: can't create /proc/sys/net/ipv6/conf/all/forwarding: nonexistent directory
brctl: bridge br0: Device or resource busy

eth2 mii.o query= phy_id:1, address:4 retval:5e1

eth2 mii.o query= phy_id:1, address:0 retval:3900

eth2 mii.o query= phy_id:1, address:5 retval:0
eth2.2: dev_set_promiscuity(master, 1)
device eth2.2 entered promiscuous mode
br0: port 3(eth2.2) entering learning state
udhcpc (v1.12.1) started
in internet.sh -----------------end
###########################################
############internet.sh end##############
############00:00:23######
############internet.sh end##############
###########################################
br0: topology change detected, propagating
br0: port 3(eth2.2) entering forwarding state
sh: /bin/super_dmz: not found
sh: ntp.sh: not found
sh: ddns.sh: not found
cat: can't open '/var/run/wscd.pid.ra0': No such file or directory
kill: you need to specify whom to kill
webs: Listening for HTTP requests at address 192.168.89.1
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
killall: ushare: no process killed

Наиболее интерсными мне показались следующие строки:

find flash: MX25L6405D

На корпусе флешки была иная маркировка, а именно - MX25L6406E. Далее разметка флешки:

deice id : c2 20 17 c2 20 (2017c220)
MX25L6405D(c2 2017c220) (8192 Kbytes)
mtd .name = raspi, .size = 0x00800000 (8M) .erasesize = 0x00010000 (64K) .numeraseregions = 0
Creating 7 MTD partitions on "raspi":
0x00000000-0x00800000 : "ALL"
0x00000000-0x00020000 : "Bootloader"
0x00020000-0x00040000 : "Config"
0x00040000-0x00050000 : "Factory"
0x00050000-0x0018372b : "Kernel"
mtd: partition "Kernel" doesn't end on an erase block -- force read-only
0x0018372b-0x00800000 : "RootFS"
mtd: partition "RootFS" doesn't start on an erase block boundary -- force read-only
0x00050000-0x00800000 : "Kernel_RootFS"

И самое интригующее:

Password for 'hongxun' changed
Password for 'admin' changed
...
--- WiFi SSID is:YOOBAO_6CE6
Set ssid to feel1945 by nvram

После загрузки системы появляется запароленная точка доступа "feel1945", для логина через UART также требовался логин и пароль, которого у меня не было. Типовые пары вроде admin/admin не подходили. Но ведь чуда никто не ждал?

Таким образом у меня была плата к которой у меня не было доступа. На самом деле меня не интерсовала родная прошивка и получение к ней доступа, вместо нее я хотел поставить OpenWRT. В самом начале загрузки появлется меню загрузчика U-Boot:

Please choose the operation:
   1: Load system code to SDRAM via TFTP.
   2: Load system code then write to Flash via TFTP.
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP. 

Т.к. на плате не было Ethernet порта, вариант с прошивкой по TFTP отпадал. Да и это было бесполезно, на нажатии клавиши "2", сразу выкидывало на загрузку с флешки, но если успеть нажать цифру 4, то попадашь в командный интерфейс U-Boot. Единственное интересное, что я смог там сделать - вытащить переменные окружения:

RT5350 # printenv
bootcmd=tftp
bootdelay=1
baudrate=57600
ethaddr="00:AA:BB:CC:DD:10"
ipaddr=10.10.10.123
serverip=10.10.10.3
ramargs=setenv bootargs root=/dev/ram rw
addip=setenv bootargs $(bootargs) ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):$(netdev):off
addmisc=setenv bootargs $(bootargs) console=ttyS0,$(baudrate) ethaddr=$(ethaddr) panic=1
flash_self=run ramargs addip addmisc;bootm $(kernel_addr) $(ramdisk_addr)
kernel_addr=BFC40000
u-boot=u-boot.bin
load=tftp 8A100000 $(u-boot)
u_b=protect off 1:0-1;era 1:0-1;cp.b 8A100000 BC400000 $(filesize)
loadfs=tftp 8A100000 root.cramfs
u_fs=era bc540000 bc83ffff;cp.b 8A100000 BC540000 $(filesize)
test_tftp=tftp 8A100000 root.cramfs;run test_tftp
stdin=serial
stdout=serial
stderr=serial
ethact=Eth0 (10/100-M)

Environment size: 765/4092 bytes
=============================================================================

Ничего более интересного я там не нашел. Для перепрошивки флешки я приобрел программатор CH341A с прищепкой:

Странная конечно штука. На обратной стороне платы написано CH341A, а на чипе имеется маркировка CH341B Софт на эту плату заявлется как для Linux так и для Windows, но версия для Linux умеет работать всего с десятком микросхем, поэтому не оставалось другого выхода, кроме как установить программу для Windows. На Windows XP SP3 в Virtual Box потребовалось лишь распаковать архив, пробросить USB-устройство в виртуалку и установить драйвер, который нашелся в том же архиве. Программу скачивал с 4пда, если вдруг у кого-то нет там регистрации, то вот альтернативная ссылка.

Внутри архива имеется pdf-файл, в котором русским языком очень подробно описано, что куда каким концом вставлять. Очень рекомендую почитать.

Относительно подключения прищепкой программатора к чипу нет однозначных мнений. Нужно осознавать, что подавая питание на флешку вы подаете питание на остальную схему, запускаете процессор, который тут же начинает с флешки что-то читать и возможно даже записывать. Но отпаять флешку будет очень сложно, там бессвинцовый припой, который паяеется только высокой температурой. Плата многослойная, дорожки тоньше бумаги. Сдувать феном тоже сложно, рядом группа резисторов без всякого обозначения, сумеете вы сдунуть флешку не захватив резисторы? Перерезать дорожку питания на плате тоже не выйдет, она идет под самой микросхемой.

Поэтому я просто зацепил прищепкой флешку и попытался считать прошивку. Прищепка довольно хлипкая, ее постоянно перекашивает, поэтому нужно хорошо убедиться, что она ровно стоит с той и другой стороны. Чтение флешки занимает минут пять, запись примерно 15 мин. В это время чип процессора RT5350F будет греться как утюг, это нормально, хотя в первый раз я подумал, что там КЗ и процессор оправился прямой дорогой к радиолампам.

Контроль установки прищепки осуществляется визуально. Под спойлером фотографии, как должен выглядеть контакт прищепки с флешкой, но у меня было кучу раз, когда все выглядело идеально, но коннекта не было:



Далее подключаем программатор к компьютеру, пробрасываем его в виртуалку, запускаем флешер. Если драйвера установились корректно, то флешер должен выдать статус "подключено" для программатора:

Дальше жмем кнопку "Детект", после чего доложно появиться окно со списком чипов для выбора, в котором нужно выбрать свой:

После чего в левой области должна появиться информация чипе:

Если окошко с выбором чипа не появилось, или в окне информации какие-то странные нули или окно появилось, но чтении/записи/стирании оно исчезло, или чтение/запись идут чересчур медленно - значит у вас плохое соединение прищепки с флешкой. Снимайте прищепку, и цепляйтесь заново. Очень советую, отключать при это этом питание программатора, т.е. вытаскивать его из USB-порта.

После установления контакта с флешкой следует нажать на кнопку "Читать", запустится процесс снятия дампа прошивки:

Чтение займет минут пять после чего дамп можно будет сохранить в виде бинарного файла.

При считывании дампа, я выбирал версии флешки mx25l6405d(как было в логе) и mx25l6406e(как было написано на самой флешке) получилось одинаково, но немного разная длина файлов. Впоследствии я стирал флешку и записывал полученные дампы обратно на устройство, и плата нормально стартовала. Скачать полученные дампы можно по следующей ссылке.

После того, как я снял дамп прошивки, с одной стороны была некая надежда найти в ней какие-то действующие логины и пароли, с другой стороны хотелось посмотреть, что это за устройство внутри.

В сети есть статьи как с помощью binwalk можно легко распаковать образы прошивок роутеров. "Почему бы и мне тоже не попробовать?" - подумал я. В Linux Mint из репозитория установился binwalk версии 2.3.3:

$ binwalk  --help |head -n2

Binwalk v2.3.3

Смотрим что у нас есть:

$ binwalk  ./mx25l6406e.bin 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             uImage header, header size: 64 bytes, header CRC: 0xE8F78683, created: 2012-11-07 03:35:21, image size: 106920 bytes, Data Address: 0x80200000, Entry Point: 0x80200000, data CRC: 0xE3ED2483, OS: Linux, CPU: MIPS, image type: Standalone Program, compression type: none, image name: "SPI Flash Image"

87344         0x15530         U-Boot version string, "U-Boot 1.1.3 (Nov  6 2012 - 19:35:17)"
87936         0x15780         CRC32 polynomial table, little endian
327680        0x50000         uImage header, header size: 64 bytes, header CRC: 0x8E14B211, created: 2014-02-18 02:16:14, image size: 4400875 bytes, Data Address: 0x80000000, Entry Point: 0x803BD000, data CRC: 0xEE673138, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "Linux Kernel Image"

327744        0x50040         LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4031052 bytes
1586987       0x18372B        Squashfs filesystem, little endian, non-standard signature, version 3.0, size: 3137746 bytes, 650 inodes, blocksize: 65536 bytes, created: 2014-02-18 02:16:04

Возможно так будет более понятно:

Как часто это бывает, тут есть две новости: одна хорошая, а другая не очень. Хорошая новость заключается в том, что я успешно снял дамп прошивки. Впоследствии я проверил это на практике, записав дамп обратно на флешку, и "раскирпичил" его. Новость не очень кроется в этой строке:

Squashfs filesystem, little endian, non-standard signature, version 3.0, size: 3137746 bytes, 650 inodes, 

SquashFS - это сжатая файловая система, которая работает только для чтения, и она поддерживает несколько типов сжатия. Запустите в консоли команду "mksquashfs -h" и там вам все расскажут. Строка "non-standard signature" означает, что используется нестандартное сжатие. Возможно, просто Magic number потерт, а возможно, что алгоритм модифицировали, или возможно binwalk некорректно определил заголовок.

Если посмотреть на структуру прошивки, то она состоит из нескольких блоков:

В принципе, было не обязательно пользоваться Binwalk, т.к. структуру флешки мы уже узнали из лога загрузки:

deice id : c2 20 17 c2 20 (2017c220)
MX25L6405D(c2 2017c220) (8192 Kbytes)
mtd .name = raspi, .size = 0x00800000 (8M) .erasesize = 0x00010000 (64K) .numeraseregions = 0
Creating 7 MTD partitions on "raspi":
0x00000000-0x00800000 : "ALL"
0x00000000-0x00020000 : "Bootloader"
0x00020000-0x00040000 : "Config"
0x00040000-0x00050000 : "Factory"
0x00050000-0x0018372b : "Kernel"
mtd: partition "Kernel" doesn't end on an erase block -- force read-only
0x0018372b-0x00800000 : "RootFS"
mtd: partition "RootFS" doesn't start on an erase block boundary -- force read-only
0x00050000-0x00800000 : "Kernel_RootFS"

И насколько понимаю, раздел "Config" - это NVRAM, где хранятся все пользовательские настройки, включая пароли. Судите сами:

$ dd if=./mx25l6406e.bin of=./config.bin bs=1 skip=$((0x20000)) count=$((0x20000))

Здесь хранится SSID точки доступа на которую переименовали с дефолтной YOOBAO_

$ strings ./config.bin |grep "feel1945"
SSID1=feel1945
SSID1=feel1945

А вот и искомый пароль от ви-фи (на самом деле это не он, читайте дальше):

$ strings ./config.bin |grep "WiFiKey"
WiFiKey=N0d7c7MZN#0549WlEJoO1#

Я не проверял пароль, потому-что когда достал его из прошивки, моя плата уже была прошита в OpenWRT, и пароль от старой прошивки мне был уже не нужен.

Следующий раздел "Factory" это заводские настройки WiFi части, впоследствии они нам пригодятся. Ну а дальше, с адреса 0x50000 = 327680 начинается сама прошивка, т.е. ядро + файловая система.

Все это я это говорю к тому, что нельзя взять прошивку openwrt на роутер с аналогичными характеристиками и прошить ею нашу плату, т.к. в результате получите кирпич.

Вот например еще один повербанк - 7Links-PX-4885 с аналогичными характеристиками:

На сайте openwrt имеется прошивка для варианта с 8МБ флешкой - px-4885-8M-squashfs-sysupgrade.bin

Но если мы на нее посмотрим с помощью binwalk:

То можно видеть, что здесь нет загрузчика U-Boot. Т.е. это прошивка для прошивки из openwrt.

Таким образом, на этом этапе перед мною встала задача поиска прошивки OpenWRT для платы с там же процессором, флешкой и размером памяти и еще с загрузчиком U-Boot. О том, что можно взять загрузчик от родной прошивки и "легким движением руки" добавить к нему OpenWRT, я тогда еще не знал.

Но давайте вернемся к нашему дампу. Версия binwalk мне показалась подозрительно древней и я решил зайти на сайт binwalk что бы убедиться, что у меня именно последняя версия. Тут мне повезло, на сайте был анонсирован Binwalk V3 и там же приводились инструкции по сборке свежей версии. Процесс занял минут пять - десять, и вот я уже тыкаю в прошивку свежей версией Binwalk:

На первый взгляд удручающее мало информации. Тогда я запускаю binwalk с ключем "-Me" и происходит чудо:

Binwalk распаковал файловую систему прошивки. Это было здорово, хотя пароли я таким образом не получил т.к. все они хранились в NVRAM, которую я расковырял уже после того как поставил на плату OpenWRT. И к тому же, родная прошивка вряд ли дала бы мне прошить устройство в OpenWrt. Но если кому интересно, как там все устроено, я выложил распакованные прошивки вместе с дампом, скачать можно по ссылке

Из интересного например, удалось найти дефолтную парольную пару:

default username hongxun with password wuzhun2012

Вторая пара это "admin/admin"

Кроме того, в скриптах было однозначно написано, это устройством явлется модель повербанка YB-628.

3) Прошивка в OpenWRT 15.05

Поиски прошивки OpenWRT c U-Boot для RT5350F привели меня опять на али:

OlinuXINO - это продукт болгарской компании Olimex. На RT5350F они делали процессорный модуль, это была многослойная плата только со штыревыми коннекторами. И отдельно шла обычная двухслойная плата расширения с всеми разъемами. Сделать полнофункциональный модуль как LinkIt Smart 7688, где есть usb и SD и коннектор питания, они видимо не смогли, или не захотели. Модуль был с 8 МБ флешкой и 32 МБ оперативки, НО(!) кварц там 20МГц, а на нашей плате 40Мгц. И в результате перепрошивки выяснилось, что это не мешает работать процессору, но WiFi не работает. Проблема описана здесь, но немного под другим углом:

На самом деле настройки радиочасти хранятся не в "Config" разделе, а в "Factory" (возможно это только в нашем случае).

Чтобы решить проблему, возьмем секции: "загрузчик + config+ factory" от родной прошивки, а ядро и OpenWRT от прошивки олимекс:

По следующей ссылке: https://github.com/OLIMEX/OLINUXINO/tree/master/SOFTWARE/RT5350F/Prebuilt%20images/old качаем прошивку (альтернативная ссылка):

$  wget https://github.com/OLIMEX/OLINUXINO/raw/refs/heads/master/SOFTWARE/RT5350F/Prebuilt%20images/old/uboot+factory+openwrt.bin

проверяем:

Далее готовим наш бутерброд:

$ dd if=./mx25l6406e.bin of=./uboot.bin bs=1 count=$((0x50000))
$ dd if=./uboot+factory+openwrt.bin of=./openwrt.bin bs=1 skip=$((0x50000))
$ cat uboot.bin openwrt.bin > /tmp/yb-628-openwrt-15.5-8M-32M.bin

Пословица "семь раз отмерь, один раз отрежь" как раз для нашего случая. Проверяем результат:

Готовую прошивку можно скачать по ссылке: yb-628-openwrt-15.5-8M-32M.bin

Теперь нам предстоит непростая процедура записи прошивки на флешку. Идея прошивки флешки на работающем устройстве так себе, но в данном случае нет выбора, и у меня выработалась стратегия как надо делать, дабы не потратить на это кучу времени. хотя она и не 100-процентно рабочая.

1. Вначале чип стирается, занимает это 30 секунд:

После этого нужно чип проверить. Для этого щелкаем "Заполнить" буфер, в открывшимся окошке ничего не меняем, щелкаем OK:

После чего нажимаем "проверить". Занимает это 5 минут:

Затем открываем файл с прошивкой и жмем "Записать". Запись занимает 15 минут. После записи автоматически запустится проверка, это еще 5 минут. Итого 20 минут:

Хочу сказать, что есть прошивки которые нормально заливаются таким способом: это дам оригинальной прошивки и yb-628-openwrt-15.5-8M-32M.bin, но вот прошивки от прошивки от HLK-RM04 вставали только на выпаяную флешку, иначе никак.

Если все получилось, убираем программатор в сторону, UART'ом подключаемся к плате, скорость 57600, должен пойти лог загрузки (под спойлером). Если не получилось, значит плохой контакт прищепки с флешкой.

U-Boot 1.1.3 (Nov  6 2012 - 19:35:17)

Board: Ralink APSoC DRAM:  32 MB
relocate_code Pointer at: 81fb4000
spi_wait_nsec: 42
spi device id: c2 20 17 c2 20 (2017c220)
find flash: MX25L6405D
raspi_read: from:30000 len:1000
.*** Warning - bad CRC, using default environment

============================================
Ralink UBoot Version: 3.6.0.0
--------------------------------------------
ASIC 5350_MP (Port5<->None)
DRAM_CONF_FROM: Boot-Strapping
DRAM_TYPE: SDRAM
DRAM_SIZE: 256 Mbits
DRAM_WIDTH: 16 bits
DRAM_TOTAL_WIDTH: 16 bits
TOTAL_MEMORY_SIZE: 32 MBytes
Flash component: SPI Flash
Date:Nov  6 2012  Time:19:35:17
============================================
icache: sets:256, ways:4, linesz:32 ,total:32768
dcache: sets:128, ways:4, linesz:32 ,total:16384

 ##### The CPU freq = 360 MHZ ####
 estimate memory size =32 Mbytes

Please choose the operation:
   1: Load system code to SDRAM via TFTP.
   2: Load system code then write to Flash via TFTP.
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.                                                                                                                                                 0

3: System Boot system code via Flash.
## Booting image at bc050000 ...
raspi_read: from:50000 len:40
.   Image Name:   MIPS OpenWrt Linux-3.18.17
   Created:      2015-07-06  11:07:52 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    1075901 Bytes =  1 MB
   Load Address: 80000000
   Entry Point:  80000000
raspi_read: from:50040 len:106abd
.................   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 80000000) ...
## Giving linux memsize in MB, 32

Starting kernel ...

[    0.000000] Linux version 3.18.17 (stefan@debian) (gcc version 4.6.4 (OpenWrt/Linaro GCC 4.6-2013.05 r46191) ) #16 Mon Jul 6 14:06:59 EEST 2015
[    0.000000] SoC Type: Ralink RT5350 id:1 rev:3
[    0.000000] bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 0001964c (MIPS 24KEc)
[    0.000000] MIPS: machine is RT5350F-OLINUXINO
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 02000000 @ 00000000 (usable)
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x00000000-0x01ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00000000-0x01ffffff]
[    0.000000] Initmem setup node 0 [mem 0x00000000-0x01ffffff]
[    0.000000] Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 32 bytes
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
[    0.000000] Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2
[    0.000000] PID hash table entries: 128 (order: -3, 512 bytes)
[    0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Writing ErrCtl register=0000f0a4
[    0.000000] Readback ErrCtl register=0000f0a4
[    0.000000] Memory: 29016K/32768K available (2403K kernel code, 121K rwdata, 480K rodata, 188K init, 181K bss, 3752K reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:256
[    0.000000] CPU Clock: 360MHz
[    0.000000] systick: running - mult: 214748, shift: 32
[    0.010000] Calibrating delay loop... 239.61 BogoMIPS (lpj=1198080)
[    0.080000] pid_max: default: 32768 minimum: 301
[    0.090000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.100000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.110000] pinctrl core: initialized pinctrl subsystem
[    0.120000] NET: Registered protocol family 16
[    0.130000] rt2880-pinmux pinctrl: invalid group "rgmii" for function "gpio"
[    0.140000] rt2880-pinmux pinctrl: invalid group "mdio" for function "gpio"
[    0.180000] rt2880_gpio 10000600.gpio: registering 22 gpios
[    0.190000] rt2880_gpio 10000600.gpio: registering 22 irq handlers
[    0.200000] rt2880_gpio 10000660.gpio: registering 6 gpios
[    0.210000] rt2880_gpio 10000660.gpio: registering 6 irq handlers
[    0.220000] Switched to clocksource systick
[    0.230000] NET: Registered protocol family 2
[    0.240000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.250000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.260000] TCP: Hash tables configured (established 1024 bind 1024)
[    0.280000] TCP: reno registered
[    0.280000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.290000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.310000] NET: Registered protocol family 1
[    0.320000] rt-timer 10000100.timer: maximum frequency is 7324Hz
[    0.330000] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.360000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.370000] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.390000] msgmni has been set to 56
[    0.430000] io scheduler noop registered
[    0.440000] io scheduler deadline registered (default)
[    0.450000] drivers/phy/phy-ralink-usb.c:ralink_usb_phy_probe[147]
[    0.460000] drivers/phy/phy-ralink-usb.c:ralink_usb_phy_probe[161]
[    0.480000] gpio-export gpio_export: 3 gpio(s) exported
[    0.490000] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    0.500000] console [ttyS0] disabled
[    0.510000] 10000c00.uartlite: ttyS0 at MMIO 0x10000c00 (irq = 20, base_baud = 2500000) is a 16550A
[    0.530000] console [ttyS0] enabled
[    0.530000] console [ttyS0] enabled
[    0.540000] bootconsole [early0] disabled
[    0.540000] bootconsole [early0] disabled
[    0.570000] m25p80 spi32766.0: found mx25l6405d, expected s25fl064k
[    0.590000] m25p80 spi32766.0: mx25l6405d (8192 Kbytes)
[    0.600000] 4 ofpart partitions found on MTD device spi32766.0
[    0.610000] Creating 4 MTD partitions on "spi32766.0":
[    0.620000] 0x000000000000-0x000000030000 : "u-boot"
[    0.630000] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.640000] 0x000000040000-0x000000050000 : "factory"
[    0.660000] 0x000000050000-0x000000800000 : "firmware"
[    0.740000] 2 uimage-fw partitions found on MTD device firmware
[    0.760000] 0x000000050000-0x000000156afd : "kernel"
[    0.770000] 0x000000156afd-0x000000800000 : "rootfs"
[    0.780000] mtd: device 5 (rootfs) set to be root filesystem
[    0.790000] 1 squashfs-split partitions found on MTD device rootfs
[    0.800000] 0x000000370000-0x000000800000 : "rootfs_data"
[    0.830000] ralink_soc_eth 10100000.ethernet eth0: ralink at 0xb0100000, irq 5
[    0.840000] rt2880_wdt 10000120.watchdog: Initialized
[    0.850000] TCP: cubic registered
[    0.860000] NET: Registered protocol family 17
[    0.870000] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    0.890000] 8021q: 802.1Q VLAN Support v1.8
[    0.930000] VFS: Mounted root (squashfs filesystem) readonly on device 31:5.
[    0.940000] Freeing unused kernel memory: 188K (802f1000 - 80320000)
[    4.020000] init: Console is alive
[    4.030000] init: - watchdog -
[    8.100000] usbcore: registered new interface driver usbfs
[    8.110000] usbcore: registered new interface driver hub
[    8.120000] usbcore: registered new device driver usb
[    8.200000] SCSI subsystem initialized
[    8.220000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    8.240000] ehci-platform: EHCI generic platform driver
[    8.450000] phy phy-usbphy.0: remote usb device wakeup disabled
[    8.460000] phy phy-usbphy.0: UTMI 16bit 30MHz
[    8.470000] ehci-platform 101c0000.ehci: EHCI Host Controller
[    8.480000] ehci-platform 101c0000.ehci: new USB bus registered, assigned bus number 1
[    8.500000] ehci-platform 101c0000.ehci: irq 26, io mem 0x101c0000
[    8.530000] ehci-platform 101c0000.ehci: USB 2.0 started, EHCI 1.00
[    8.540000] hub 1-0:1.0: USB hub found
[    8.550000] hub 1-0:1.0: 1 port detected
[    8.560000] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    8.570000] ohci-platform: OHCI generic platform driver
[    8.590000] ohci-platform 101c1000.ohci: Generic Platform OHCI controller
[    8.600000] ohci-platform 101c1000.ohci: new USB bus registered, assigned bus number 2
[    8.620000] ohci-platform 101c1000.ohci: irq 26, io mem 0x101c1000
[    8.690000] hub 2-0:1.0: USB hub found
[    8.700000] hub 2-0:1.0: 1 port detected
[    8.720000] usbcore: registered new interface driver usb-storage
[    9.130000] init: - preinit -
[   10.310000] rt305x-esw 10110000.esw: link changed 0x00
[   10.640000] random: procd urandom read with 16 bits of entropy available
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[   14.440000] jffs2: notice: (321) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[   14.470000] mount_root: switching to jffs2 overlay
[   14.540000] procd: - early -
[   14.550000] procd: - watchdog -
[   15.490000] procd: - ubus -
[   16.510000] procd: - init -
Please press Enter to activate this console.
[   17.970000] NET: Registered protocol family 10
[   18.000000] ip6_tables: (C) 2000-2006 Netfilter Core Team
[   18.030000] i2c /dev entries driver
[   18.040000] i2c-ralink 10000900.i2c: loaded
[   18.060000] Loading modules backported from Linux version master-2015-03-09-0-g141f155
[   18.080000] Backport generated by backports.git backports-20150129-0-gdd4a670
[   18.100000] ip_tables: (C) 2000-2006 Netfilter Core Team
[   18.130000] nf_conntrack version 0.5.0 (456 buckets, 1824 max)
[   18.220000] xt_time: kernel timezone is -0000
[   18.280000] cfg80211: Calling CRDA to update world regulatory domain
[   18.320000] cfg80211: World regulatory domain updated:
[   18.330000] cfg80211:  DFS Master region: unset
[   18.340000] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[   18.360000] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   18.370000] cfg80211:   (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   18.390000] cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[   18.400000] cfg80211:   (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[   18.420000] cfg80211:   (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (0 s)
[   18.440000] cfg80211:   (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[   18.460000] cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[   18.470000] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[   18.590000] PPP generic driver version 2.4.2
[   18.600000] NET: Registered protocol family 24
[   18.670000] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 5350, rev 0500 detected
[   18.680000] ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 5350 detected
[   28.590000] device eth0.1 entered promiscuous mode
[   28.600000] device eth0 entered promiscuous mode
[   28.630000] br-lan: port 1(eth0.1) entered forwarding state
[   28.640000] br-lan: port 1(eth0.1) entered forwarding state
[   30.640000] br-lan: port 1(eth0.1) entered forwarding state
[   32.560000] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[   32.580000] device wlan0 entered promiscuous mode
[   32.620000] br-lan: port 2(wlan0) entered forwarding state
[   32.630000] br-lan: port 2(wlan0) entered forwarding state
[   32.640000] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[   34.630000] br-lan: port 2(wlan0) entered forwarding state



BusyBox v1.23.2 (2015-07-06 11:31:11 EEST) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 CHAOS CALMER (Bleeding Edge, r46191)
 -----------------------------------------------------
  * 1 1/2 oz Gin            Shake with a glassful
  * 1/4 oz Triple Sec       of broken ice and pour
  * 3/4 oz Lime Juice       unstrained into a goblet.
  * 1 1/2 oz Orange Juice
  * 1 tsp. Grenadine Syrup
 -----------------------------------------------------
root@RT5350F-OLinuXino:/#

4) Первичная настройка OpenWRT

Первым делом следует задать пароль рута, чтобы можно было зайти по ssh:

# passwd

LAN-интерфейс по умолчанию настроен как static-IP с адресом "192.168.1.1". Поменяйте последнюю цифру на любой другой не занятый адрес в вашей локальной сети.

# vi /etc/config/network

WiFi по умолчанию отключен, чтобы его включить подаем команду:

# uci set wireless.@wifi-device[0].disabled=0; uci commit wireless; wifi

Перезагружаемся:

# reboot

После перезагрузки должна появиться незапороленная точка доступа OpenWRT:

$ nmcli device wifi list
IN-USE  BSSID              SSID              MODE   CHAN  RATE        SIGNAL  BARS  SECURITY 
        BC:AE:C5:C5:0A:F2  Alien             Infra  1     54 Мбит/с   100     ▂▄▆█  WPA2      
*       00:0C:05:07:6C:E6  OpenWrt           Infra  11    65 Мбит/с   89      ▂▄▆█  --    
        0C:80:63:A9:5D:18  TP-Link_5D18      Infra  11    270 Мбит/с  55      ▂▄__  WPA2      
        08:C6:B3:B8:57:99  MTSRouter_118120  Infra  4     270 Мбит/с  52      ▂▄__  WPA2      
        B0:95:75:DA:A8:3A  TP-Link_A83A      Infra  11    270 Мбит/с  52      ▂▄__  WPA2      
        BC:0F:9A:05:52:F3  MTSRouter-0552F1  Infra  13    130 Мбит/с  52      ▂▄__  WPA2      
        60:E3:27:EE:9A:A6  TP-LINK_9AA6      Infra  4     270 Мбит/с  42      ▂▄__  WPA1 WPA2 
        14:CC:20:33:44:4E  Servant           Infra  6     135 Мбит/с  42      ▂▄__  WPA2      
        3A:1C:23:09:0D:DB  4G CPE 0DDB       Infra  11    65 Мбит/с   39      ▂▄__  WPA2

Если точка доступа появилось, то значит wiFi работает. На суперскую связь рассчитывать не стоит, керамическая антена все-таки.

$ ping 192.168.1.50
PING 192.168.1.50 (192.168.1.50) 56(84) bytes of data.
64 bytes from 192.168.1.50: icmp_seq=1 ttl=64 time=2.99 ms
64 bytes from 192.168.1.50: icmp_seq=2 ttl=64 time=4.26 ms
64 bytes from 192.168.1.50: icmp_seq=3 ttl=64 time=0.844 ms
64 bytes from 192.168.1.50: icmp_seq=4 ttl=64 time=104 ms
64 bytes from 192.168.1.50: icmp_seq=5 ttl=64 time=2.31 ms
64 bytes from 192.168.1.50: icmp_seq=6 ttl=64 time=110 ms
64 bytes from 192.168.1.50: icmp_seq=7 ttl=64 time=2.29 ms
64 bytes from 192.168.1.50: icmp_seq=8 ttl=64 time=0.892 ms
64 bytes from 192.168.1.50: icmp_seq=10 ttl=64 time=111 ms
64 bytes from 192.168.1.50: icmp_seq=11 ttl=64 time=109 ms
64 bytes from 192.168.1.50: icmp_seq=13 ttl=64 time=112 ms
64 bytes from 192.168.1.50: icmp_seq=14 ttl=64 time=2.29 ms
64 bytes from 192.168.1.50: icmp_seq=15 ttl=64 time=4.67 ms

Пинг в свыше 100 мс не внушает оптимизма, поэтому пока продолжаем работать через UART.

Сейчас наша задача по быстрому подключить устройство к интернету. Договоримся, что мы не будем использовать устройство в качестве роутера, это будет обычный клиент внутри локальной сети. Для этого:

1. Сохраните дефолтные конфиги "/etc/config/network" и "/etc/config/wireless" в каталоге "/root". В случае чего, сможете начать с чистого листа.

2. Конфиг "/etc/config/network" приводим к следующему виду:


config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config interface 'lan'
        option ifname 'eth0.1'
        option force_link '1'
        option macaddr '00:0c:05:07:6c:e6'
        option type 'bridge'
        option proto 'static'
        option ipaddr '192.168.100.50'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option proto 'dhcp'

config switch
        option name 'rt305x'
        option reset '1'
        option enable_vlan '0'

Здесь у нас две сетки, wan и lan, причем мы будем пользоваться wan, т.е. фактически это локалка, а вот LAN для режима работы "точка доступа (AP)" и обратите внимание - она в другой подсети 192.168.100.50. Следовало бы поменять их местами, но у меня все работает и меня это устраивает.

Конфиг "/etc/config/wireless" будет такой:


config wifi-device 'radio0'
        option type 'mac80211'
        option channel 'auto'
        option hwmode '11g'
        option path '10180000.wmac'
        option htmode 'HT20'
        option disabled '0'

config wifi-iface 'ap'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'YB-628'
        option encryption 'none'

config wifi-iface 'sta'
        option device 'radio0'
        option mode 'sta'
        option network 'wan'
        option ssid 'ВАША_ТОЧКА_ДОСТУПА'
        option encryption 'psk2' # тип шифрования ВАШЕЙ точки доступа
        option key 'ключ'

Здесь используются режимы работы sta+ap, т.е. плата в режиме sta по WiFi подключается к домашней точке доступа, через нее получает интернет, и становится доступной в локалке. Режим работы AP для возможности подключения на случай если плата "потерялась" из-за некорректных сетевых настроек. Несмотря что точка доступа безпарольная, для подключения через ssh все равно потребуется пароль. Но в целом, неплохо было бы запаролить AP, добавив строки к ее секции:

    option encryption 'psk2'
    option key 'пароль'

Далее следует отключить роутерные функции, такие как: преобразование адресов NAT и фильтрацию трафика через firewall, потому-что устройство не будет роутером, оно будет обычным клиентом в ЛВС. Для этого конфиг "/etc/config/dhcp" приводим к следующему виду:

config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option filterwin2k '0'
    option localise_queries '1'
    option rebind_protection '1'
    option rebind_localhost '1'
    option local '/lan/'
    option domain 'lan'
    option expandhosts '1'
    option nonegcache '0'
    option authoritative '0'       # Not authoritative since we're not handling DHCP
    option readethers '1'
    option leasefile '/tmp/dhcp.leases'
    option resolvfile '/tmp/resolv.conf.auto'

config dhcp 'lan'
    option interface 'lan'
    option ignore '1'             # Disable DHCP server

Далее опционально очищаем правила iptables в конфиге "/etc/config/firewall"

config defaults
    option syn_flood '0'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'

Теперь отключаем NAT

# /etc/init.d/dnsmasq disable
# /etc/init.d/dnsmasq stop

Тоже самое для файрвола:

# /etc/init.d/firewall disable
# /etc/init.d/firewall stop

После последней команды должны пойти строки вроде таких:

root@RT5350F-OLinuXino:/# /etc/init.d/firewall stop
Warning: Unable to locate ipset utility, disabling ipset support
Warning: Section @zone[1] (wan) cannot resolve device of network 'wan6'
 * Flushing IPv4 filter table
 * Flushing IPv4 nat table
 * Flushing IPv4 mangle table
 * Flushing IPv4 raw table
 * Flushing IPv6 filter table
 * Flushing IPv6 mangle table
 * Flushing IPv6 raw table
 * Flushing conntrack table ...

И последний штрих - в конфиге "/etc/config/system" можно задать hostname и свой часовой пояс. В моем случае это выглядит так:

config system
    option hostname 'lv-223'
    option conloglevel '8'
    option cronloglevel '8'
    option zonename 'Europe/Samara'
    option timezone 'SAMT-4'

config timeserver 'ntp'
    list server '0.openwrt.pool.ntp.org'
    list server '1.openwrt.pool.ntp.org'
    list server '2.openwrt.pool.ntp.org'
    list server '3.openwrt.pool.ntp.org'
    option enabled '1'

Теперь скрещиваем пальцы и перезагружаемся. Полностью загрузка системы вместе с установлением связи занимает минуту. После перезагрузки, под финиш, должны появиться такие строки:

[   60.717344] wlan0: authenticate with bc:ae:c5:c5:0a:f2
[   60.730187] wlan0: send auth to bc:ae:c5:c5:0a:f2 (try 1/3)
[   60.745413] wlan0: authenticated
[   60.759856] wlan0: associate with bc:ae:c5:c5:0a:f2 (try 1/3)
[   60.778935] wlan0: RX AssocResp from bc:ae:c5:c5:0a:f2 (capab=0x431 status=0 aid=1)
[   60.794808] wlan0: associated
[   60.828114] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[   60.867567] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0-1: link becomes ready
[   60.881990] br-lan: port 2(wlan0-1) entered blocking state
[   60.893093] br-lan: port 2(wlan0-1) entered forwarding state

Здесь нас интересуют токены: "wlan0: authenticated", "wlan0: associated", "wlan0: link becomes ready", которые означают, что устройство успешно соеденилась с точкой доступа.

Что будет означать, что устройство успешно соединилось с точкой доступа. Проверяем правила firewall:

root@RT5350F-OLinuXino:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination    

Т.е. сейчас нам будет позволено зайти на устройство из локалки. Сетевой адрес:

$ ifconfig|grep "inet addr"
          inet addr:192.168.100.50  Bcast:192.168.100.255  Mask:255.255.255.0
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet addr:192.168.1.14  Bcast:192.168.1.255  Mask:255.255.255.0

Видно, что домашний роутер дал устройству адрес "192.168.1.14".

Пингуем устройство с компьютера:

$ ping 192.168.1.14
PING 192.168.1.14 (192.168.1.14) 56(84) bytes of data.
64 bytes from 192.168.1.14: icmp_seq=1 ttl=64 time=2.10 ms
64 bytes from 192.168.1.14: icmp_seq=2 ttl=64 time=8.11 ms
64 bytes from 192.168.1.14: icmp_seq=3 ttl=64 time=1.94 ms
64 bytes from 192.168.1.14: icmp_seq=4 ttl=64 time=1.91 ms
64 bytes from 192.168.1.14: icmp_seq=5 ttl=64 time=1.72 ms
64 bytes from 192.168.1.14: icmp_seq=6 ttl=64 time=2.55 ms
64 bytes from 192.168.1.14: icmp_seq=7 ttl=64 time=3.33 ms
64 bytes from 192.168.1.14: icmp_seq=8 ttl=64 time=2.11 ms
64 bytes from 192.168.1.14: icmp_seq=9 ttl=64 time=1.73 ms
64 bytes from 192.168.1.14: icmp_seq=10 ttl=64 time=2.01 ms
64 bytes from 192.168.1.14: icmp_seq=11 ttl=64 time=2.96 ms
64 bytes from 192.168.1.14: icmp_seq=12 ttl=64 time=4.27 ms
64 bytes from 192.168.1.14: icmp_seq=13 ttl=64 time=5.18 ms
64 bytes from 192.168.1.14: icmp_seq=14 ttl=64 time=1.71 ms
^C
--- 192.168.1.14 ping statistics ---
14 packets transmitted, 14 received, 0% packet loss, time 13019ms
rtt min/avg/max/mdev = 1.710/2.972/8.110/1.745 ms

Уже не так все фатально. Посмотрим что там у нас есть:

$ nmap -sT  192.168.1.14
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-05-03 22:07 +04
Nmap scan report for 192.168.1.14
Host is up (0.0065s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 2.93 seconds

Когда пароль root не задан, вы не сможете зайти по SSH, dropbear вас не пропустит. Поэтому при сканировании портов можно будет увидет telnet, через который можно зайти без пароля и поставить пароль. После того как пароль установлен, telnet отключается и его больше не видно, как в этом случае.

В прошивке OLinuXINO нет LUCI (при самостоятельной сборки прошивки люся в комплект не водит), поэтому при сканировании нет и 80 порта.

Теперь заходим на устройство через ssh, проверяем связь с внешним миром:

Если выплюнет что-то вроде:

$ ssh root@192.168.1.14
Unable to negotiate with 192.168.1.14 port 22: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,kexguess2@matt.ucc.asn.au

То в "~/.ssh/config" вашего Linux, добавьте секцию:

Host 192.168.1.14
     KexAlgorithms +diffie-hellman-group1-sha1
     HostKeyAlgorithms +ssh-rsa
    Ciphers aes256-cbc

И проблема исчезнет. Следующий этап настройка opkg. Если попытаться им воспользоваться, то получим:

root@RT5350F-OLinuXino:~# cd /tmp
root@RT5350F-OLinuXino:/tmp# opkg update
Downloading http://downloads.openwrt.org/snapshots/trunk/ramips/rt305x/packages/base/Packages.gz.
wget: can't execute 'openssl': No such file or directory
wget: error getting response: Connection reset by peer

Проблема кроется в том, за десять лет с момента выхода "Chaos Calmer" мир перешел на шифрованный протокол https, включая репозитории OpenWrt. Потребуется вручную установить пакеты необходимые для работы opkg. Для этого заходим на репозиторий OpenWRT https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/ и в каталогах "base" и "packages" ищем и скачиваем следующие пакеты:

ca-certificates_20150426_ramips_24kec.ipk
libopenssl_1.0.2g-1_ramips_24kec.ipk
libpcre_8.38-1_ramips_24kec.ipk
libpthread_0.9.33.2-1_ramips_24kec.ipk
libpolarssl_1.3.14-1_ramips_24kec.ipk
librt_0.9.33.2-1_ramips_24kec.ipk
libustream-polarssl_2015-07-09-c2d73c22618e8ee444e8d346695eca908ecb72d3_ramips_24kec.ipk
wget_1.16.3-1_ramips_24kec.ipk
zlib_1.2.8-1_ramips_24kec.ipk

Далее запускаем mc и устанавливаем shell-соединение с одноплатником:

После чего копируем скачанные файлы в директорию "/tmp". все вместе, они весят около 1.3 МБ. На одноплатнике командой "opkg install имя_пакета" ставим пакеты с учетом зависимостей в таком порядке:

ca-certificates_20150426_ramips_24kec.ipk
libpolarssl_1.3.14-1_ramips_24kec.ipk
libustream-polarssl_2015-07-09-c2d73c22618e8ee444e8d346695eca908ecb72d3_ramips_24kec.ipk
zlib_1.2.8-1_ramips_24kec.ipk
libopenssl_1.0.2g-1_ramips_24kec.ipk
libpcre_8.38-1_ramips_24kec.ipk
libpthread_0.9.33.2-1_ramips_24kec.ipk
librt_0.9.33.2-1_ramips_24kec.ipk
wget_1.16.3-1_ramips_24kec.ipk

Пробуем что-либо скачать по https:

root@RT5350F-OLinuXino:/tmp# wget https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/Packages.gz
--2025-05-04 07:21:28--  https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/Packages.gz
Resolving archive.openwrt.org... 2001:470:2030:2::3, 81.0.124.218
Connecting to archive.openwrt.org|2001:470:2030:2::3|:443... failed: Permission denied.
Connecting to archive.openwrt.org|81.0.124.218|:443... connected.
ERROR: cannot verify archive.openwrt.org's certificate, issued by 'CN=R11,O=Let\'s Encrypt,C=US':
  Unable to locally verify the issuer's authority.
To connect to archive.openwrt.org insecurely, use `--no-check-certificate'.
root@RT5350F-OLinuXino:/tmp# wget --no-check-certificate https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/Packages.gz
--2025-05-04 07:23:05--  https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/Packages.gz
Resolving archive.openwrt.org... 2001:470:2030:2::3, 81.0.124.218
Connecting to archive.openwrt.org|2001:470:2030:2::3|:443... failed: Permission denied.
Connecting to archive.openwrt.org|81.0.124.218|:443... connected.
WARNING: cannot verify archive.openwrt.org's certificate, issued by 'CN=R11,O=Let\'s Encrypt,C=US':
  Unable to locally verify the issuer's authority.
HTTP request sent, awaiting response... 200 OK
Length: 111745 (109K) [application/octet-stream]
Saving to: 'Packages.gz'

Packages.gz                            100%[=============================================================================>] 109.13K   490KB/s   in 0.2s

2025-05-04 07:23:06 (490 KB/s) - 'Packages.gz' saved [111745/111745]

root@RT5350F-OLinuXino:/tmp# ls -l ./Packages.gz
-rw-r--r--    1 root     root        111745 Mar  2  2016 ./Packages.gz

К сожалению, сертификаты не помогли, пришлось отключать их проверку опцией "--no-check-certificate". Теперь нужно объяснить это opkg.

Менеджер пакетов opkg - это скомпилированный бинарный файл и дополнительную опцию в вызов внешней программы туда не вставишь.

Решение было придумано следующее. wget - это симлинк на wget-ssl:

# ls -l  /usr/bin/wget
lrwxrwxrwx    1 root     root            10 May  4 07:14 /usr/bin/wget -> ./wget-ssl

1. удалите симлинк wget. 2. Вместо него разместите такой скрипт:

#!/bin/ash
#set -x

/usr/bin/wget-ssl --no-check-certificate -q "$2" "$3" "$4" "$5"
exit 0

Не забудьте установить права на исполнение. Для отладки раскомментируйте "set -x" и уберите ключ "-q" из параметров запуска wget.

Конфиг "/etc/opkg.conf" приведите к следующему виду:

dest root /
dest ram /tmp
lists_dir ext /var/opkg-lists
option overlay_root /overlay
src/gz chaos_calmer_base https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/
#src/gz chaos_calmer_telephony http://downloads.openwrt.org/snapshots/trunk/ramips/rt305x/packages/telephony
src/gz chaos_calmer_packages https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/packages
#src/gz chaos_calmer_routing http://downloads.openwrt.org/snapshots/trunk/ramips/rt305x/packages/routing
#src/gz chaos_calmer_luci http://downloads.openwrt.org/snapshots/trunk/ramips/rt305x/packages/luci
#src/gz chaos_calmer_management http://downloads.openwrt.org/snapshots/trunk/ramips/rt305x/packages/management
# src/gz chaos_calmer_targets http://downloads.openwrt.org/snapshots/trunk/ramips/rt305x/packages/targets
option check_signature 1

Как можно видеть по ссылкам на trunk, у нас не релизная версия Openwrt-15.05 а сборка из транка. Вследствии этого или нет, наши ключи к репозиторию пакетов 15.05 не подойдут. Поэтому удаляем их:

# rm  /etc/opkg/keys/*

Вместо них помещаем следующие два файла с именами "53bad1233d4c98c5" и "de98a2dd1d0f8a07" и таким содержимым:

root@RT5350F-OLinuXino:/tmp# for i in /etc/opkg/keys/*; do echo filename is: "$i"; cat "$i"; done
filename is: /etc/opkg/keys/53bad1233d4c98c5
untrusted comment: Local build key
RWRTutEjPUyYxcuFKuF19hS8WfHi09AkVhK33KMQPri/dFG9PhEzDtMH
filename is: /etc/opkg/keys/de98a2dd1d0f8a07
untrusted comment: openwrt.org 15.05 release key
RWTemKLdHQ+KBxOILy8gyk+5PaDVdfyJ32TFnY/jnQOrBAd1wobbLNYz

Эти ключи я вытащил из релизной версии OpenWRT-15.05 для OLinuXINO. Скачал прошивку, распаковал binwalk'ом и взял ключи. Можете повторить.

Итак, проверяем:

root@RT5350F-OLinuXino:/tmp# opkg update
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/Packages.gz.
Updated list of available packages in /var/opkg-lists/chaos_calmer_base.
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/Packages.sig.
Signature check passed.
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/packages/Packages.gz.
Updated list of available packages in /var/opkg-lists/chaos_calmer_packages.
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/packages/Packages.sig.
Signature check passed.

Теперь можно что-нибудь поставить:

root@RT5350F-OLinuXino:/tmp# opkg install nano 
Installing nano (2.4.1-1) to root...
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/packages/nano_2.4.1-1_ramips_24kec.ipk.
Installing libncurses (5.9-2) to root...
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/libncurses_5.9-2_ramips_24kec.ipk.
Installing terminfo (5.9-2) to root...
Downloading https://archive.openwrt.org/chaos_calmer/15.05/ramips/rt305x/packages/base/terminfo_5.9-2_ramips_24kec.ipk.
Configuring terminfo.
Configuring libncurses.
Configuring nano.

В результате, после установки всех этих пакетов у нас осталось свободного места на флешке:

root@RT5350F-OLinuXino:/tmp# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                    4.6M      2.0M      2.6M  43% /
/dev/root                 2.3M      2.3M         0 100% /rom
tmpfs                    14.3M    408.0K     13.9M   3% /tmp
/dev/mtdblock6            4.6M      2.0M      2.6M  43% /overlay
overlayfs:/overlay        4.6M      2.0M      2.6M  43% /
tmpfs                   512.0K         0    512.0K   0% /dev

Этого в принципе достаточно чтобы поставить lighttpd, несколько модов и какой-нибудь ЯПВУ для выполнения GCI-сценариев. Но на данном этапе, я бы посоветовал поставить openssh-ssftp-server, что бы можно было перекидывать файлы с компа на одноплатник и обратно с помощью утилиты "scp". И еще настроил бы беспарольный доступ по следующему мануалу "Dropbear key-based authentication". Это сэкономит вам кучу времени.

5) Вторая плата

Когда я убедился, что на одноплатник можно поставить OpenWRT, я заказал вторую плату. Я честно говоря удивлен, что она до сих пор продется, потому-что первую я заказывал в далеком 2022 году, и за это время много всякой дичи исчезло с али. Я опасался что придет вариант с 16 МБ ОЗУ, но мне повезло и в этот раз. Однако без подвоха не обошлось. Во-первых плата была с другими чипами:

Здесь флешка windond w25q64bvsig на 8 МБ и оперативка Winbond w9825g6jh-6 на 32 МБ.

Однако родная прошивка загружаться отказалась:

U-Boot 1.1.3 (Nov  6 2012 - 19:35:17)

Board: Ralink APSoC DRAM:  32 MB
relocate_code Pointer at: 81fb4000
spi_wait_nsec: 42
spi device id: ef 40 17 0 0 (40170000)
find flash: W25Q64BV
raspi_read: from:30000 len:1000
.*** Warning - bad CRC, using default environment

============================================
Ralink UBoot Version: 3.6.0.0
--------------------------------------------
ASIC 5350_MP (Port5<->None)
DRAM_CONF_FROM: Boot-Strapping
DRAM_TYPE: SDRAM
DRAM_SIZE: 256 Mbits
DRAM_WIDTH: 16 bits
DRAM_TOTAL_WIDTH: 16 bits
TOTAL_MEMORY_SIZE: 32 MBytes
Flash component: SPI Flash
Date:Nov  6 2012  Time:19:35:17
============================================
icache: sets:256, ways:4, linesz:32 ,total:32768
dcache: sets:128, ways:4, linesz:32 ,total:16384

 ##### The CPU freq = 360 MHZ ####
 estimate memory size =32 Mbytes

Please choose the operation:
   1: Load system code to SDRAM via TFTP.
   2: Load system code then write to Flash via TFTP.
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.                                                                                                                                                                                   0

3: System Boot system code via Flash.
## Booting image at bc050000 ...
raspi_read: from:50000 len:40
.   Image Name:   Linux Kernel Image
   Created:      2013-11-27  11:12:02 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    5918970 Bytes =  5.6 MB
   Load Address: 80000000
   Entry Point:  803c6000
raspi_read: from:50040 len:5a50fa
...........................................................................................   Verifying Checksum ... Bad Data CRC

На этой Bad Data CRC все и заканчивалось. Это было очень странно, потому-что какую попало прошивку через родной интерфейс обновления прошивки в чип не загрузишь. Хорошая новость заключалась в том, что и плата была рабочая. И т.к. у меня появилась вторая плата для экспериментов, я прошил в нее дамп с первой прошивки, и с нею она успешно загрузилась появилась точка доступа "feel1945", т.е. радиочасть работала.

Можно кстати посмотреть на эффективность керамической антенны:

Точка доступа Sparky находится за капитальной стеной, это полметра кирпича. И тем не менее, ее сигнал сильнее чем сигнал от рядом лежащего одноплатника. Я не хочу сказать, что керамика никуда не годится, есть же другие факторы кроме силы сигнала, такие как габариты. Но когда подключаешься к плате по ssh - некоторая задумчивость в работе имеется.

Я попытался подключиться к точке доступа с ранее найденным ключем:

WiFiKey=N0d7c7MZN#0549WlEJoO1#

Но точка доступа его не приняла. Немного почесав репу, я снова полез в Config раздел, и нашел уже настоящий ключ:

Дальше все просто. После подключения к точке доступа заходим на IP "192.168.89.1", там тоже надо будет залогинится с этим же ключем, после чего переключаем интерфейс с китайского на английский и заходим в раздел "Advanced", где нажимаем "загрузить настройки по умолчанию"

После этого все пароли сбросятся до дефолтных, связь пропадет, вместо "feel1945" появится точка доступа "YOOBAO_C6E6" с ключем "YOOBAO123". Через UART можно будет залогиниться с парольной парой:

username: hongxun with password: wuzhun2012

C этой же парольной парой можно будет зайти через telnet. Ну и как я предполагал, через интерфейс обновления firmware, прошить OpenWRT не получится:

Что касается OpenWrt, если у вас две платы или больше, то их MAC адреса по умолчанию будут одинаковыми и точка доступа к которой они будут подключаться не сможет понять кто есть кто. Поэтому нужно менять MAC адрес для WIFI интерфейса следующей командой:

# uci -q set wireless.@wifi-iface[-1].macaddr="00:0C:05:07:6C:E0" # здесь впишите свой вариант
# uci commit wireless
# wifi

После этого WiFi перезапустится, на MAC уже будет другой:

# ifconfig|grep "HWaddr"
br-lan    Link encap:Ethernet  HWaddr 00:0C:05:07:6C:E6  
eth0      Link encap:Ethernet  HWaddr 00:0C:05:07:6C:E6  
eth0.1    Link encap:Ethernet  HWaddr 00:0C:05:07:6C:E6  
wlan0     Link encap:Ethernet  HWaddr 00:0C:05:07:6C:E0 
wlan0-1   Link encap:Ethernet  HWaddr 00:0C:05:07:6C:E6 

При этом в /etc/config/wireless появится строчка вида (выделено красным):

config wifi-iface 'sta'
        option device 'radio0'
        option mode 'sta'
        option network 'wan'
        option ssid 'Alien'
        option encryption 'psk2'
        option key 'password'
        option macaddr '00:0C:05:07:6C:E0'

6) Обновление OpenWRT до версии 19.07

Можно существенно упростить себе жизнь, если поставить версию OpenWRT посвежее нежели 15.05. Из последних релизов сборки для OLinuXINO убрали, но я собирал из исходников и там получается размер прошивки почти 5 мегабайт. Очевидно, что проект OpenWRT движется в сторону более производительного и дорогого железа, оставляя за бортом устаревшие изделия. Однако не все так плохо, самосборная прошивка OpenWRT-19.07 весит всего 3.4 МБ в то время как OpenWRT-15.05 3.3 МБ разница несущественная на мой взгляд. Прошивка OpenWRT версии 21.02 уже на один мегабайт толще (имеется в виду прошивка с люсей. прошивка с люсей 19.07 весит 3.8 МБ). Готовую прошивку версии 19.07 можно скачать с официального сайта openwrt-19.07.10-ramips-rt305x-rt5350f-olinuxino-squashfs-sysupgrade.bin, но там размер 3.8 МБ из-за того, что в сборку включена люся. Кастомную прошивку можно скачать отсюда, она без люси и полностью совместима c официальной, при сборке я там только таргет выставлял.

Прошивка закидывается в "/tmp" каталог устройства. Обязательно проверяйте контрольные суммы. Для кастомной прошивки они следующие:

$ sha256sum  ./openwrt-ramips-rt305x-rt5350f-olinuxino-squashfs-sysupgrade.bin 
f77fb26369e705001266b4fa6c0479a9793e1b62d5fa4e78cf8d3b6bba339866  ./openwrt-ramips-rt305x-rt5350f-olinuxino-squashfs-sysupgrade.bin
$  md5sum  ./openwrt-ramips-rt305x-rt5350f-olinuxino-squashfs-sysupgrade.bin 
e4c7d26141fbce8a915f05ef04914e9e  ./openwrt-ramips-rt305x-rt5350f-olinuxino-squashfs-sysupgrade.bin

Перепрошивка командой:

sysupgrade -n -F имя_файла.bin

Т.е. без сохранения настроек. Опция "-F" -принудительная прошивка нужна из-за того, что выдало ошибку 'platform_check_image' - failed:

После перепошивки настаивается сеть, так же как было описано выше, но в этом случае никаких пакетов ставить не надо, ключи менять не надо, opkg работает "из коробки". Единственное, в случае с кастомной прошивкой следует поправить адреса репозитория в файле "/etc/opkg/distfeeds.conf"

src/gz openwrt_core http://downloads.openwrt.org/releases/19.07.9/targets/ramips/rt305x/packages
src/gz openwrt_base http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/base
#src/gz openwrt_freifunk http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/freifunk
src/gz openwrt_luci http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/luci
src/gz openwrt_packages http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/packages
#src/gz openwrt_routing http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/routing
#src/gz openwrt_telephony http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/telephony

Т.е. у нас очень существенно экономится пространство на флешке по сравнению с использованием OpenWRT-15.05:

# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.0M      2.0M         0 100% /rom
tmpfs                    13.9M     52.0K     13.8M   0% /tmp
/dev/mtdblock6            4.6M    256.0K      4.4M   5% /overlay
overlayfs:/overlay        4.6M    256.0K      4.4M   5% /
tmpfs                   512.0K         0    512.0K   0% /dev

Доступно 4.4 МБ вместо 2.6 МБ на OpenWRT-15.05. Пакетный менеджер при этом полностью работоспособен:

root@lv-223:~# opkg update
Downloading http://downloads.openwrt.org/releases/19.07.9/targets/ramips/rt305x/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_core
Downloading http://downloads.openwrt.org/releases/19.07.9/targets/ramips/rt305x/packages/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/base/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_base
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/base/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/luci/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_luci
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/luci/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_packages
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/packages/Packages.sig
Signature check passed.
root@lv-223:~# opkg install nano
Installing nano (6.2-1) to root...
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/packages/nano_6.2-1_mipsel_24kc.ipk
Installing terminfo (6.1-5) to root...
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/base/terminfo_6.1-5_mipsel_24kc.ipk
Installing libncurses6 (6.1-5) to root...
Downloading http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/base/libncurses6_6.1-5_mipsel_24kc.ipk
Configuring terminfo.
Configuring libncurses6.
Configuring nano.

Однако, если в последствии вам все-таки придется выкачивать что-то по https, то все-равно придется поставить wget-ssl, который за собой потянет зависимости:

# opkg install wget-ssl
Installing wget (1.20.3-4) to root...
Downloading http://downloads.openwrt.org/releases/19.07.10/packages/mips_mips32/packages/wget_1.20.3-4_mips_mips32.ipk
Installing libpcre (8.43-1) to root...
Downloading http://downloads.openwrt.org/releases/19.07.10/packages/mips_mips32/packages/libpcre_8.43-1_mips_mips32.ipk
Installing zlib (1.2.11-4) to root...
Downloading http://downloads.openwrt.org/releases/19.07.10/packages/mips_mips32/base/zlib_1.2.11-4_mips_mips32.ipk
Installing libopenssl1.1 (1.1.1n-1) to root...
Downloading http://downloads.openwrt.org/releases/19.07.10/packages/mips_mips32/base/libopenssl1.1_1.1.1n-1_mips_mips32.ipk
Installing librt (1.1.24-2) to root...
Downloading http://downloads.openwrt.org/releases/19.07.10/targets/brcm63xx/generic/packages/librt_1.1.24-2_mips_mips32.ipk
Configuring libpcre.
Configuring zlib.
Configuring libopenssl1.1.
Configuring librt.
Configuring wget.

В даном случае я установил wget-ssl на роутер c mips32 архитектурой, поэтому суффиксы "mips_mips32". Но OpenWRT там тот же 19.07

Для доступа на устройство по ssh, в конфиге "~/.ssh/config" я добавил следующую секцию:

Host lv-223 192.168.1.19 # здесь должен быть IP Вашего устройства
     HostKeyAlgorithms +ssh-rsa
    Ciphers aes128-ctr,aes256-ctr

Мне было любопытно, какой результат покажет чип RT5350F в бенчмарке. Я установил пакеты "micropython", "micropython-lib" и скачал бенчмарк:

$ wget https://raw.githubusercontent.com/ckuehnel/micropython_benchmarks/refs/heads/master/1.9.4-479/benchmark.py

Его потребовалось немного подредактировать, т.к. вычисление 100000 знаков числа Пи заняло бы длительное время, кроме того, в Linux версии микропитона нет модуля "machine". Результат выполнения теста вышел следующим:

Для сравнения я взял роутер с похожими характеристиками - sagem fast - 2704v2, там тоже установлен OpenWRT-19.07, и результат теста на нем вышел следующим:

Принципе, у Sagem частота ниже - 320 МГц, но производительность лучше, BogoMIPS более высокий, но общий результат где-то на одном уровне. На роутерных процессорах нет поддержки операций чисел с плавающей запятой, но результат выглядит так, словно это не играет особой роли. Такой результат мне показался странным, я уверен, что нативная программа на роутере считала в несколько раз быстрее чем на ESP32:

Нативную программу под роутер можно собрать с помощью кросс-компилятора, который собирается в процессе сборки прошивки. У меня прошивка собиралась в Slackware, т.к. я не хотел тащить зависимости необходимые для сборки в Mint, но готовым кросс-компилятором можно пользоваться и в Mint. Скачать готовый тулчейн для OpenWRT-19.07-MIPSEL можно ссылке.

$ /mnt/slack/home/flanker/mydev/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/bin/mipsel-openwrt-linux-g++ --version 
mipsel-openwrt-linux-g++ (OpenWrt GCC 7.5.0 r11436-1da2e82c11) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Добавляем каталог с тулчейном в PATH и :

$ export PATH=/mnt/slack/home/flanker/mydev/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/bin/:$PATH

Составлем hello.cpp:

#include <stdio.h>
int main(int argc, char** argv)
{
    printf("Hello, World!\n");
    return 0;
}

Компиляция:

$ mipsel-openwrt-linux-g++  ./hello.cpp -o hello
mipsel-openwrt-linux-g++: warning: environment variable 'STAGING_DIR' not defined
mipsel-openwrt-linux-g++: warning: environment variable 'STAGING_DIR' not defined
mipsel-openwrt-linux-g++: warning: environment variable 'STAGING_DIR' not defined

Чтобы убрать warning, задём переменную окружения "STAGING_DIR":

$ export STAGING_DIR=/mnt/slack/home/flanker/mydev/openwrt/staging_dir

Давайте посмотрим, что у нас получилось:

$ ls -l ./hello
-rwxrwxr-x 1 flanker flanker 8536 мая  9 10:09 ./hello
$ file ./hello
./hello: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-mipsel-sf.so.1, with debug_info, not stripped

На выходе получили динамически линкуемую программу. Можно ее дизассемблировать с помощью команды:

$ mipsel-openwrt-linux-objdump -S ./hello

В частности, секция "main" выглядит следующим образом:

00400620 <main>:
#include <stdio.h>
int main(int argc, char** argv)
{
  400620:       27bdffe0        addiu   sp,sp,-32
  400624:       afbf001c        sw      ra,28(sp)
  400628:       afbe0018        sw      s8,24(sp)
  40062c:       03a0f025        move    s8,sp
  400630:       afc40020        sw      a0,32(s8)
  400634:       afc50024        sw      a1,36(s8)
    printf("Hello, World!\n");
  400638:       3c020040        lui     v0,0x40
  40063c:       24440700        addiu   a0,v0,1792
  400640:       0c1001ec        jal     4007b0 <puts@plt>
  400644:       00000000        nop
    return 0;
  400648:       00001025        move    v0,zero
}
  40064c:       03c0e825        move    sp,s8
  400650:       8fbf001c        lw      ra,28(sp)
  400654:       8fbe0018        lw      s8,24(sp)
  400658:       27bd0020        addiu   sp,sp,32
  40065c:       03e00008        jr      ra
  400660:       00000000        nop
        ...

Для сравнения, та же самая секция для ARM-процессора Allwinner H2 состоит из 16-битных инструкций, т.е. это Thumb набор. Причем я собирал пример без какой-либо оптимизации. Теперь, если мы перекинем скомпилированный бинарник "hello" на плату RT5350, то окажется, что для запуска программы не хватает динамических библиотек:

# ldd ./hello
    /lib/ld-musl-mipsel-sf.so.1 (0x77e80000)
Error loading shared library libstdc++.so.6: No such file or directory (needed by ./hello)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x77e5c000)
    libc.so => /lib/ld-musl-mipsel-sf.so.1 (0x77e80000)

Не хватает "libstdc++.so.6", которая весит почти под два мегабайта:

$ ls -l /mnt/slack/home/flanker/mydev/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/lib/libstdc++.so.6.0.24
-rwxr-xr-x 1 flanker users 1776392 мая  7 08:21 /mnt/slack/home/flanker/mydev/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/lib/libstdc++.so.6.0.24

Ситуацию можно исправить если скомпилировать "hello.cpp" c опцией "-static":

$ mipsel-openwrt-linux-g++  -static ./hello.cpp -o hello
$ mipsel-openwrt-linux-strip  hello
$ ls -l ./hello
-rwxrwxr-x 1 flanker flanker 10716 мая  9 11:17 ./hello

Перекидываем программу на OpenWRT и запускаем оттуда:

Десять килобайт - это уже более приемлемо. Программа скомпилированная статично будет работать и в других версиях OpenWRT, и на других чипах, главное чтобы архитектура была MIPSEL.

7) Использование эмулятора QEMU

Чтобы запустить описанную выше программу "hello" на компьютере, можно воспользоваться эмулятором QEMU:

$ qemu-mipsel ./hello
Hello, World!

Но что делать, если требуется запустить динамически-линкуемую программу, которая была собрана без флага "-static"? Потому-что если попытаться ее запустить как статическую, то закономерно получим ошибку:

$ qemu-mipsel ./hello
qemu-mipsel: Could not open '/lib/ld-musl-mipsel-sf.so.1': No such file or directory

Здесь проблема комплексная. 1. В каталоге /lib нам требуется нахождение библиотеки (на самом деле нескольких). но мы же не будем захламлять хост-систему непонятно чем? Решить вопрос может chroot. 2. Но для этого потребуется статическая версия qemi-mipsel, потому-что он должен выполняться из chroot. Третья проблем в том, что chroot требует привилегированных прав. А мы же не хотим запускать непонятно что с привилегированными правами?

По порядку. Вторая проблема решается проще всего. Для этого ставим пакет qemu-user-static.

$ sudo apt install qemu-user-static

Далее создаем каталоги для "chroot":

$ $ mkdir -p /tmp/dir/{bin,lib}

В "/tmp/bin" кидаем hello, в "/tmp/lib" библиотеку "ld-musl-mipsel-sf.so.1". Библиотека является частью тулчейна для mipsel, ссылка на который была выше "staging_dir.tar.gz" (Он весит почти целый гигабайт). В "корень" копируем "qemu-mipsel-static"

$ cp -v /usr/bin/qemu-mipsel-static /tmp/dir/

Допустим, у нас сейчас как-то так:

$ tree /tmp/dir
/tmp/dir
├── bin
│   └── hello
├── lib
│   ├── ld-musl-mipsel-sf.so.1
│   └── libstdc++.so.6
└── qemu-mipsel-static

Попытаемся запустить программу "hello" с помощью "chroot":

$ sudo bash -c 'chroot /tmp/dir /qemu-mipsel-static /bin/hello'
[sudo] пароль для flanker:         
Error loading shared library libgcc_s.so.1: No such file or directory (needed by /bin/hello)
Error loading shared library libgcc_s.so.1: No such file or directory (needed by /lib/libstdc++.so.6)
Error relocating /lib/libstdc++.so.6: _Unwind_SetIP: symbol not found
Error relocating /lib/libstdc++.so.6: _Unwind_Resume: symbol not found
Error relocating /lib/libstdc++.so.6: _Unwind_DeleteException: symbol not found
Error relocating /lib/libstdc++.so.6: __adddf3: symbol not found
Error relocating /lib/libstdc++.so.6: __gtdf2: symbol not found
Error relocating /lib/libstdc++.so.6: __fixunsdfsi: symbol not found
Error relocating /lib/libstdc++.so.6: _Unwind_SetGR: symbol not found
...
и так далее

Требуются еще библиотеки, и вполне возможно, что этим библиотекам потребуются свои библиотеки и так до бесконечности.

На мой взгляд, самым простым будет разархивировать прошивку OpenWRT с помощью binwalk, там уже будет готовое окружение для запуска программы hello (ну почти).

Я скачал с сайта OpenWRT прошивку 19.07 - openwrt-19.07.10-ramips-rt305x-rt5350f-olinuxino-squashfs-sysupgrade.bin и распаковал ее. Из тулчейна потребуется скопировать в "/lib" каталог библиотеку "libstd++.so.6":

$ cp /mnt/slack/home/flanker/mydev/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/lib/libstdc++.so.6.0.24 ./squashfs-root/lib/libstd++.so.6

В каталог "/bin" кидаем программу "hello". В корень кидаем эмулятор "qemu-mipsel-static". Запускаем:

$ sudo bash -c "chroot ./squashfs-root/ /qemu-mipsel-static /bin/hello"
Hello, World!

Работает, это хорошо. А теперь давайте сделаем это без "sudo":

$ unshare -r bash -c "chroot ./squashfs-root/ /qemu-mipsel-static /bin/hello"
Hello, World!

Отлично! А теперь давайте подумаем, что мы еще можем запустить таким образом? Да что угодно:

$ unshare -r bash -c "chroot ./squashfs-root/ /qemu-mipsel-static /bin/ash"

Часто так бывает, что на SoC нет вообще никакой документации, даже даташита. Взять к примеру широко распространенный RTL8676S. Исполняемые файлы извлеченные из прошивки - это единственный способ понять, что из себя представляет тот или иной чип.

Но что же делать, если нашу программу требуется проверить на устройстве, где есть сеть, сокеты, где можно запустить веб-сервер? Для этого QEMU может эмулировать устройство на MIPS архитектуре, на котором можно обкатать свою сборку OpenWRT, программу, и или еще что-то. Устройств (роутеров) на MIPS очень много, QEMU умеет эмулировать более-менее универсальную машину Malta, с нею и придется работать. Запустить ядро из произвольной прошивки от какого-либо роутера на QEMU не получится, но кое-что сделать можно.

Для мальты в OpenWRT есть отдельный таргет, и даже выложены сборки на официальном сайте, но для архитектуры MISP32_BE (big endianness). Для MIPSEL архитектуры мне пришлось собрать OpenWRT-19.07 под мальту вручную. Про запуск MIPS на QEMU есть вики OpenWrt in QEMU MIPS, но вот как пробросить в OpenWRT сеть там не сказано ни слова. Поэтому освещать этот вопрос буду я.

Для начала скачиваем OpenWRT-19.07 для MIPSEL по ссылке. В архиве нас будут интересовать два файла:

Тренироваться будем на "openwrt-malta-le-vmlinux-initramfs.elf" - это OpenWRT c ramfs в качестве корневой файловой системы. Говоря простым языком все изменения и настройки сделанные в ходе работы НЕ будут сохраняться. Запускаем виртуальную машину командой:

$ qemu-system-mipsel -kernel ./openwrt-malta-le-vmlinux-initramfs.elf -m 256 -nographic

MIPS32 имеет в QEMU ограничение на размер ОЗУ 256 МБ. Если опустить токен "-nographic", то виртуальная машина запуститься в окошке, где надо будет выбрать метод вывода Serial IO:

С токеном "-nographic" вы запустите виртуальную машину прямо в консоли:

Машина запускается и работает, но интернета там нет. Для того чтобы пробросить интернет в виртуальную машину QEMU, для нее создадим виртуальный сетевой интерфейс "tap0":

$ sudo tunctl -u flanker -t tap0
Пароль: 
Set 'tap0' persistent and owned by uid 1000

В Slackware пришлось поставить пакет tunctl из SBo, в Mint этот пакет уже присутствовал (точно уже не помню). У нас дожен появиться неактивный сетевой интерфейс tap0:

tap0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether ee:58:dd:c2:69:1d  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Назначаем интерфейсу статический IP-адрес и активируем его.

$ sudo ip addr add 192.168.0.1/24 dev tap0
$ sudo ip link set tap0 up

Проверяем:

$ /sbin/ifconfig |tail

tap0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.0.1  netmask 255.255.255.0  broadcast 0.0.0.0
        ether ee:58:dd:c2:69:1d  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Теперь надо связать реальный Ethernet интерфейс с виртуальным "tap0" с помощью NAT. Для начала следует в принципе это (forwarding) разрешить в ядре (фильтрация трафика осуществлется ядром):

$ sudo bash -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

Сбрасываем действующие правила iptables (если они есть):

$ iptables -F FORWARD
$ iptables -t nat -F POSTROUTING

После чего подключаем наш виртуальный "tap0" к рельному "eth0" и включаем NAT:

$ iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT
$ iptables -A FORWARD -i eth0 -o tap0 -m state --state ESTABLISHED,RELATED -j ACCEPT
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Вместо "eth0" подставьте свой сетевой интерфейс, в Mint у меня вместо "eth0" был "enp0s25".

Что бы совершать все эти действия одной командой, я составил скрипт "qemu_net_up.sh":

#!/usr/bin/bash
set -x
# Create tap0 interface
if ! tunctl -u "$1" -t tap0; then
    echo "Failed to create tap0"
    exit 1
fi

# Configure IP and bring up tap0
ip addr add 192.168.0.1/24 dev tap0 || exit 1
ip link set tap0 up || exit 1

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward || exit 1

# Flush existing rules (optional)
iptables -F FORWARD
iptables -t nat -F POSTROUTING

# Set up forwarding and NAT
iptables -A FORWARD -i tap0 -o "$2" -j ACCEPT || exit 1
iptables -A FORWARD -i "$2" -o tap0 -m state --state ESTABLISHED,RELATED -j ACCEPT || exit 1
iptables -t nat -A POSTROUTING -o "$2" -j MASQUERADE || exit 1

echo "Setup completed successfully."

И еще один скрипт - "qemu_net_down.sh", чтобы сбрасывать эти настройки:

#!/usr/bin/bash
set -x
# Flush existing rules
iptables -F FORWARD
iptables -t nat -F POSTROUTING

# Disable IP forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward || exit 1

# Down tap0 interface
ip link set tap0 down || exit 1

# Delete tap0 interface
if ! tunctl  -d tap0; then
    echo "Failed to delete tap0"
    exit 1
fi

echo "Down tap0 interface completed successfully."

Работает это так:

$ sudo bash -c "sh ./qemu_net_up.sh $(whoami) eth2"
+ tunctl -u flanker -t tap0
Set 'tap0' persistent and owned by uid 1000
+ ip addr add 192.168.0.1/24 dev tap0
+ ip link set tap0 up
+ echo 1
+ iptables -F FORWARD
+ iptables -t nat -F POSTROUTING
+ iptables -A FORWARD -i tap0 -o eth2 -j ACCEPT
+ iptables -A FORWARD -i eth2 -o tap0 -m state --state ESTABLISHED,RELATED -j ACCEPT
+ iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
+ echo 'Setup completed successfully.'
Setup completed successfully.

Где вместо "eth2", в параметре команды должно быть имя вашего ethernet интерфейса.

Сброс виртуального интерфейса:

$ sudo bash -c 'sh ./qemu_net_down.sh'
Пароль: 
+ iptables -F FORWARD
+ iptables -t nat -F POSTROUTING
+ echo 0
+ ip link set tap0 down
+ tunctl -d tap0
Set 'tap0' nonpersistent
+ echo 'Down tap0 interface completed successfully.'
Down tap0 interface completed successfully.

Если все работает корректно, то самое сложное было уже сделано. Теперь активируем виртуальный интерфейс и запускаем виртуальную машину командой:

$  qemu-system-mipsel -M malta -m 256 -kernel ./openwrt-malta-le-vmlinux-initramfs.elf -nographic -net nic  -net tap,ifname=tap0,script=no

Нужно дождаться, когда в логе загрузки появится строка поднятия сетевого интерфейса:

28.112521] pcnet32 0000:00:0b.0 eth0: link up

Жмем "Enter" и командной строке "ложим" этот интерфейс обратно:

# ip link set eth0 down

Поднимаем интерфейс со статическим адресом и пробуем достучаться до хост машины:

# ip addr add 192.168.0.2/24 dev eth0
# ip link set eth0 up
# ping 192.168.0.1 -c 5
PING 192.168.0.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: seq=0 ttl=64 time=15.289 ms
64 bytes from 192.168.0.1: seq=1 ttl=64 time=2.017 ms
64 bytes from 192.168.0.1: seq=2 ttl=64 time=2.818 ms
64 bytes from 192.168.0.1: seq=3 ttl=64 time=1.143 ms
64 bytes from 192.168.0.1: seq=4 ttl=64 time=3.340 ms

--- 192.168.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 1.143/4.921/15.289 ms

Далее ставим шлюз командой:

# /sbin/route add default gw 192.168.0.1

и пробуем пинговать интернет:

# ping 8.8.8.8 -c 3 
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=105 time=40.667 ms
64 bytes from 8.8.8.8: seq=1 ttl=105 time=41.965 ms
64 bytes from 8.8.8.8: seq=2 ttl=105 time=42.586 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 40.667/41.739/42.586 ms

Осталась установить "resolv.conf":

# echo "nameserver 77.88.8.8" > /etc/resolv.conf
# ping ya.ru -c 3
PING ya.ru (77.88.55.242): 56 data bytes
64 bytes from 77.88.55.242: seq=0 ttl=52 time=31.640 ms
64 bytes from 77.88.55.242: seq=1 ttl=52 time=31.624 ms
64 bytes from 77.88.55.242: seq=2 ttl=52 time=33.040 ms

--- ya.ru ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 31.624/32.101/33.040 ms

Ну вот и все, интернет в нашей виртуальной машине есть:

Все эти манипуляции можно автоматизировать, если конфиг "/etc/config/network" привести к следующему виду:

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config globals 'globals'
    option ula_prefix 'auto'

config interface 'lan'
    option ifname 'eth0'
    option proto 'static'
    option ipaddr '192.168.0.2'
    option netmask '255.255.255.0'
    option gateway '192.168.0.1'
    option dns '77.88.8.8'

Применяем изменения:

# uci commit network
# /etc/init.d/network restart
'radio0' is disabled
'radio1' is disabled
[  660.888400] pcnet32 0000:00:0b.0 eth0: link up

И сеть у нас на месте. Чтобы можно было зайти по ssh с хост-машины на виртуальною машину, нужно будет установить пароль для root, иначе dropbear не пропустит.

Чтобы заработал opkg, нужно конфигурационный файл "/etc/opkg/distfeeds.conf" привести к следующему виду:

src/gz openwrt_core http://downloads.openwrt.org/releases/19.07.9/targets/ramips/rt305x/packages
src/gz openwrt_base http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/base
#src/gz openwrt_freifunk http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/freifunk
#src/gz openwrt_luci http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/luci
src/gz openwrt_packages http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/packages
#src/gz openwrt_routing http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/routing
#src/gz openwrt_telephony http://downloads.openwrt.org/releases/19.07.9/packages/mipsel_24kc/telephony

И мы получили полностью работоспособную и бинарно совместимую с RT5350F виртуальную машину. Делайте в ней, что угодно. После рестарта все изменения однозначно сбросятся:

Последнее обстоятельство не всегда удобно на мой взгляд. Хотелось бы иметь виртуальную машину с диском, где сохранялись бы все конфигурации и данные.

Делается это так же как и перенос rootfs на флешку или карточку в обычной OpenWRT. В данном случае, на хост-системе я создал пустой RAW-файл на 256 МБ, разбил его fdisk'ом, отформатировал в ext4. Затем смонтировал его и перенес него файловую систему из "openwrt-malta-le-vmlinux-initramfs.elf", которую извлек с помощью binwalk. В данном случае binwalk не совсем корректно отработал, многие симлинки из "/usr/bin" потерялись. Система загружалась, но не было команд: "wget", "cut", "head" и других. Поэтому я сжал каталог "/usr" в архив на запущенной системе с initramfs, и перенес его на диск. Больше проблем вроде не было.

Для демонстрации я подготовил файл с минимальными настройками сети, который можно скачать по ссылке. Для запуска виртуальной машины понадобится ядро "openwrt-malta-le-vmlinux.elf" из скачанного ранее архива.

Виртуальная машина запускается командой:

$ qemu-system-mipsel -M malta -m 256 -kernel ./openwrt-malta-le-vmlinux.elf -drive file=mips.ext4,format=raw,index=0,media=disk -append "root=/dev/sda2 console=ttyS0" -nographic -net nic  -net tap,ifname=tap0,script=no

Здесь сразу корректно настроена сеть и пакетный менеджер. Свободного места - 184 МБ. Этого должно хватить для всех (с).

Пароль root'а cброшен, его потребуется задать самостоятельно.

Вместо заключения

В процессе изучения модуля от повербанка я научился работать c SPI-программатором, распаковывать прошивки с помощью binwalk, узнал чем прошивка отличается от дампа, научился работать с виртуальными сетевыми интерфейсам, а также пробрасывать сеть в виртуальную машину QEMU. Несмотря на то, что у меняя имеется LinkIt Smart 7688 и несколько роутеров на OpenWRT, я не сталкивался при работе с ними с теми проблемами, что мне пришлось решать в данном случае. Просто потому, что там все работало как надо. Поэтому я считаю, что в познавательном плане, результат от "ковыряния железки" для меня гораздо ценнее, чем само устройство. Можно сказать по другому:

Прищепка от программатора, конечно, порядочно сделала нервов :)
Всем добра и успехов в творчестве!