给OpenWRT固件增加USB功能

/ 3评 / 0

作为斐讯 P2P 的受害者,我一直使用着斐讯的路由器设备。

如今仍在服役的设备有

K2P 由于是硬改版,因此适用的 firmware 一直都只能自己编译。
K3 的设计很棒,但是也同样由于设计的问题,散热性能非常差,CPU 动辄 80℃ 以上。

Anyway ,瑕不掩瑜,斐讯虽然让大家受害不轻,但它的确开启了智能路由器的新时代。

随着 Linux kernel 的更新,虽然 K2P 依旧能够使用,但性能开始下降,当前仍在售卖的可刷第三方固件的路由器中,360T7 的性价比很高,可市面上绝大多数的改版仅仅只硬改了 RAM 而已,7981 的 CPU 本身是支持 USB 功能的,但是几乎没有多少厂家愿意在设计之初就把 USB 给计划进去。

一款路由自带 USB 的好处是不言而喻的,比如你可以挂载一块外置硬盘来实现轻 NAS 的功能,这样简单地使用 Aria2 下载比较大点的东西就不至于一直开着电脑对不对?或者像我一样,一个音乐发烧友,到家就喜欢用 Airplay 听歌的人,给路由器插上一块最便宜的那种 USB 声卡后,连接好音响就可以用 iOS 设备来推送音乐到音响了。

360T7 的二手改版(仅增加 RAM)交易价格大致在 160 元 RMB 左右,而加上 USB 的大致在 200 RMB 出口,并且还不太好找,皇天不负有心人,我还是找到一家。

收到机器,根据以前的经验编译了带 USB 的固件,刷入后却发现无法识别任何插入的 USB 设备,但是卖家发来的固件却是可以正常识别 USB 设备的,这说明我学艺不精,一定还有我没搞懂的地方。

对比了两种固件的差异,几乎是没有的,任何跟 USB 有关的选项我都是开启了并且编译进了固件中的,看来问题不是出在软件包上。

Lean的 GitHub 论坛里,其实根本就是无人维护的状态,只有恩山论坛的网友热衷于技术交流和互相帮助,在恩山经过搜寻和询问,经高人指点才了解到设备树这个概念。

找了两篇关于设备树的介绍文章,Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)不懂Linux Device Tree,被新人嘲笑之后,含泪写完

看完后大致了解了原理。

也就是说,要想给原本不支持 USB 的设备加上 USB 并且还能正常使用的前提条件还有设备树 DTS 这个步骤。

然后我尝试了在 immortalwrt 的相应位置修改了 mt7981 的 DTS 文件,最后编译出来的固件完美支持了自动挂载 U盘,但也许是因为第一次测试,我只是胡乱选中了 USB 相关的选项,其余的并未仔细检查,后来才发现固件不带 WiFi。

又尝试了 hanwckf 的 immortalwrt-mt798x 项目,但试验失败,还需要时间继续调试。

最后尝试了修改 lean 的 lede 源码,编译出了带 USB 且 WiFi 也正常的 360T7 USB 固件。

测试 U盘能自动挂载识别,USB 声卡也正常,此刻我正使用着 Pandora radio 呢。

针对于使用 lean 源码的人,请用以下方法进行修改:

cd lede/target/linux/mediatek/dts/
cp mt7981b-qihoo-360t7.dts mt7981b-qihoo-360t7.dts.bak
nano mt7981b-qihoo-360t7.dts

编辑 mt7981b-qihoo-360t7.dts 文件,找到

        leds {
                compatible = "gpio-leds";

                led_status_red: red {
                        label = "red:status";
                        gpios = <&pio 3 GPIO_ACTIVE_LOW>;
                };

                led_status_green: green {
                        label = "green:status";
                        gpios = <&pio 7 GPIO_ACTIVE_LOW>;
                };
        };

在下面增加如下代码:

        usb_vbus: regulator-usb-vbus {
                compatible = "regulator-fixed";
                regulator-name = "usb_vbus";
                regulator-min-microvolt = <5000000>;
                regulator-max-microvolt = <5000000>;
                gpio = <&pio 12 GPIO_ACTIVE_HIGH>;
                enable-active-high;
                regulator-boot-on;
        };

移动到最末端,增加如下代码:

&usb_phy {
        status = "okay";
};

&xhci {
        vbus-supply = <&usb_vbus>;

        status = "okay";
};

保存退出编辑状态。
如往常一样开始编译即可。

给出基于当前时间 2023-09-03 的完整代码:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

#include "mt7981.dtsi"

/ {
        model = "Qihoo 360T7";
        compatible = "qihoo,360t7", "mediatek,mt7981";

        aliases {
                serial0 = &uart0;

                led-boot = &led_status_red;
                led-failsafe = &led_status_red;
                led-running = &led_status_green;
                led-upgrade = &led_status_green;
        };

        chosen {
                stdout-path = "serial0:115200n8";
        };

        memory {
                reg = <0 0x40000000 0 0x10000000>;
        };

        gpio-keys {
                compatible = "gpio-keys";

                reset {
                        label = "reset";
                        linux,code = <KEY_RESTART>;
                        gpios = <&pio 1 GPIO_ACTIVE_LOW>;
                };

                wps {
                        label = "wps";
                        linux,code = <KEY_WPS_BUTTON>;
                        gpios = <&pio 0 GPIO_ACTIVE_LOW>;
                };
        };

        leds {
                compatible = "gpio-leds";

                led_status_red: red {
                        label = "red:status";
                        gpios = <&pio 3 GPIO_ACTIVE_LOW>;
                };

                led_status_green: green {
                        label = "green:status";
                        gpios = <&pio 7 GPIO_ACTIVE_LOW>;
                };
        };

        usb_vbus: regulator-usb-vbus {
                compatible = "regulator-fixed";
                regulator-name = "usb_vbus";
                regulator-min-microvolt = <5000000>;
                regulator-max-microvolt = <5000000>;
                gpio = <&pio 12 GPIO_ACTIVE_HIGH>;
                enable-active-high;
                regulator-boot-on;
        };

};

ð {
        status = "okay";

        gmac0: mac@0 {
                compatible = "mediatek,eth-mac";
                reg = <0>;
                phy-mode = "2500base-x";

                fixed-link {
                        speed = <2500>;
                        full-duplex;
                        pause;
                };
        };
};

&mdio_bus {
        switch: switch@0 {
                compatible = "mediatek,mt7531";
                reg = <31>;
                reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
                interrupt-controller;
                #interrupt-cells = <1>;
                interrupt-parent = <&pio>;
                interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
        };
};

&spi0 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi0_flash_pins>;
        status = "okay";

        spi_nand@0 {
                compatible = "spi-nand";
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <0>;

                spi-max-frequency = <52000000>;
                spi-tx-buswidth = <4>;
                spi-rx-buswidth = <4>;

                mediatek,nmbm;
                mediatek,bmt-max-ratio = <1>;
                mediatek,bmt-max-reserved-blocks = <64>;

                partitions {
                        compatible = "fixed-partitions";
                        #address-cells = <1>;
                        #size-cells = <1>;

                        partition@0 {
                                label = "bl2";
                                reg = <0x0000000 0x0100000>;
                                read-only;
                        };

                        partition@100000 {
                                label = "u-boot-env";
                                reg = <0x0100000 0x0080000>;
                        };

                        factory: partition@180000 {
                                label = "Factory";
                                reg = <0x0180000 0x0200000>;
                                read-only;
                        };

                        partition@380000 {
                                label = "fip";
                                reg = <0x0380000 0x0200000>;
                                read-only;
                        };

                        partition@580000 {
                                label = "ubi";
                                reg = <0x0580000 0x6c00000>;
                        };

                        partition@7180000 {
                                label = "config";
                                reg = <0x7180000 0x0100000>;
                                read-only;
                        };

                        partition@7280000 {
                                label = "factory";
                                reg = <0x7280000 0x0080000>;
                                read-only;
                        };

                        partition@7300000 {
                                label = "log";
                                reg = <0x7300000 0x0700000>;
                                read-only;
                        };
                };
        };
};

&switch {
        ports {
                #address-cells = <1>;
                #size-cells = <0>;

                port@0 {
                        reg = <0>;
                        label = "lan3";
                };

                port@1 {
                        reg = <1>;
                        label = "lan2";
                };

                port@2 {
                        reg = <2>;
                        label = "lan1";
                };

                port@3 {
                        reg = <3>;
                        label = "wan";
                };

                port@6 {
                        reg = <6>;
                        label = "cpu";
                        ethernet = <&gmac0>;
                        phy-mode = "2500base-x";

                        fixed-link {
                                speed = <2500>;
                                full-duplex;
                                pause;
                        };
                };
        };
};

&pio {
        spi0_flash_pins: spi0-pins {
                mux {
                        function = "spi";
                        groups = "spi0", "spi0_wp_hold";
                };

                conf-pu {
                        pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
                        drive-strength = <8>;
                        mediatek,pull-up-adv = <0>; /* bias-disable */
                };

                conf-pd {
                        pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
                        drive-strength = <8>;
                        mediatek,pull-up-adv = <0>; /* bias-disable */
                };
        };
};

&uart0 {
        status = "okay";
};

&watchdog {
        status = "okay";
};

&wifi {
        status = "okay";

        mediatek,mtd-eeprom = <&factory 0x0>;
};

&usb_phy {
        status = "okay";
};

&xhci {
        vbus-supply = <&usb_vbus>;

        status = "okay";
};

以上便是如何在 lean 的源码中通过修改设备树 DTS 来给 360T7 这款不带 USB 的路由器增加 USB 功能的方法。

最后,给出我自己编译的基于 Lean 源码编译的 360T7 USB 固件:

Lean 源码 360T7 USB 固件

《“给OpenWRT固件增加USB功能”》 有 3 条评论

  1. user说道:

    自己编译两天,搞不定,心累~
    CMCC RAX3000M好像这款自带usb,规格跟360t7一样,打算放弃,买这款试试

  2. user说道:

    感谢,非常好!我也是这个路由器,512+usb,200多点拿下,之前一直没有找到可以挂usb的固件!这个用起来挺顺手,唯一就是[全能推送]没有[Web 登录提醒]!设置了,也不起作用,恩山上有人讲这是lean固件的问题,用logread查日志的确没有记录,有没有时间重新编译一个?我之前自己编译过,但是系统现在换了mac,没有环境

    • weeper说道:

      @user 抱歉,我是一个懒散的博主,没想到你的留言居然是去年发的了。

      全能推送我一直没打开过web登陆提醒,刚刚试了一下,ImmortalWrt的源码是可以收到web登陆提醒的。我用的是bark,ios上的app。

      另外呢,我现在其实把源码换成L大的基于ImmortalWrt的MT7981的源码了,一套源码解决360T7和RAX3000M的问题。

      RAX3000M我也买了NAND版的在使用,不过这个机器说实话给我的感觉不如360T7,温度高是一方面,另外一个诡异的问题就是airplay找不到服务,而airplay才是我花高价买USB款路由器的最初原因。

      能帮到你,就很好。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注