HamsterBear Linux 啟用USB Gadget RNDIS


HamsterBear Linux 啟用USB Gadget RNDIS

環境

  • Soc - F1C200s
  • Kernel版本 - 主線 5.17.0

適配過程供參考

kernel

修改 arch/arm/boot/dts/suniv-f1c100s.dtsi
在soc節點添加如下節點

                usb_otg: usb@1c13000 {
                        compatible = "allwinner,suniv-musb"; // compatible reg等因soc而異
                        reg = <0x01c13000 0x0400>;
                        clocks = <&ccu CLK_BUS_OTG>;
                        resets = <&ccu RST_BUS_OTG>;
                        interrupts = <26>;
                        interrupt-names = "mc";
                        phys = <&usbphy 0>;
                        phy-names = "usb";
                        extcon = <&usbphy 0>;
                        allwinner,sram = <&otg_sram 1>;
                        status = "disabled";
                };

                usbphy: phy@1c13400 {
                        compatible = "allwinner,suniv-usb-phy";  // 同上
                        reg = <0x01c13400 0x10>;
                        reg-names = "phy_ctrl";
                        clocks = <&ccu CLK_USB_PHY0>;
                        clock-names = "usb0_phy";
                        resets = <&ccu RST_USB_PHY0>;
                        reset-names = "usb0_reset";
                        #phy-cells = <1>;
                        status = "disabled";
                };

對應如下兩個驅動文件:
drivers/phy/allwinner/phy-sun4i-usb.c
drivers/usb/musb/sunxi.c

arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts 中引用結點如下

&otg_sram {
        status = "okay";
};

&usb_otg {
        dr_mode = "otg";
        status = "okay";
};

&usbphy {
        usb0_id_det-gpio = <&pio 4 2 GPIO_ACTIVE_HIGH>; /* PE2 */  // USB ID腳 需要根據查看板子原理圖確定
        status = "okay";
};

配置kernel config

定位到 Device drivers --> USB support
image

配置如上

然后選擇 USB Gadget 編譯進內核
image

USB Gadget 的配置
image

進入 USB Gadget precomposed configurations,配置如下
image

選擇了USB Ethernet Gadget USB以太網
USB Mass Storage Gadget USB大容量存儲設備
USB Serial Gadget USB虛擬串口編譯為模塊

ok, 配置完之后重新編譯內核+模塊

  • 拷貝內核到sd卡boot分區
  • 拷貝驅動文件到文件系統/lib/modules

驅動文件打包參考:

INSTALL_MOD_PATH=./tmp make modules_install

rootfs

拷貝完成后連接到板子串口,執行modprobe加載驅動文件

modprobe g_ether

此時,不出意外的情況下(虛擬機會詢問新設備連接位置),windows pc機這邊會識別到一個端口(COM 和 LPT)

image

為什么會是一個端口?,可參考如下回答

最初由MS論壇上的dlech發表
Linux rndis小工具函數的USB類為2,子類為2,與usbser.inf文件中的“USB \ Class_02&SubClass_02”相匹配。這就是為什么對於某些人來說,他們的設備最初被檢測為COM端口而不是RNDIS。
通過一些快速的Google搜索,似乎有些VM用戶沒有遇到此問題,可能是因為類/子類對在呈現給訪客時被篡改了?

需要將驅動替換為 Windows 10 signed RNDIS driver for USBNetwork,可參考如下鏈接1樓的解決方案
https://www.mobileread.com/forums/showthread.php?p=3283986

如果你訪問不了上面的鏈接,這里提供一份備用驅動文件鏈接
kindle_rndis.inf_amd64-v1.0.0.1.zip

順便貼下怎么用吧

  1. Download & Unzip attachment kindle_rndis.inf_amd64-v1.0.0.1.zip
  2. R-click "5-runasadmin_register-CA-cer.cmd" and "Run as administrator"*
  3. In Device Manager, expand "Ports (COM & LPT)", R-click "Serial USB device (COM3)" > Update Driver Software...
  4. Browse for my computer for driver software > Select extract folder

替換完成之后會變成這個設備 Kindle USB RNDIS Device

image

然后回到板子這邊

ifconfig usb0 up
ifconfig usb0 192.168.1.101

然后pc這邊來到 控制面板 --> 網絡和Internet --> 網絡連接,亦可直接搜索查看網絡連接
image

手動分配下ip地址為 192.168.1.100

(這里因為我給usb共享了網絡,所以此處ip為192.168.137.1,為網關地址)

image

然后在板子這邊 ping 192.168.1.100 已經可以ping通了

更多的玩法

1. 共享pc網絡給板子

image

pc中選中一個有效的網絡連接, 然后右鍵屬性 - 共享,勾選允許其他網絡用戶通過此計算機的Internet連接來連接,選擇usb網卡,
(如果手動配置過ip,會提示ip信息覆蓋)
然后回到板子,執行

udhcpc -i usb0

此時已經得到了動態分配的ip地址,/etc/resolv.conf中添加dns服務器nameserver 114.114.114.114,並嘗試訪問外網
image

我想只用一根usb線就能調試板子,就像beaglebone black那樣,真酷,我應該怎么做?

添加/etc/init.d/S51usbifup,增加755權限,腳本如下,

(udhcpc可能會導致腳本阻塞,視情況可在啟動后執行)

#!/bin/sh
#
# usbifup        Starts usb gadget rndis.
#

umask 077

start() {
        printf "Starting USB Gadget RNDIS: "
        modprobe g_ether
        ifconfig usb0 up
        udhcpc -i usb0
        echo "OK"
}
stop() {
        printf "Stopping USB Gadget RNDIS: "
        rmmod g_ether
        echo "OK"
}
restart() {
        stop
        start
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        restart
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

這樣,啟動后便會自動加載驅動,pc機這邊控制台執行

arp -a | findstr "137"
接口: 192.168.137.1 --- 0x5c
  192.168.137.115       36-bd-3d-9b-31-e0     靜態
  192.168.137.255       ff-ff-ff-ff-ff-ff     靜態

192.168.137.115就是自動分配給板子的ip

使用ssh登錄到板子ssh root@192.168.137.115

root用戶登陸需要修改/etc/ssh/sshd_config,添加PermitRootLogin yes

image

2. 使用 VNC 連接到 X 桌面環境

針對 F1c200s suniv系列的修改

需要修改適配 phy 和 musb 的代碼,其實全志官方4.15版本的內核早就修改過了,但不知道為什么沒有合並到主線里。

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 788dd5c..44dcffa 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -99,6 +99,7 @@
 #define POLL_TIME                      msecs_to_jiffies(250)

 enum sun4i_usb_phy_type {
+       suniv_phy,
        sun4i_a10_phy,
        sun6i_a31_phy,
        sun8i_a33_phy,
@@ -857,6 +858,14 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
        return 0;
 }

+static const struct sun4i_usb_phy_cfg suniv_cfg = {
+       .num_phys = 1,
+       .type = suniv_phy,
+       .disc_thresh = 3,
+       .phyctl_offset = REG_PHYCTL_A10,
+       .dedicated_clocks = true,
+};
+
 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
        .num_phys = 3,
        .type = sun4i_a10_phy,
@@ -970,6 +979,7 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
 };

 static const struct of_device_id sun4i_usb_phy_of_match[] = {
+       { .compatible = "allwinner,suniv-usb-phy", .data = &suniv_cfg },
        { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
        { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
        { .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg },
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 961c858..85542d1 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -722,14 +722,16 @@ static int sunxi_musb_probe(struct platform_device *pdev)
        INIT_WORK(&glue->work, sunxi_musb_work);
        glue->host_nb.notifier_call = sunxi_musb_host_notifier;

-       if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb"))
+       if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb") ||
+           of_device_is_compatible(np, "allwinner,suniv-musb"))
                set_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags);

        if (of_device_is_compatible(np, "allwinner,sun6i-a31-musb"))
                set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);

        if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb") ||
-           of_device_is_compatible(np, "allwinner,sun8i-h3-musb")) {
+           of_device_is_compatible(np, "allwinner,sun8i-h3-musb") ||
+           of_device_is_compatible(np, "allwinner,suniv-musb")) {
                set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
                set_bit(SUNXI_MUSB_FL_NO_CONFIGDATA, &glue->flags);
        }
@@ -822,6 +824,7 @@ static int sunxi_musb_remove(struct platform_device *pdev)
 }

 static const struct of_device_id sunxi_musb_match[] = {
+       { .compatible = "allwinner,suniv-musb", },
        { .compatible = "allwinner,sun4i-a10-musb", },
        { .compatible = "allwinner,sun6i-a31-musb", },
        { .compatible = "allwinner,sun8i-a33-musb", },


參考資料

Windows 10 signed RNDIS driver for USBNetwork
測試測試 g_serial / g_ether USB Gadget (RNDIS)
小白自制Linux開發板 七. USB驅動配置


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM