https://www.mobileread.com/forums/showthread.php?p=3283986
目錄結(jié)構(gòu)說明
一、環(huán)境說明
1霹菊、環(huán)境介紹
2空猜、RNDIS介紹
3、網(wǎng)絡(luò)環(huán)境配置
4、編譯腳本說明
二粱坤、uboot的RNDIS測試
1、配置編譯uboot的RNDIS功能
2瓷产、測試uboot的RNDIS網(wǎng)絡(luò)是否正常
三站玄、kernel的RNDIS測試
1、配置編譯kernel的RNDIS功能
2濒旦、測試kernel的RNDIS網(wǎng)絡(luò)是否正常
3株旷、測試kernel的RNDIS網(wǎng)絡(luò)的nfs功能是否正常
四、綜合測試RNDIS網(wǎng)絡(luò)
1尔邓、通過uboot手動測試tftp加載kernel啟動
2晾剖、通過uboot手動測試tftp加載kernel掛載nfs啟動
3、把測試啟動的nfs命令轉(zhuǎn)換成boot.scr啟動腳本
一梯嗽、環(huán)境說明
1齿尽、環(huán)境介紹
?? 首先這里我們需要安裝一些基礎(chǔ)的編譯環(huán)境,安裝tftp服務(wù)器灯节,安裝nfs服務(wù)器等循头,這里我們可以參考文章《用buildroot編譯整個系統(tǒng),用qemu仿真vexpressa9》中的環(huán)境準備章節(jié)炎疆,自行安裝相關(guān)服務(wù)卡骂,在這里不展開。
2磷雇、RNDIS介紹
?? RNDIS是指Remote NDIS偿警,基于USB實現(xiàn)RNDIS實際上就是TCP/IP over USB,就是在USB設(shè)備上跑TCP/IP唯笙,讓USB設(shè)備看上去像一塊網(wǎng)卡螟蒸。簡單的來說,就是通過USB模擬了一個網(wǎng)卡崩掘,這樣我們可以通過這個網(wǎng)卡實現(xiàn)和虛擬機的聯(lián)機七嫌,以及正常的網(wǎng)絡(luò)訪問。相關(guān)內(nèi)容可以參考網(wǎng)站https://zhidao.baidu.com/question/1930394656632188907.html
3苞慢、網(wǎng)絡(luò)環(huán)境配置
?? 1诵原、這里我們實現(xiàn)的網(wǎng)絡(luò)環(huán)境配置如下圖所示。在win10主機上虛擬一個網(wǎng)橋,win10主機和Ubuntu虛擬機通過這個網(wǎng)橋連接到無線網(wǎng)絡(luò)绍赛,訪問外網(wǎng)蔓纠。同時orangepione開發(fā)板則通過USB實現(xiàn)與win10主機的RNDIS網(wǎng)絡(luò)共享。通過主機訪問外網(wǎng)吗蚌。
?? 2腿倚、通過win10的hyperv創(chuàng)建虛擬網(wǎng)橋,把虛擬機的網(wǎng)絡(luò)和主機的網(wǎng)絡(luò)通過網(wǎng)橋橋接起來蚯妇。在hyperv管理器上面找的虛擬交換機管理器敷燎,并點擊新建虛擬交換機網(wǎng)絡(luò),這里名字隨意就好箩言,我這里的名字叫做hyper-net硬贯,相關(guān)配置如下圖所示,這里要選擇一個可以上外網(wǎng)的網(wǎng)卡進行橋接
?? 3陨收、在編譯好后饭豹,在開發(fā)板上電并進行網(wǎng)絡(luò)通信的時候會在設(shè)備管理器出現(xiàn)RNDIS相管的提示信息,如果沒有驅(qū)動畏吓,則按照https://www.mobileread.com/forums/showthread.php?p=3283986網(wǎng)址上的驅(qū)動方式對RNDIS進行驅(qū)動墨状,先下載kindle_rndis.inf_amd64-v1.0.0.1.zip并解壓,再執(zhí)行第5個cmd腳本注冊驅(qū)動簽名菲饼,然后再設(shè)備管理器更新驅(qū)動管理程序肾砂,選擇下載的驅(qū)動目錄進行驅(qū)動,如果驅(qū)動成功宏悦,則在設(shè)備管理器會顯示下面的驅(qū)動
??4镐确、設(shè)置和主機的網(wǎng)絡(luò)共享,在驅(qū)動成功后饼煞,需要在更改適配器選項界面源葫,設(shè)置共享配置,這里選擇共享的是之前hyperv橋接的網(wǎng)卡砖瞧,這里建議把hyperv橋接網(wǎng)卡的ip設(shè)置為靜態(tài)ip息堂,后面共享的網(wǎng)卡需要通過該網(wǎng)卡的ip進行dns解析,配置如下圖所示
這里如果配置不成功块促,后面會不能正常通訊
4荣堰、編譯腳本說明
這里我們和還是使用文章《用buildroot編譯整個系統(tǒng),用qemu仿真vexpressa9》提到的buildroot環(huán)境進行開發(fā)竭翠。但是我們這里稍微改變了一下在orangepione目錄下的腳本build.sh振坚,腳本的主要功能是編譯,和拷貝文件到tftp目錄斋扰,以及修改生成boot.scr文件渡八,可能需要根據(jù)實際的情況進行相關(guān)的調(diào)整
#! /bin/bash
NPWD=`realpath .`
echo $NPWD
if [ $1_x == cp_x ];then
cp $NPWD/rootfs/build/linux-custom/arch/arm/boot/zImage ~/tftp
cp $NPWD/rootfs/build/linux-custom/arch/arm/boot/dts/sun8i-h3-orangepi-one.dtb ~/tftp
elif [ $1_x == env_x ];then
/home/vencol/code/buildroot/host/bin/mkimage -C none -A arm -T script -d $NPWD/boot.cmd $NPWD/boot.scr
cp $NPWD/boot.scr $NPWD/rootfs/images/boot.scr
else
cd $NPWD/../buildroot
mkdir -p $NPWD/rootfs
make O=$NPWD/rootfs ARCH=arm $1
fi
二啃洋、uboot的RNDIS測試
1、配置編譯uboot的RNDIS功能
- 在orangepi目錄執(zhí)行
./build.sh uboot-menuconfig
會彈出uboot的menuconfig的配置界面屎鳍,我們的配置選項如下 Device Drivers --->USB support --->
EHCI HCD (USB 2.0) support --->CONFIG_USB_EHCI_HCD
Support for generic EHCI USB controller--->CONFIG_USB_EHCI_GENERIC
MUSB gadget mode support--->CONFIG_USB_MUSB_GADGET
Enable sunxi OTG / DRC USB controller--->CONFIG_USB_MUSB_SUNXI
Disable MUSB bulk split/combine--->CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
Disable DMA (always use PIO)--->CONFIG_USB_MUSB_PIO_ONLY
USB Gadget Support--->CONFIG_USB_GADGET
(0x0525) Vendor ID of the USB device--->CONFIG_USB_GADGET_VENDOR_NUM
(0xA4A2) Product ID of the USB device--->CONFIG_USB_GADGET_PRODUCT_NUM
USB Ethernet Gadget--->CONFIG_USB_ETHER
USB Ethernet Gadget Model (RNDIS Protocol)--->CONFIG_USB_ETH_RNDIS
(de:ad:be:ef:00:01) USB Gadget Ethernet device mac address--->CONFIG_USBNET_DEVADDR
(de:ad:be:ef:00:00) USB Gadget Ethernet host mac address--->CONFIG_USBNET_HOST_ADDR
- 配置完成后宏娄,使用腳本命令
./build.sh -j4
進行uboot編譯,如無意外逮壁,則可以正常編譯通過绝编,通過orangpi相關(guān)燒錄指引,把sdcard.img燒錄到sd卡中 -
燒錄完成后貌踏,插入sd卡。連接調(diào)試串口窟勃,并啟動orangepi祖乳,在uboot3s后輸入空格停下啟動信息,如下圖所示
2秉氧、測試uboot的RNDIS網(wǎng)絡(luò)是否正常
- 在uboot停止的頁面輸入下面的內(nèi)容
usb start
setenv ethact usb_ether
setenv ipaddr 192.168.137.2
setenv netmask 255.255.255.0
setenv gatewayip 192.168.137.1
saveenv
ping 192.168.1.111
-
這里ping的ip是虛擬機的ip地址眷昆,需要查看uboot是否可以和虛擬機通訊,如果出現(xiàn)下圖類似情況ip is alive則通訊成功
三汁咏、kernel的RNDIS測試
1亚斋、配置編譯kernel的RNDIS功能
- 在orangepi目錄執(zhí)行
./build.sh linux-menuconfig
會彈出kernel的menuconfig的配置界面,我們的配置選項如下
RNDIS選項的配置 (這里一開始我們先配置為模塊攘滩,調(diào)用g_ether.ko帅刊,調(diào)試通過后再編譯進內(nèi)核)Device Drivers --->USB support --->
Support for Host-side USB--->CONFIG_USB
Enable USB persist by default--->CONFIG_USB_DEFAULT_PERSIST
EHCI HCD (USB 2.0) support--->CONFIG_USB_EHCI_HCD
Improved Transaction Translator scheduling--->CONFIG_USB_EHCI_TT_NEWSCHED
Generic EHCI driver for a platform device--->CONFIG_USB_EHCI_HCD_PLATFORM
OHCI HCD (USB 1.1) support--->CONFIG_USB_OHCI_HCD
Generic OHCI driver for a platform device--->CONFIG_USB_OHCI_HCD_PLATFORM
Inventra Highspeed Dual Role Controller--->CONFIG_USB_MUSB_HDRC
MUSB Mode Selection (Gadget only mode)--->CONFIG_USB_MUSB_GADGET
Allwinner (sunxi)--->USB_MUSB_SUNXI
USB Gadget Support--->CONFIG_USB_GADGET
USB Gadget precomposed configurations--->
Ethernet Gadget (with CDC Ethernet support)--->CONFIG_USB_ETH
RNDIS support--->CONFIG_USB_ETH_RNDIS
NFS網(wǎng)絡(luò)選項的配置 Networking support --->Networking options --->
TCP/IP networking--->CONFIG_INET
IP: kernel level autoconfiguration--->CONFIG_IP_PNP
IP: DHCP support--->CONFIG_IP_PNP_DHCP
IP: BOOTP support--->CONFIG_IP_PNP_BOOTP
NFS文件系統(tǒng)選項的配置 File systems --->Network File Systems --->
NFS client support--->CONFIG_NFS_FS
NFS client support for NFS version 2--->CONFIG_NFS_V2
NFS client support for NFS version 3--->CONFIG_NFS_V3
NFS client support for the NFSv3 ACL protocol extension--->CONFIG_NFS_V3_ACL
NFS client support for NFS version 4--->CONFIG_NFS_V4
Root file system on NFS--->CONFIG_ROOT_NFS
- 通過源碼修改kernel的ubs0網(wǎng)卡地址,因為如果不修改地址漂问,每次重啟都會產(chǎn)生一個隨機的網(wǎng)卡地址赖瞒,那么win10這邊識別的就不是前面設(shè)置的共享網(wǎng)卡了,這里我們需要把網(wǎng)卡設(shè)置成和uboot的網(wǎng)卡地址一樣蚤假,這里我么需要修改的文件是栏饮,kernel源碼下面的u_ether.c文件的gether_setup_name_default函數(shù)添加usb網(wǎng)卡的判斷,當識別到usb網(wǎng)卡的時候磷仰,設(shè)置其默認的host地址為de:ad:be:ef:00:00袍嬉,dev地址為de:ad:be:ef:00:01
837 snprintf(net->name, sizeof(net->name), "%s%%d", netname);
838
839 if(memcmp(netname, "usb", 3) == 0)
840 {
841 eth_random_addr(dev->dev_mac);
842 pr_warn("using usb my random %s ethernet address\n", "self");
843 eth_random_addr(dev->host_mac);
844 pr_warn("using usb my %s ethernet address\n", "host");
845 dev->host_mac[0] = 222;
846 dev->host_mac[1] = 173;
847 dev->host_mac[2] = 190;
848 dev->host_mac[3] = 239;
849 dev->host_mac[4] = 0;
850 dev->host_mac[5] = 0;
851
852 dev->dev_mac[0] = 222;
853 dev->dev_mac[1] = 173;
854 dev->dev_mac[2] = 190;
855 dev->dev_mac[3] = 239;
856 dev->dev_mac[4] = 0;
857 dev->dev_mac[5] = 1;
858 }
859 else
860 {
861 eth_random_addr(dev->dev_mac);
862 pr_warn("using random %s ethernet address\n", "self");
863 eth_random_addr(dev->host_mac);
864 pr_warn("using random %s ethernet address\n", "host");
865 }
- 配置修改完成后,使用腳本命令
./build.sh -j4
進行uboot編譯灶平,如無意外伺通,則可以正常編譯通過,通過orangpi相關(guān)燒錄指引民逼,把sdcard.img燒錄到sd卡中
2泵殴、測試kernel的RNDIS網(wǎng)絡(luò)是否正常
- 重新上電后,等等其加載mmc的根文件系統(tǒng)拼苍,加載成功后登陸系統(tǒng)笑诅,通過命令
modprobe g_ether
加載模塊驅(qū)動调缨,如果加載成功,會出現(xiàn)類似的信息
[ 1.526195] usb0: HOST MAC de:ad:be:ef:00:00
[ 1.530505] usb0: MAC de:ad:be:ef:00:01
[ 1.534355] using usb my random self ethernet address
[ 1.539399] using usb my host ethernet address
[ 1.543905] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
[ 1.550519] g_ether gadget: g_ether ready
- 通過
ifconfig -a
查看是否存在usb0網(wǎng)卡吆你,如果存在usb0網(wǎng)卡弦叶,說明網(wǎng)卡正常驅(qū)動 - 啟動usb0網(wǎng)卡且對其進行配置
ifconfig usb0 up && ifconfig usb0 192.168.137.2 netmask 255.255.255.0
- 配置默認網(wǎng)關(guān)
route add default gw 192.168.137.1
- 測試是否可以ping通虛擬機
ping 192.168.1.111
,如果正常ping通說明網(wǎng)絡(luò)成功通訊 - 通過命令
/etc/network/nfs_check
創(chuàng)建網(wǎng)卡啟動時對nfs的檢查文件
#!/bin/sh
# This allows NFS booting to work while also being able to configure
# the network interface via DHCP when not NFS booting. Otherwise, a
# NFS booted system will likely hang during DHCP configuration.
# Attempting to configure the network interface used for NFS will
# initially bring that network down. Since the root filesystem is
# accessed over this network, the system hangs.
# This script is run by ifup and will attempt to detect if a NFS root
# mount uses the interface to be configured (IFACE), and if so does
# not configure it. This should allow the same build to be disk/flash
# booted or NFS booted.
nfsip=`sed -n '/^[^ ]*:.* \/ nfs.*[ ,]addr=\([0-9.]\+\).*/s//\1/p' /proc/mounts`
if [ -n "$nfsip" ] && ip route get to "$nfsip" | grep -q "dev $IFACE"; then
echo Skipping $IFACE, used for NFS from $nfsip
exit 1
fi
- 通過命令
vi /etc/network/interfaces
添加usb0網(wǎng)卡開機自動掛載
auto usb0
iface usb0 inet static
pre-up /etc/network/nfs_check
address 192.168.137.2
netmask 255.255.255.0
gateway 192.168.137.1
#dns-nameservers 8.8.8.8 192.168.137.1 211.136.20.203
- 通過命令
vi /etc/resolv.conf
配置dns服務(wù)器妇多,注意resolv.conf文件不能是鏈接文件
nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 192.168.137.1
3伤哺、測試kernel的RNDIS網(wǎng)絡(luò)的nfs功能是否正常
- 在虛擬機服務(wù)器端開啟nfs服務(wù)
- 在虛擬機通過命令
ln -s nfsroot nfs
創(chuàng)建nfs文件的的軟連接,nfsroot是實際的根文件系統(tǒng)目錄者祖,而后面的nfs是創(chuàng)建的軟連接目錄 - 在虛擬機通過命令
sudo vi /etc/exports
修改文件內(nèi)容立莉,添加類似的內(nèi)容/home/vencol/code/nfs *(insecure,rw,sync,no_root_squash,no_subtree_check)
- 在虛擬機通過命令
sudo /etc/init.d/nfs-kernel-server restart
重啟nfs服務(wù) - 在開發(fā)創(chuàng)建nfsdir目錄,并且通過命令
mount -t nfs -o nolock 192.168.1.111:/home/vencol/code/nfs nfsdir
七问,如果掛載成功通過ls nfsdir
則可以看到nfs根文件系統(tǒng)的內(nèi)容蜓耻。
四、綜合測試RNDIS網(wǎng)絡(luò)
1械巡、通過uboot手動測試tftp加載kernel啟動
- 由于前面我們使用了saveenv命令來保存uboot的環(huán)境參數(shù)刹淌,所以這里我們只要沒有重新燒錄,都可以不用再次設(shè)置讥耗,如果需要設(shè)置有勾,請參考【測試uboot的RNDIS網(wǎng)絡(luò)是否正常】章節(jié)內(nèi)容
- 我們在虛擬機上通過執(zhí)行
./build.sh cp
命令把zImage和sun8i-h3-orangepi-one.dtb設(shè)備樹文件拷貝到我們的tftp服務(wù)器目錄下古程。 - 我們在開發(fā)板上設(shè)置bootargs參數(shù)為
setenv bootargs "console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait"
并且通過saveenv保存該參數(shù) - 在開發(fā)板上蔼卡,使用
tftp 0x42000000 zImage
加載zimage到內(nèi)存,通過tftp 0x43000000 sun8i-h3-orangepi-one.dtb
加載設(shè)備樹到內(nèi)存 - 在開發(fā)板上籍琳,通過
bootz 0x42000000 - 0x43000000
啟動內(nèi)核菲宴,如無意外,可以成功進入登錄界面趋急,但是這時加載的是mmc根文件系統(tǒng)喝峦,下面我們開始加載nfs文件系統(tǒng)
2、通過uboot手動測試tftp加載kernel掛載nfs啟動
- 在前面已經(jīng)可以正常加載mmc根文件系統(tǒng)的前提下呜达,進行nfs文件系統(tǒng)的加載
- 在uboot界面停下谣蠢,由于前面保存了相關(guān)的環(huán)境變量,這里我們直接進行bootargs參數(shù)的修改查近,通過命令修改bootargs參數(shù)為眉踱,
setenv bootargs root=/dev/nfs rw rootpath=/home/vencol/code/nfs nfsroot=192.168.1.111:/home/vencol/code/nfs,nolock ip=192.168.137.2:192.168.1.111:192.168.137.1:255.255.255.0 console=ttyS0,115200 nfsvers=2
這里的rootpath是虛擬機上nfs根文件的地址,而ip則是根據(jù)我們的實際情況設(shè)置霜威,由于這里虛擬機和開發(fā)板不在同一網(wǎng)段谈喳,所以需要填寫網(wǎng)關(guān)和掩碼信息 - 在開發(fā)板上,使用
tftp 0x42000000 zImage
加載zimage到內(nèi)存戈泼,通過tftp 0x43000000 sun8i-h3-orangepi-one.dtb
加載設(shè)備樹到內(nèi)存 - 在開發(fā)板上婿禽,通過
bootz 0x42000000 - 0x43000000
啟動內(nèi)核赏僧,如無意外,可以成功進入登錄界面扭倾,但是這時加載的是mmc根文件系統(tǒng)淀零,下面我們開始加載nfs文件系統(tǒng) - 出現(xiàn)問題排查
1.nfs服務(wù)器端的傳輸協(xié)議是否和開發(fā)版客戶端的協(xié)議一致,如果不一致膛壹,在bootargs添加nfsserver=2驾中,這里2是nfs2的意思,對應(yīng)版本即可
- 查看nfs根文件系統(tǒng)中的/dev目錄是否存在模聋,/dev/console和/dev/null肩民,如果不存在通過下面命令創(chuàng)建
sudo mknod console c 5 1 //創(chuàng)建console字符設(shè)備,
sudo mknod null c 1 3 //創(chuàng)建null 字符設(shè)備,
sudo chown 1000:1000 console null```- 在源碼文件init/do_mounts.c的do_mount_root函數(shù)中調(diào)用的do_mount函數(shù)返回的錯誤打印出來,查看錯誤碼是什么链方,如果錯誤碼為-93此改,那么就是服務(wù)器版本不對,這里有可能是下面4這點的問題侄柔。在服務(wù)器端用
nfsstat -s
查看版本,如果是其他錯誤可以參考/var/log/syslog
中nfs的輸出日志占调。- 低版本uboot和高版本ubuntu搭配進行開發(fā)時暂题,發(fā)現(xiàn)nfs不能使用.uboot默認啟動協(xié)議為2.而高版本的ubuntu17之后nfs就默認支持3和4,因此需要ubuntu支持協(xié)議2究珊。在文件
/etc/default/nfs-kernel-server
末尾添加RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
薪者,然后重啟nfs服務(wù)。
3剿涮、把測試啟動的nfs命令轉(zhuǎn)換成boot.scr啟動腳本
- boot.scr是通過mkimage工具生成的言津,這里我們需要先拷貝buildroot中orangepione的boot.cmd文件到腳本目錄,在這個文件的基礎(chǔ)上進行修改取试,其目錄在
buildroot/board/orangepi/orangepi-one/boot.cmd
- 修改boot.cmd文件如下悬槽,其中rootdelay=3看具體情況使用
setenv fdt_high ffffffff
usb start
setenv ethact usb_ether
setenv ipaddr 192.168.137.2
setenv gatewayip 192.168.137.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.111
#setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait
setenv bootargs root=/dev/nfs rw rootpath=/home/vencol/code/nfs nfsroot=192.168.1.111:/home/vencol/code/nfs,nolock ip=192.168.137.2:192.168.1.111:192.168.137.1:255.255.255.0 console=ttyS0,115200 nfsvers=2 rootdelay=3
tftp $kernel_addr_r zImage
tftp $fdt_addr_r sun8i-h3-orangepi-one.dtb
bootz $kernel_addr_r - $fdt_addr_r
#fatload mmc 0 $kernel_addr_r zImage
#fatload mmc 0 $fdt_addr_r sun8i-h3-orangepi-one.dtb
#bootz $kernel_addr_r - $fdt_addr_r
- 通過腳本命令
./build.sh env
生成boot.scr文件在當前目錄中 - 把boot.scr文件拷貝到nfs目錄的root目錄下
- 在開發(fā)板已經(jīng)正常進入mmc根文件系統(tǒng)的情況下,掛載nfs目錄到nfsdir目錄中
- 通過命令
mount /dev/mmcblk0p1 /mnt/fat/
掛載boot分區(qū)到/mnt/fat/ - 把nfs目錄的boot.scf拷貝到boot分區(qū)
cp nfsdir/root/boot.scr /mnt/fat
- 確認boot分區(qū)的boot.scr文件更新后瞬浓,卸載boot分區(qū)初婆,并重啟
umount /mnt/fat && reboot
如無意外,則可以看到類似的掛nfs信息出現(xiàn)
: