Я долгое время избегал темы OpenWRT, опасаясь деструктивных последствий статей по перепрошивке домашней техники. Однако плата про которую речь пойдет ниже, не является домашней техникой, это модуль от повербанка, который продется без какого-либо описания, характеристик и обещаний, что он у вас заработает. В моем случае одна плата пришла с неработоспособной прошивкой, а вторая запароленная. Модуль выполнен на чипе RT5350F компании Ralink (сейчас подразделение тайваньской Mediatek), который был популярным лет десять назад, главным образом благодаря миниатюрному роутеру HAME MPR-A1 включая его всевозможные клоны. Главным образом в плате меня привлек форм-фактор, т.е. миниатюрный размер, 8 МБ флеш-памяти и 32 МБ ОЗУ. Кроме того, хотелось поковыряться в железке, чему-то научиться, подержать в руках на чип о котором когда-то много читал, составить свое мнение (в начале я вообще думал, что у него архитектура ARM).
Данная статья - это ворклог, о превращению платы без какого - либо описания в маломощный одноплатник. Целевое применение такого модуля, на мой взгляд - это веб-интерфейс какого-либо сложного устройства, например для музыкального центра вместо пульта ДУ. В данном случае подразумевается работа данного модуля в связке с микроконтроллером, связь с которым осуществляется посредством либо UART, либо USB (в зависимости от объема передаваемых данных).
ВНИМАНИЕ! Статья не является рекламной, я не даю ссылок, где приобретался модуль, я НЕ(!) рекомендую эту плату к покупке, так же как и любого другого старого барахла для OpenWRT. В лотах продавцов данных модулей НЕ указаны характеристики устройств, могут прислать с 16 МБ ОЗУ и 4 МБ флеш-памяти, и вы не получите никакой компенсации открывая спор. В настоящее время можно прибрести новый одноплатник на любой бюджет, и он будет в сто раз лучше, чем RT5350F с SDRAM(!) памятью и рабочей температурой в 60(!!) градусов. Будьте благоразумны.
Содержание:
Итак, перед нами плата от повербанка 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, и изнутри он выглядит следующим образом:
На фото видно, что флешка другая winbond, а чип оперативки тот же EM63A165TS-6G. Если мы захотим вывести разъем USB и Ethernet, то придется воссоздать по фото нижнюю плату:
Чип 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:
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.
Поиски прошивки 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:/#
Первым делом следует задать пароль рута, чтобы можно было зайти по 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". Это сэкономит вам кучу времени.
Когда я убедился, что на одноплатник можно поставить 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'
Можно существенно упростить себе жизнь, если поставить версию 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.
Чтобы запустить описанную выше программу "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, я не сталкивался при работе с ними с теми проблемами, что мне пришлось решать в данном случае. Просто потому, что там все работало как надо. Поэтому я считаю, что в познавательном плане, результат от "ковыряния железки" для меня гораздо ценнее, чем само устройство. Можно сказать по другому:
Прищепка от программатора, конечно, порядочно сделала нервов :)
Всем добра и успехов в творчестве!