Android ROM开发

[Mtk][M0]如何添加 USB 以太网功能

2018-10-18  本文已影响28人  灰灰手记

最近碰到个需求,客户要添加 USB以太网卡 功能,下面简单记录一下配置过程。

一、确定网卡芯片型号

这一步非常重要,因为它将直接决定后面的步骤怎么进行下去,也将决定目标网卡能不能被识别到。方法大致有如下几种,按从易到难的顺序说一下。

1、看 Model 定义

先看下我测试用的两款网卡,如下图,这俩外观及丝印格式基本一致,看着有模有样的。


图1、正规渠道买的网卡 图2、非正规渠道买的网卡

上图中的 Model No 就是我这里说的网卡芯片型号,这俩的格式是一样的,都是用横线-连着的两段代码,它们的定义是这样的:

表1、Model No 格式

表中最后一列,就是我们要关注的注芯片型号。

PS:
不一定所有的格式都是这样,这里是个人理解,仅供参考。

2、看芯片丝印

可能大家已经注意到图1、图2上我特别强调了购买渠道,原因大家应该都能想到。
想不到为什么的人,看看下面的图也就明白了。

图3、正规渠道的芯片丝印 图4、非正规渠道的芯片丝印

没错,正规渠道的产品Model No丝印是一致的,但“地摊货”的芯片型号就是个谜了。

PS:
我按Model No 配好之后,客户反馈用不了,拿过来拆开之后才发现是个“地摊货”......

3、看PC识别结果

那么“地摊货”的芯片型号怎么看呢?
想办法插电脑上就可以看了,这里我用的是 Linux,因为 Windows 的设备管理器里面看不到型号,不知道怎么看。

Linux 查看方法:

# lsusb

shawnxiafei:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 413c:301a Dell Computer Corp. 
Bus 001 Device 127: ID 18d1:4ee7 Google Inc. 
Bus 001 Device 002: ID 413c:2113 Dell Computer Corp. 
Bus 001 Device 014: ID 05c6:9091 Qualcomm, Inc. 
Bus 001 Device 015: ID 0bda:8152 Realtek Semiconductor Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

其中的 Realtek 一项就是USB以太网卡,8152就是芯片型号,可以看到和Model No、丝印都是一致的:

Bus 001 Device 015: ID 0bda:8152 Realtek Semiconductor Corp.

PS:
配好 DM9601 的驱动之后,网卡识别到了,也能正常连接了,但实际上联网有数据下行的时候,就会极大概率的出现 system 重启。
而使用 RTL8152 却没有问题,检查了 DM9601 的驱动,发现从 M0~O1 基本没变,这也就侧面说明 DM9601 的驱动已经很成熟了,再次质疑下这个“地摊货”的质量。

二、确定源码上是否有驱动

1、确定驱动路径

Android 是基于 Linux 的,在网卡支持这块也延用了 Linux 的部分内容。默认情况下,Android 内核源码中已经带有一些常见网卡芯片的驱动了,路径如下:

kernel-x.xx\drivers\net\

在日常生活中,我们往往按是否要接网线将网卡分为有线网卡、无线网卡,按挂载方式又可分为板载网卡、外挂网卡,这些分类方法实际上相互有重叠,就不纠结了。这里net 目录下同样有这些对应的子目录,分别放着对应的驱动文件,如下:

kernel-x.xx\drivers\net\ethernet\    # 板载以太网
kernel-x.xx\drivers\net\usb\         # USB网卡
kernel-x.xx\drivers\net\wan\         # WAN接口(路由器接外网的接口)
kernel-x.xx\drivers\net\wireless\    # 板载无线网卡
......

其中,usb 目录就是本文关注的USB 以太网卡的目录。确定了路径之后,就要检查是否有这个驱动了。

2、Kconfig

usb 目录下,有一个 Kconfig 文件,这里面会记录所有已经支持的网卡型号;其它子目录中也同样有这么一个文件。在这个文件中搜一下上面弄到的芯片型号,搜数字部分就可以了,如下:

config USB_RTL8152
    tristate "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
    select MII
    help
      This option adds support for Realtek RTL8152 based USB 2.0
      10/100 Ethernet adapters and RTL8153 based USB 3.0 10/100/1000
      Ethernet adapters.

      To compile this driver as a module, choose M here: the
      module will be called r8152.

config USB_NET_DM9601
    tristate "Davicom DM96xx based USB 10/100 ethernet devices"
    depends on USB_USBNET
    select CRC32
    help
      This option adds support for Davicom DM9601/DM9620/DM9621A
      based USB 10/100 Ethernet adapters.

这里这两个芯片默认已经支持了,不用重新配驱动代码了,Nice! 简单解释下这段代码的内容:

config     描述宏开关名称
tristate   可取值 y、n、m
depends    要依赖的“模块”
select     depends on 的内容有效时,select 的内容也有效
help       帮助信息

PS:更多关于 Kconfig 文件的内容可查看如下文章:
Kconfig文件详解
https://blog.csdn.net/ultraman_hs/article/details/52984929

很明显,要启用 DM9601,还需要启用 USB_USBNET,其代码如下:

config USB_USBNET
    tristate "Multi-purpose USB Networking Framework"
    select MII
    ---help---
      This driver supports several kinds of network links over USB,
      with "minidrivers" built around a common network driver core
      that supports deep queues for efficient transfers.  (This gives
      better performance with small packets and at high speeds).

      The USB host runs "usbnet", and the other end of the link might be:

      - Another USB host, when using USB "network" or "data transfer"
        cables.  These are often used to network laptops to PCs, like
        "Laplink" parallel cables or some motherboards.  These rely
        on specialized chips from many suppliers.

      - An intelligent USB gadget, perhaps embedding a Linux system.
        These include PDAs running Linux (iPaq, Yopy, Zaurus, and
        others), and devices that interoperate using the standard
        CDC-Ethernet specification (including many cable modems).

      - Network adapter hardware (like those for 10/100 Ethernet) which
        uses this driver framework.

      The link will appear with a name like "usb0", when the link is
      a two-node link, or "eth0" for most CDC-Ethernet devices.  Those
      two-node links are most easily managed with Ethernet Bridging
      (CONFIG_BRIDGE) instead of routing.

      For more information see <http://www.linux-usb.org/usbnet/>.

      To compile this driver as a module, choose M here: the
      module will be called usbnet.

三、配置驱动

在确定了有驱动之后,接下来就是准备配置驱动了。那么这两个驱动应该如何配上来呢?

1、Makefile

usb 目录下,有个 Makefile 文件,它记录着宏开关和编译输出文件的对应关系,同样在里面搜芯片信号数字部分,可以找到如下内容:

obj-$(CONFIG_USB_RTL8152) += r8152.o
obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
obj-$(CONFIG_USB_USBNET) += usbnet.o

到这里宏开关名字和编译输出文件的名字就都知道了,也就知道宏开关要配置在哪里了。

2、defconfig

看到 CONFIG_XXX 格式的宏开关,就知道要是在项目的 defconfig 中配置这几个宏开关了,文件路径如下:

kernel-x.xx\arch\arm[64]\configs\xxx_defconfig
kernel-x.xx\arch\arm[64]\configs\xxx_debug_defconfig

在这两个文件中同时添加如下配置:

#For USB Ethernet
CONFIG_USB_RTL8152=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_DM9601=y

到这里就可以单编boot.img,看下对应的.o文件是否有生成了。.o文件编译输出目录:

out\target\product\xxx\obj\KERNEL_OBJ\drivers\net\usb\

如果这里没有出现 Makefile 里面对应的文件,则说明配置有问题,需要倒回去仔细检查一下。

3、init.project.rc

确认能正常编出来.o文件之后,也只是说明有了驱动,但驱动并没有跑起来,还是不能识别的。

若想正常使用,还需要在项目的 init.project.rc 文件中给驱动添加 service,代码如下:

# device/pskyed/xxx/init.project.rc

# 增加如下代码
service dhcpcd_eth0 /system/bin/dhcpcd -BK -dd
    class main
    user dhcp
    group net_admin net_raw
    disabled
    oneshot

 #
 # Connectivity related services (End)
 #

到这里,再次插上 USB 以太网卡时,在 adb shell 中就能看到如下信息了:

C:\Users\ShawnXia>adb shell ifconfig
eth0      Link encap:UNSPEC
          inet6 addr: fe80::2e0:4cff:fe53:4458/64 Scope: Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 TX bytes:0

lo        Link encap:UNSPEC
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:536 TX bytes:536

C:\Users\ShawnXia>

根据名字以及前面配置 service 的代码不难看出,eth0 就是刚连接的 USB 以太网卡,已经正常识别到了。另一个 lo 表示回环接口,它是虚拟出来的,IPMask 一般是固定的。

此时若开了 WiFi,还能看到如下信息:

wlan0     Link encap:UNSPEC
          inet addr:192.168.0.108  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::208:22ff:fe10:233b/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:30 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2526 TX bytes:2795

p2p0      Link encap:UNSPEC
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 TX bytes:168

更多 Linux 网络接口信息,可查看如下文章:
ifconfig中lo、eth0、br0接口
https://blog.csdn.net/u012336923/article/details/50463599

四、配置 framework

到这里底层的配置基本完成了,接下来需要对 framework 进行相应的配置。

1、permissions

因为 USB 以太网卡算一个 Feature,所以还需要将相应的 permissions 文件编译到系统中。修改项目的 device.mk 文件,添加如下代码:

#device/pskyed/xxx/device.mk

PRODUCT_COPY_FILES += device/pskyed/xxx/ht120.mtc:system/etc/.tp/.ht120.mtc
#增加下面这行
PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml

2、networkAttributes

配置好 permissions 后,最后一步就是配置网络参数了,这个参数在:

frameworks/base/core/res/res/values/config.xml

其默认值如下:

    <!-- This string array should be overridden by the device to present a list of network
         attributes.  This is used by the connectivity manager to decide which networks can coexist
         based on the hardware -->
    <!-- An Array of "[Connection name],[ConnectivityManager.TYPE_xxxx],
         [associated radio-type],[priority],[restoral-timer(ms)],[dependencyMet]  -->
    <!-- the 5th element "resore-time" indicates the number of milliseconds to delay
         before automatically restore the default connection.  Set -1 if the connection
         does not require auto-restore. -->
    <!-- the 6th element indicates boot-time dependency-met value. -->
    <string-array translatable="false" name="networkAttributes">
        <item>"wifi,1,1,2,-1,true"</item>
        <item>"tedongle,49,49,1,-1,true"</item>
        <item>"mobile,0,0,0,-1,true"</item>
        <item>"mobile_mms,2,0,2,300000,true"</item>
        <item>"mobile_supl,3,0,2,300000,true"</item>
        <item>"mobile_dun,4,0,3,300000,true"</item>
        <item>"mobile_hipri,5,0,3,300000,true"</item>
        <item>"bluetooth,7,7,0,-1,true"</item>
        <item>"mobile_fota,10,0,2,300000,true"</item>
        <item>"mobile_ims,11,0,-1,-1,true"</item>
        <item>"mobile_cbs,12,0,2,300000,true"    </item>
        <item>"mobile_dm,34,0,3,300000,true"</item>
        <item>"mobile_wap,35,0,3,300000,true"</item>
        <item>"mobile_net,36,0,3,300000,true"</item>
        <item>"mobile_cmmail,37,0,3,300000,true"</item>
        <item>"mobile_rcse,38,0,3,300000,true"</item>
        <item>"mobile_ia,14,0,2,-1,true"</item>
        <item>"mobile_emergency,15,0,2,-1,true"</item>
        <item>"mobile_xcap,40,0,3,300000,true"</item>
        <item>"mobile_rcs,41,0,3,300000,true"</item>
    </string-array>

因为是新增的以太网(有线网卡)功能,所以要新增一项:

<item>"ethernet,9,9,0,-1,true"</item>

又因为我这设备是单 WiFi 的设备,没有数据流量功能,因此我去除了 mobile 相关的内容,最后就是这样:

<string-array translatable="false" name="networkAttributes">
    <item>"wifi,1,1,2,-1,true"</item>
    <item>"tedongle,49,49,1,-1,true"</item>
    <item>"bluetooth,7,7,0,-1,true"</item>
    <item>"ethernet,9,9,0,-1,true"</item>
</string-array>

至此,和 USB 以太网卡相关的配置就结束了,插上就能正常用了。

3、Ethernet APP

如果还需要添加设置动态IP静态IP的功能,那还需要添加 MTK 新增的 APP:Ethernet。这个代码量很大,而且也不影响USB以太网卡的正常使用,就不贴代码了,下面是它的功能界面截图:

Ethernet APP

五、小结

1、Android 网卡功能延用了 Linux 的很多东西,大部分常见的网卡芯片驱动也默认都有了,只需要按步骤配置好就可以用了。
2、如果某个没有某个芯片的驱动,也只需要让找到厂商放出来的驱动代码,集成进来就可以了。
3、如果碰到“地摊货”,也只需要确保正规渠道买的同芯片的产品功能正常,毕竟没人知道“地摊货”的芯片到底怎么来的。
4、不要想着把市面上的驱动都配上来,配几个常见的就可以,毕竟多一个驱动,boot.img 就大一点,多了还得调分区,而且还会影响机器性能。


此笔记已推送到微信公众号:灰灰的Rom笔记

上一篇 下一篇

猜你喜欢

热点阅读