HamsterBear Linux 啟用USB Gadget RNDIS
環境
Soc
- F1C200sKernel版本
- 主線 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
配置如上
然后選擇 USB Gadget
編譯進內核
USB Gadget
的配置
進入 USB Gadget precomposed configurations
,配置如下
選擇了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)
為什么會是一個端口?,可參考如下回答
最初由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
順便貼下怎么用吧
- Download & Unzip attachment kindle_rndis.inf_amd64-v1.0.0.1.zip
- R-click "5-runasadmin_register-CA-cer.cmd" and "Run as administrator"*
- In Device Manager, expand "Ports (COM & LPT)", R-click "Serial USB device (COM3)" > Update Driver Software...
- Browse for my computer for driver software > Select extract folder
替換完成之后會變成這個設備 Kindle USB RNDIS Device
然后回到板子這邊
ifconfig usb0 up
ifconfig usb0 192.168.1.101
然后pc這邊來到 控制面板 --> 網絡和Internet --> 網絡連接,亦可直接搜索查看網絡連接
手動分配下ip地址為 192.168.1.100
(這里因為我給usb共享了網絡,所以此處ip為192.168.137.1,為網關地址)
然后在板子這邊 ping 192.168.1.100 已經可以ping通了
更多的玩法
1. 共享pc網絡給板子
pc中選中一個有效的網絡連接, 然后右鍵屬性 - 共享,勾選允許其他網絡用戶通過此計算機的Internet連接來連接
,選擇usb網卡,
(如果手動配置過ip,會提示ip信息覆蓋)
然后回到板子,執行
udhcpc -i usb0
此時已經得到了動態分配的ip地址,/etc/resolv.conf
中添加dns服務器nameserver 114.114.114.114
,並嘗試訪問外網
我想只用一根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
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驅動配置