
Once, before the dollar jumps, I needed a very cheap SOHO router. Requirements - 5 ports, NAT and Wi-Fi, would not hurt and USB. The choice fell on
Upvel UR-313N4G , which in those days was worth 860 rubles in Citilink. The router was purchased and performed its duties quite tolerably, stably hanging once a week. In addition, port forwarding did not work, so what, it didn’t need much pain. In addition, the Web interface had access to the command line, so in critical cases, you could just write iptables -A PREROUTING -j DNAT and enjoy the working ports until the next hang. However, I did not expect more from the box for such a ridiculous price. Then something in my life changed and the router went to the far shelf, and was replaced by TP-Link TR-ML3420. I must say, TR-ML3420 works fine under OpenWRT and there are no problems with it, but Upvel routers are not officially supported by OpenWRT a little less than completely (there are only two routers from the whole lineup).
When it became clear that Upvel UR-313N4G is no longer a pity to me, I decided to try to put OpenWRT on it. The main task is to make the Megafon M21-4 3G modem, also known as Huawei E3531, work. I have to say that I had the experience of running OpenWRT routers through both the Web interface and the UART, but it was reduced to “select the file for the firmware and pray” or “type these three commands in the console and pray”. This time I wanted to find out why such commands are being introduced, and, in general, to get a general idea of ​​the MIPS architecture, which I hadn’t worked with before.
Here, of course, it should be noted that reading this material to
fathers who develop Gigabit Ethernet cards on FPGA and write video drivers for Mali-400 will probably be funny - they all have known this for so long.
To begin with, we will ask Google about what we will sew and where. In the x86 architecture, to boot the OS, a specially prepared medium is used - a hard disk, SSD or flash memory, marked according to the MBR or GPT standard, with a main boot record and a specially marked boot partition. The internal structure of the disk is hidden from the OS by its firmware, and the BIOS provides the minimum functionality even when the OS is not installed. In a router with MIPS architecture, everything is different. Data is stored on an MTD device, which is an EEPROM chip without a controller, so when we write to this circuit, we need to try not to write to the same sectors too often. In addition, MTD has a fixed and rather large block size that can be erased (in my case, 64Kb). There are no partition tables on the MTD device, but when the Linux kernel is loaded, it simulates the presence of a partition table. The settings for this simulation are set either when building the kernel, or using the mtdparts parameter when booting. At the beginning of the MTD there is a bootloader, which can be erased if the circumstances fail, and then only the EEPROM firmware on the programmer will help. The loader unpacks the image stitched into MTD into memory and transfers control to the Linux kernel.
')
Now it's time to experiment. First, let's open the router and see the marking of the main chip - Ralink 5350F. Easy googling shows that this chip is supported by OpenWRT, and quite well, there is a whole
ramips directory with firmware for the 5350 series. You can also see the 32 MB RAM chip and the 8 MB EEPROM on the board. A 4pda search site shows that the Ralink 5350F chipset is built on Upvel UR-322N4G, Hame MPR-A1 and Zyxel Keenetic 4G II. Well,
download OpenWRT for Hame MPR-A1 and try to flash through the web interface of the router.
The firmware is not sewn, apparently, some signatures are not checked. To clarify with a debugger at the ready what exactly, there is no desire. Well, okay, it did not hurt.
There are several ways to flash a router without using a web interface. You can, for example, use the recovery mode, in which the bootloader switches when the router starts. if the reset button is pressed. Looking ahead, I’ll say that there is no such mode in Upvel UR-313N4G, no luck, what can you do.
You can also connect to the router via telnet, which is available in the original firmware, “clear” the memory of the router, killing unnecessary processes, load the new firmware into memory via tftp and flash it with the mtd_write command. This method is bad because we, in fact, have only one attempt - if the firmware is incompatible with the router and cannot boot, then we will get a “semi-brick” at the output, which can be restored, but only through UART. In addition, in this case, you will have to break your head over which section of the MTD should write the firmware. I’ll say right away that in the MTD markup, which is used in the original firmware, there is no Firmware section.
UART firmware
From all this it follows that for experiments we need to connect to the router via UART, then we will have access to the console from the moment the router starts. Just in case, we will order a programmer from China for 160 rubles. If we don’t kill the bootloader, we don’t need a programmer, but, as they say, “cases are different.” On the board, if you hold it with the LEDs towards you, in the upper right-hand side there are 4 unsoldered holes in a row, suspiciously similar to the UART. We carefully look at the board - the first hole on the left is made in a wide layer of foil, it seems to be a schematic earth, the tracks from the next two holes go somewhere deep into the board - these are Rx and Tx, although it's not clear yet. in what order. The far right hole is also located on the foil layer, but smaller, it is most likely +3.3 V. Take the tester in your hands and measure the voltage. On Tx it should be +3.3 V, on Rx - 0 V. We receive (from left to right) - 0V; 3.3V, 0V, 3.3V. Mean, the second from the left is Tx, and the third is Rx. The rightmost contact is 3.3V, we will not unsolder - we will burn the adapter.
We take the Chinese clone of the cord Nokia CA-42, we cut it, we find the
pinout in Google and we solder (from left to right) - orange, red, blue.
Put Putty (I have Linux on the workstation, there shouldn't be any problems with Windows either) and select the speed of the port: set the standard values ​​for the COM port, turn on the router and see that the screen contains not sensible text, but meaningful text. I connected at a speed of 57600 baud. Now we have access to the loader, which means that the chance to distort the router is reduced.
Well, let's try to flash through the bootloader. At the time of the start of the system, we see a greeting
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.
I’m most attracted to this menu item 1 - receiving firmware via TFTP and launching it from RAM. It turns out that you can check the compatibility of the firmware with the device without even flashing it in the EEPROM. For me it was a pleasant surprise. Install the tftp-server (I took atftpd), put the firmware from the Hame MPR-A1 in the working directory and rename it more conveniently - to mpr-a1.bin.
We start the router, press the key 1 in the console, set the address 10.10.10.3 on the computer’s network interface, enter the necessary parameters in the loader and load the firmware.
The firmware started up, hurray! Even there is access to the Web-interface, and it means that most of the firmware is workable. And we have not sewed anything yet! Only something strange is going on with the LEDs - only Wi-Fi is on (and it is turned off and should not be on), but the LEDs on the Ethernet ports are off. We understand further. To configure switches in OpenWRT, the swconfig utility is used. Find out what our switch can do
>swconfig dev rt2305x help switch0: rt305x(rt305x-esw), ports: 7 (cpu @ 6), vlans: 4096 --switch Attribute 1 (int): enable_vlan (VLAN mode (1:enabled)) Attribute 2 (int): alternate_vlan_disable (Use en_vlan instead of doubletag to disable VLAN mode) Attribute 3 (int): bc_storm_protect (Global broadcast storm protection (0:Disable, 1:64 blocks, 2:96 blocks, 3:128 blocks)) Attribute 4 (int): led_frequency (LED Flash frequency (0:30mS, 1:60mS, 2:240mS, 3:480mS)) Attribute 5 (none): apply (Activate changes in the hardware) Attribute 6 (none): reset (Reset the switch) --vlan Attribute 1 (ports): ports (VLAN port mapping) --port Attribute 1 (int): disable (Port state (1:disabled)) Attribute 2 (int): doubletag (Double tagging for incoming vlan packets (1:enabled)) Attribute 3 (int): untag (Untag (1:strip outgoing vlan tag)) Attribute 4 (int): led (LED mode (0:link, 1:100m, 2:duplex, 3:activity, 4:collision, 5:linkact, 6:duplcoll, 7:10mact, 8:100mact, 10:blink, 11:off, 12:on)) Attribute 5 (int): lan (HW port group (0:wan, 1:lan)) Attribute 6 (int): recv_bad (Receive bad packet counter) Attribute 7 (int): recv_good (Receive good packet counter) Attribute 8 (int): tr_bad (Transmit bad packet counter. rt5350 only) Attribute 9 (int): tr_good (Transmit good packet counter. rt5350 only) Attribute 10 (int): pvid (Primary VLAN ID) Attribute 11 (string): link (Get port link information)
At first glance, hopefully, we can manage not only VLANs, which is vital for distinguishing LAN and WAN subnet traffic, but also program LEDs.
Do
>swconfig dev rt305x port 4 set led 12 >swconfig dev rt305x set apply
and ... nothing happens. Apparently the problem is somewhere deeper in the drivers. Well, that OpenWRT open source. Go to the
git-repository , find the source of the driver there and see
446 static void esw_hw_init(struct rt305x_esw *esw) 447 { 448 int i; 449 u8 port_disable = 0; 450 u8 port_map = RT305X_ESW_PMAP_LLLLLL; 451 452 453 esw_w32(esw, 0xC8A07850, RT305X_ESW_REG_FCT0); 454 esw_w32(esw, 0x00000000, RT305X_ESW_REG_SGC2);
it seems to use voodoo magic. And yet - it is immediately clear from the driver code that we cannot understand it without detailed documentation on the switch registers. But it is clear that the driver parameters are not set through the arguments of the modprobe command, but, apparently, through the lines compiled into the kernel:
1431 reg_init = of_get_property(np, "ralink,led_polarity", NULL);
Okay, let's postpone the source and try to enter from the other side. All three routers — Upvel UR-322N4G, Hame MPR-A1, and Zyxel Keenetic 4G II — are dual port. Surely among the clouds of supported models on the Ralink 5350 there are five-port models. Go to
WikiDev and find, for example, D-Link 320 NRU B1. Five-port router, one USB port - what you need. We download the firmware, load the router into memory, run it. LEDs work as expected. Very interesting. We will flash on it, but for now let's try to find the difference between the OpenWRT for the Hame MPR-A1 and the D-Link 320 NRU B1. The difference is to be found in the profiles of the assembly -
DTS . For example, the led_polarity parameter for Hame is not specified, and for D-Link it is 0x17. And I thought that polarity is only direct and reverse! Again we climb into the source of the driver, we find a constant there
#define RT5350_EWS_REG_LED_POLARITY 0x168
find the way to set the polarity
565 566 esw_w32(esw, esw->reg_led_polarity & 0x1F, RT5350_EWS_REG_LED_POLARITY);
and again we are convinced that without a description of the switch registers we have nothing to catch.
We found out that the firmware from D-Link DIR-320 NRU B1 is best suited for our router. Now you need to flash. You may have noticed that to test the firmware, I selected files with the word uImage in the name. This file contains only the kernel image and file system, loaded into RAM and read-only. Such an image can be run directly from the memory, but for the firmware it is not very suitable - the settings in this image are simply nowhere to be stored. Therefore, for the firmware, we will select an image with the sysupgrade extension - at the end of this image, the JFFS2 partition is attached, which will store the changes we made to the file system of the router. Therefore, the sysupgrade image cannot start from memory without firmware on the USB flash drive.
It is very good that the Upvel UR-313N4G 8Mb flash drive, after installation we will have a little more than 4MB for additional packages. But in TP-Link TR-ML3420 a flash drive with 4 MB and free space there - the cat cried.
Reboot the router, press 2, specify the name of the firmware and sew. So, everything seems to be fine: the interfaces have risen, the LEDs blink, in general, life is boiling. Have you forgotten that our main goal was to make the router work with a Megafon M21-4 modem? We plug the modem into the USB port, look at the dmesg and ... nothing. That is, absolutely nothing. There are two options - either the kernel did not see any hellish bus on which a USB port is hanging inside the chip (we’re not helping), or forgot to add drivers for this port to the firmware. In the D-Link 320 NRU B1, there is a USB port, so the second option is more likely. We google “OpenWRT usb support”, configure the WAN port on the router so that the firmware can access the Internet and install packages.
>opkg update >opkg install kmod-usb2 >opkg install kmod-usb-ohci
In that order, because the kmod-usb2 module must be loaded before kmod-usb-ohci
The following lines appear in the console:
[ 121.570000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 121.600000] ehci-platform: EHCI generic platform driver [ 121.810000] phy phy-usbphy.0: remote usb device wakeup disabled [ 121.830000] phy phy-usbphy.0: UTMI 16bit 30MHz [ 121.840000] ehci-platform 101c0000.ehci: EHCI Host Controller [ 121.850000] ehci-platform 101c0000.ehci: new USB bus registered, assigned bus number 1 [ 121.860000] ehci-platform 101c0000.ehci: irq 26, io mem 0x101c0000 [ 121.900000] ehci-platform 101c0000.ehci: USB 2.0 started, EHCI 1.00 [ 121.910000] hub 1-0:1.0: USB hub found [ 121.920000] hub 1-0:1.0: 1 port detected [ 122.300000] usb 1-1: new high-speed USB device number 2 using ehci-platform [ 151.680000] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 151.710000] ohci-platform: OHCI generic platform driver [ 151.720000] ohci-platform 101c1000.ohci: Generic Platform OHCI controller [ 151.730000] ohci-platform 101c1000.ohci: new USB bus registered, assigned bus number 2 [ 151.750000] ohci-platform 101c1000.ohci: irq 26, io mem 0x101c1000 [ 151.820000] hub 2-0:1.0: USB hub found [ 151.830000] hub 2-0:1.0: 1 port detected
Wow, the system saw the device on the USB bus, so we continue.
Now we put the package, which, when the modem is connected, will send a “magic sequence” to it, switching the modem from the CD-ROM / TF Card mode to the CD-ROM / TF Card mode + 3 COM ports.
>opkg install usb-modeswitch
In the console we see the following:
[ 278.230000] usb 1-1: USB disconnect, device number 2 [ 278.990000] usb 1-1: new high-speed USB device number 3 using ehci-platform
So, usb-modeswitch worked - sent a command to the modem, and the modem then disappeared from the USB bus and appeared there as another device.
We put two packages with drivers that will see the COM ports and make them available to the system.
>opkg install kmod-usb-serial kmod-usb-serial-options
[ 326.530000] usbcore: registered new interface driver usbserial [ 326.540000] usbcore: registered new interface driver usbserial_generic [ 326.550000] usbserial: USB Serial support registered for generic [ 326.820000] usbcore: registered new interface driver option [ 326.830000] usbserial: USB Serial support registered for GSM modem (1-port) [ 326.850000] option 1-1:1.0: GSM modem (1-port) converter detected [ 326.860000] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB0 [ 326.870000] option 1-1:1.2: GSM modem (1-port) converter detected [ 326.890000] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB1 [ 326.900000] option 1-1:1.3: GSM modem (1-port) converter detected [ 326.910000] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB2
It can be seen that the modem was defined correctly and 3 COM ports appeared in the system.
We put the package necessary to create sending commands to 3G modems and an extension for the Web interface:
>opkg install comgt luci-proto-3g
We go into the Web-interface, configure 3G, specify / dev / ttyUSB0 as the port, everything works.
Now take up the LEDs. First, install the kmod-ledtrig-usbdev package - it will allow us to control the LEDs depending on the availability of devices on the USB bus. Go to the Web interface on the System-> LED Configuration tab and define there two LEDs:
Name: usb LED Name: d-link:green:usb Trigger: usbdev USB Device: 1-1 (HUAWEI - HUAWEI Mobile) Name: wifi LED Name: rt2800:phy0:radio Trigger: netdev Default state: on Device: wlan0 Trigger Mode: Link On, Transmit, Receive
and click the Save / Apply button
At this point, the configuration of the router is completed.
It is worth adding that the “usb” LED refers to a specific device address on the USB bus (1-1), and therefore, if the address changes, the LED will not work.
Telnet Firmware
But now it's time to find out whether it is possible to flash a router without access to the UART. To begin with, let's try the recovery mode - it usually turns on if the power is applied while the reset button is held down. We clamp, feed and look in the console: nothing. Mode is not available. Roll back through the bootloader to the original firmware and look at the boot log:
: System Boot system code via Flash.
It can be seen that the u-boot reads 64 bytes, starting at address 0x00050000 (
fathers , explain why in the bc050000 log?). Starting from 0x00050000 on MTD, the uImage image is flashed and in its first 64 bytes there is a header. The size of the image, its future address in RAM and the entry point are taken from the header, after which the image is unpacked into RAM and control is transferred to the entry point.
Let's wait until the original firmware is loaded and look at the log:
mtd .name = raspi, .size = 0x00800000 (8M) .erasesize = 0x00010000 (64K) .numeraseregions = 0 Creating 6 MTD partitions on "raspi": 0x00000000-0x00800000 : "ALL" 0x00000000-0x00030000 : "Bootloader" 0x00030000-0x00040000 : "Config" 0x00040000-0x00050000 : "Factory" 0x00050000-0x007d0000 : "Kernel" 0x007d0000-0x00800000 : "RW_FS"
Starting at address 0x00050000, the Kernel section begins, and this address suspiciously matches the address from the u-boot log. So, this is where the router firmware is stored, here we will write OpenWRT. Let's look at which devices the partitions are mapped to:
cat /proc/mtd dev: size erasesize name mtd0: 00800000 00010000 "ALL" mtd1: 00030000 00010000 "Bootloader" mtd2: 00010000 00010000 "Config" mtd3: 00010000 00010000 "Factory" mtd4: 00780000 00010000 "Kernel" mtd5: 00030000 00010000 "RW_FS"
The size of the Kernel partition is 7680 Kb, and the OpenWRT image takes about 3.5 MB, therefore, you can flash without fear that the new firmware will not fit into the old partition.
Let's see how much free memory we have:
>free total used free shared buffers Mem: 28300 19952 8348 0 0 Swap: 0 0 0 Total: 28300 19952 8348
We need about 3.5 MB and we have them.
Run atftpd on the workstation (address 192.168.10.100) and copy the firmware into the router's RAM:
>tftp -l dir-320.bin -r dir-320.bin -g 192.168.10.100
First, erase the RW_FS section. Maybe this should not be done, but just in case, we will reinsure ourselves:
> mtd_write erase /dev/mtd5 Unlocking /dev/mtd5 ... Erasing /dev/mtd5 ... Erase char is 255
Now write the firmware:
>mtd_write -r write dir-320.bin /dev/mdt4 Unlocking /dev/mtd4 ... Writing from dir-320.cc.sys.bin to /dev/mtd4 ...
The -r switch means that after the command is executed, the router will reboot. There is no need to adjust the partition table, because it exists only inside the Linux kernel.
After rebooting, go to the Web interface, put the packages kmod-usb2, kmod-usb-ohci, kmod-usb-serial, kmod-usb-serial-option, kmod-ledtrig-usbdev, usb-modeswitch, comgt, luci-proto- 3g, we configure interfaces and LEDs.
The router is stitched, you can open the cookies and pour the tea.