大家好,我是三颗芋圆,始于LWIP,陷于TCP/IP,忠于80211。
终于迎来了第一个专题:Wi-Fi模组移植,本次专题将介绍如何在 tina上移植一款Wi-Fi模组,从理论到实操移植XR829详细介绍。
避免篇幅太长,分成了前导篇,理论篇,实践篇。
实践篇
这里我将以 XR829 为例子详细介绍模组适配的全过程。
- 主控:<span class="hljs-selector-tag">D1</span>
- 无线模组:<span class="hljs-selector-tag">XR829</span>
- 内核版本:<span class="hljs-selector-tag">linux-5</span><span class="hljs-selector-class">.4</span>
- 方案:<span class="hljs-selector-tag">d1_nezha-tina</span>
复制代码
按照理论篇的5个步骤来操作
1. 内核驱动适配
内核驱动适配分为如下四个步骤:
• 获取源码。
• 添加 Kconfig 和 Makefile 配置。
• make kernel_menuconfig 配置。
• 编译。
1)获取 xr829 驱动源码,放到内核驱动路径下。客户可以从一号通账号获取。
- tina<span class="hljs-regexp">/lichee/linux-5.4/drivers/net/wireless/xr829/</span>
- ├── include
- ├── Kconfig
- ├── Makefile
- ├── umac
- └── wlan
复制代码
2)内核添加 Kconfig 和 Makefile 的配置。
tina/lichee/linux-5.4/drivers/net/wireless/Kconfig 文件中引入 XR829 驱动的 Kconfig 配 置
- <span class="hljs-attribute">source</span> <span class="hljs-string">"drivers/net/wireless/xr829/Kconfig"</span>
复制代码
tina/lichee/linux-5.4/drivers/net/wireless/Makefile 文件中引入 XR829 驱动的 Makefile配置
- <span class="hljs-meta">obj-[ DISCUZ_CODE_3 ]lt;/span><span class="bash">(CONFIG_XR829_WLAN) += xr829/</span>
复制代码
3)make kernel_menuconfig 配置
在 tina/lichee/linux-5.4 内核目录执行 m kernel_menuconfig
a. XR829 驱动的配置
- <span class="hljs-meta">></span><span class="bash"> Device Drivers > Network device support > Wireless LAN</span>
- <M> XR829 WLAN support
复制代码
b. sunxi-rf 的配置
- <span class="hljs-meta">></span><span class="bash"> Device Drivers > Misc devices</span>
- <*> Allwinner rfkill driver
复制代码
c. SDIO 的配置
- <span class="hljs-meta">></span><span class="bash"> Device Drivers > MMC/SD/SDIO card support</span>
- <*> Allwinner sunxi SD/MMC Host Controller support --->
复制代码
4) 编译
在 tina/lichee/linux-5.4 内核目录执行 mkernel 进行编译
- tina/lichee/linux<span class="hljs-number">-5.4</span>]$ mkernel
- tina/lichee/linux<span class="hljs-number">-5.4</span>/drivers/net/wireless/xr829/
- ├── <span class="hljs-keyword">include</span>
- ├── Kconfig
- ├── Makefile
- ├── modules.order
- ├── umac
- ├── wlan
- ├── xr829.ko <span class="hljs-comment">//正常编译出xr829.ko模块</span>
- ├── xr829.mod
- ├── xr829.mod.c
- ├── xr829.mod.o
- └── xr829.o
复制代码
2. 硬件资源适配
在 tina/device/config/chips/r528/configs/evb1/linux/board.dts中添加引脚配置
- wlan_pins_a:wlan@<span class="hljs-number">0</span> {
- pins = <span class="hljs-string">"PG11"</span>;
- function = <span class="hljs-string">"clk_fanout1"</span>; <span class="hljs-comment">//这里涉及一个特殊处理,该方案的32k采用PG11复用给出 </span>
- };
- ...
- rfkill: rfkill@<span class="hljs-number">0</span> {
- compatible = <span class="hljs-string">"allwinner,sunxi-rfkill"</span>;
- chip_en;
- power_en;
- pinctrl<span class="hljs-number">-0</span> = <&wlan_pins_a>;
- pinctrl-names = <span class="hljs-string">"default"</span>;
- status = <span class="hljs-string">"okay"</span>;
- wlan: wlan@<span class="hljs-number">0</span> {
- compatible = <span class="hljs-string">"allwinner,sunxi-wlan"</span>;
- clock-names = <span class="hljs-string">"32k-fanout1"</span>;
- clocks = <&ccu <span class="hljs-built_in">CLK_FANOUT1_OUT</span>>; wlan_busnum = <<span class="hljs-number">0x1</span>>;
- wlan_regon = <&pio PE <span class="hljs-number">17</span> GPIO_ACTIVE_HIGH>;
- wlan_hostwake = <&pio PG <span class="hljs-number">10</span> GPIO_ACTIVE_HIGH>;
- <span class="hljs-comment">/*wlan_power = "VCC-3V3";*/</span>
- <span class="hljs-comment">/*wlan_power_vol = <3300000>;*/</span>
- <span class="hljs-comment">/*interrupt-parent = <&pio>;*/</span>
- <span class="hljs-comment">/*interrupts = < PG 10 IRQ_TYPE_LEVEL_HIGH>;*/</span>
- wakeup-source;
- };
- ...
- };
复制代码
注意:以上所有项必须参看原理图进行配置,配置与原理图实际使用的资源保持一致;最好是和硬件同事一起确认,比如有些设计供电可能是没有 axp 的,硬件直接供电了,所以不需要配置,特别注意的就是 sdio 的配置。
3. 方案 module 适配
在 tina/target/allwinner/r528-common/modules.mk 中添加模块配置
- <span class="hljs-keyword">define</span> KernelPackage/net-xr829-40M
- SUBMENU:=<span class="hljs-variable">$(WIRELESS_MENU)</span>
- TITLE:=xr829 support (staging)
- DEPENDS:= +xr829-firmware +[url=home.php?mod=space&uid=2868119]@IPv6[/url] +@XR829_USE_40M_SDD +@USES_XRADIO +@PACKAGE_xr829-rftest
- KCONFIG:=
- CONFIG_XR829_WLAN=m
- CONFIG_PM=y
- CONFIG_BT=y
- CONFIG_BT_BREDR=y
- CONFIG_BT_RFCOMM=y
- CONFIG_BT_RFCOMM_TTY=y
- CONFIG_BT_DEBUGFS=y
- CONFIG_XR_BT_LPM=y
- CONFIG_XR_BT_FDI=y
- CONFIG_BT_HCIUART=y
- CONFIG_BT_HCIUART_H4=y
- CONFIG_HFP_OVER_PCM=y
- CONFIG_RFKILL=y
- CONFIG_RFKILL_PM=y
- CONFIG_RFKILL_GPIO=y
- <span class="hljs-comment">#FILES:=$(LINUX_DIR)/drivers/net/wireless/xr829/wlan/xradio_core.ko</span>
- <span class="hljs-comment">#FILES+=$(LINUX_DIR)/drivers/net/wireless/xr829/wlan/xradio_wlan.ko</span>
- <span class="hljs-comment">#FILES+=$(LINUX_DIR)/drivers/net/wireless/xr829/umac/xradio_mac.ko</span>
- <span class="hljs-comment">#AUTOLOAD:=$(call AutoProbe, xradio_mac xradio_core xradio_wlan)</span>
- FILES:=<span class="hljs-variable">$(LINUX_DIR)</span>/drivers/net/wireless/xr829/xr829.ko
- AUTOLOAD:=<span class="hljs-variable">$(<span class="hljs-built_in">call</span> AutoProbe, xr829)</span>
- <span class="hljs-keyword">endef</span>
- <span class="hljs-keyword">define</span> KernelPackage/net-xr829-40M/description
- Kernel modules for xr829 support
- <span class="hljs-keyword">endef</span>
- <span class="hljs-variable">$(<span class="hljs-built_in">eval</span> $(<span class="hljs-built_in">call</span> KernelPackage,net-xr829-40M)</span>)
复制代码
几点说明:
DEPENDS:Tina包依赖配置
KCONFIG:内核依赖配置
FILES:内核模块路径
一般不需要用户自己适配,可以自己从已经适配过的方案的modules.mk中拷贝过来就好,也可以直接拷贝这段代码。
注意:XR829分为40M和24M晶振,如果是24M晶振建议用下面的配置做区分。
- <span class="hljs-keyword">define</span> KernelPackage/net-xr829
- SUBMENU:=<span class="hljs-variable">$(WIRELESS_MENU)</span>
- TITLE:=xr829 support (staging)
- DEPENDS:= +xr829-firmware +@IPV6 +@USES_XRADIO +@PACKAGE_xr829-rftest +@PACKAGE_xr829-
- rftest
- KCONFIG:=
- CONFIG_XR829_WLAN=m
- CONFIG_PM=y
- CONFIG_BT=y
- CONFIG_BT_BREDR=y
- CONFIG_BT_RFCOMM=y
- CONFIG_BT_RFCOMM_TTY=y
- CONFIG_BT_DEBUGFS=y
- CONFIG_XR_BT_LPM=y
- CONFIG_XR_BT_FDI=y
- CONFIG_BT_HCIUART=y
- CONFIG_BT_HCIUART_H4=y
- CONFIG_HFP_OVER_PCM=y
- CONFIG_RFKILL=y
- CONFIG_RFKILL_PM=y
- CONFIG_RFKILL_GPIO=y
- <span class="hljs-comment">#FILES:=$(LINUX_DIR)/drivers/net/wireless/xr829/wlan/xradio_core.ko</span>
- <span class="hljs-comment">#FILES+=$(LINUX_DIR)/drivers/net/wireless/xr829/wlan/xradio_wlan.ko</span>
- <span class="hljs-comment">#FILES+=$(LINUX_DIR)/drivers/net/wireless/xr829/umac/xradio_mac.ko</span>
- <span class="hljs-comment">#AUTOLOAD:=$(call AutoProbe, xradio_mac xradio_core xradio_wlan)</span>
- FILES+=<span class="hljs-variable">$(LINUX_DIR)</span>/drivers/net/wireless/xr829/xr829.ko
- AUTOLOAD:=<span class="hljs-variable">$(<span class="hljs-built_in">call</span> AutoProbe, xr829)</span>
- <span class="hljs-keyword">endef</span>
- <span class="hljs-keyword">define</span> KernelPackage/net-xr829/description
- Kernel modules for xr829 support
- <span class="hljs-keyword">endef</span>
- <span class="hljs-variable">$(<span class="hljs-built_in">eval</span> $(<span class="hljs-built_in">call</span> KernelPackage,net-xr829)</span>)
复制代码
接着在 tina 根目录执行 m menuconfig 就可以看到新添加的模组
- make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Kernel modules > Wireless Drivers</span>
复制代码
4. 添加 Firmware
在 tina/package/firmware/linux-firmware/添加 xr829 需要的 firmware
- tina/<span class="hljs-keyword">package</span>/firmware/linux-firmwarexr829/
- ├── boot_xr829.bin <span class="hljs-comment">//启动相关bin</span>
- ├── etf_xr829.bin <span class="hljs-comment">//etf测试工具相关bin</span>
- ├── fw_xr829_40M.bin <span class="hljs-comment">//wifi固件40M晶振需要的bin</span>
- ├── fw_xr829.bin <span class="hljs-comment">//wifi固件24M晶振需要的bin</span>
- ├── fw_xr829_bt_40M.bin <span class="hljs-comment">//bt固件40M晶振需要的bin</span>
- ├── fw_xr829_bt.bin <span class="hljs-comment">//bt固件24M晶振需要的bin</span>
- ├── sdd_xr829_40M.bin <span class="hljs-comment">//功率配置40M晶振的bin</span>
- ├── sdd_xr829.bin <span class="hljs-comment">//功率配置24M晶振的bin</span>
- └── xr829.mk <span class="hljs-comment">//Makefile文件</span>
复制代码
说明:功能调试阶段 wifi 只需要关注 boot_xr829.bin,fw_xr829.bin,sdd_xr829.bin。这些文件的获取一般伴随 xr829 产品包一起释放。
注意:一定要区分 24M 晶振和 40M 晶振
- Package/xr829-firmware = $(call Package/firmware-<span class="hljs-keyword">default</span>,Xradio xr829 firmware)
- PKG_CONFIG_DEPENDS +=CONFIG_XR829_USE_40M_SDD
- define Package/xr829-firmware/install
- $(INSTALL_DIR) $(<span class="hljs-number">1</span>)/$(FIRMWARE_PATH)
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/boot_xr829.bin $(<span class="hljs-number">1</span>)
- /$(FIRMWARE_PATH)/boot_xr829.bin
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/etf_xr829.bin $(<span class="hljs-number">1</span>)/
- $(FIRMWARE_PATH)/etf_xr829.bin
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/fw_xr829.bin $(<span class="hljs-number">1</span>)/$
- (FIRMWARE_PATH)/fw_xr829.bin
- ifeq ($(CONFIG_XR829_USE_40M_SDD), y)
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/sdd_xr829_40M.bin
- $(<span class="hljs-number">1</span>)/$(FIRMWARE_PATH)/sdd_xr829.bin
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/fw_xr829_bt_40M.bin
- $(<span class="hljs-number">1</span>)/$(FIRMWARE_PATH)/fw_xr829_bt.bin
- <span class="hljs-keyword">else</span>
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/sdd_xr829.bin $(<span class="hljs-number">1</span>)/
- $(FIRMWARE_PATH)/sdd_xr829.bin
- $(INSTALL_DATA) $(TOPDIR)/package/firmware/linux-firmware/xr829/fw_xr829_bt.bin
- $(<span class="hljs-number">1</span>)/$(FIRMWARE_PATH)/fw_xr829_bt.bin
- endif
- endef
- $(<span class="hljs-built_in">eval</span> $(call BuildPackage,xr829-firmware))
复制代码
说明:可以看到整个 Makefile 文件就只是做了简单的拷贝动作。
注意:一般 firmware 的路径是:系统的/lib/firmware/, 如果更改请确保是否和驱动中定义的保持一致,最新版驱动已经自适应寻找路径了, 早期的驱动版本一定要留意。
驱动中定义 firmware 文件为:xr829/wlan/etf.h
- <span class="hljs-meta">#</span><span class="bash">ifdef USE_VFS_FIRMWARE</span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_ETF_FIRMWARE (<span class="hljs-string">"/system/vendor/etc/firmware/etf_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash"><span class="hljs-keyword">else</span></span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_ETF_FIRMWARE (<span class="hljs-string">"etf_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash">endif</span>
- xr829/wlan/fwio.h
- <span class="hljs-meta">#</span><span class="bash">ifdef USE_VFS_FIRMWARE</span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_BOOTLOADER (<span class="hljs-string">"/system/vendor/etc/firmware/boot_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_FIRMWARE (<span class="hljs-string">"/system/vendor/etc/firmware/fw_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_SDD_FILE (<span class="hljs-string">"/system/vendor/etc/firmware/sdd_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash"><span class="hljs-keyword">else</span></span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_BOOTLOADER (<span class="hljs-string">"boot_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_FIRMWARE (<span class="hljs-string">"fw_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash">define XR829_SDD_FILE (<span class="hljs-string">"sdd_xr829.bin"</span>)</span>
- <span class="hljs-meta">#</span><span class="bash">endif</span>
复制代码
接着在 tina 根目录执行 m menuconfig 就可以看到新添加的 firmware 配置
- <span class="hljs-quote">> Firmware</span>
- -*- xr829-firmware..................................... Xradio xr829 firmware
- (/lib/firmware/) Firmware's directory //如想临时配置修改也可以改这里的路径
- -*- xr829 with 40M sdd
复制代码
(注意:晶振 24M 和 40M 的区分,根据实际硬件选择)
5. 应用工具适配
1)wifimanager 配置
- make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Allwinner > wifimanager</span>
复制代码
2)smartlinkd 配网配置
- make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Allwinner > smartlinkd</span>
复制代码
3)softap 配置
- make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Allwinner > softap</span>
复制代码
4)rf 工具配置
在 tina/package/utils/rftest 目录下添加 xr829 的 RF 测试工具(一般都会随产品包释放)
- tina/<span class="hljs-keyword">package</span>/utils/rftest/xr829/
- └── etf
- ├── btetf_1.4.0
- ├── btetf_riscv_1.0.5
- ├── etf
- ├── etf_riscv_1.4.0
- └── xrbt_testmode_1.4.0
复制代码
在 tina/package/utils/rftest/Makefile 中添加
- <pre class="markdown-highlight"><code class="hljs makefile"><span class="hljs-keyword">define</span> Package/xr829-rftest
- $(Package/<span class="hljs-variable">$(PKG_NAME)</span>/Default)
- TITLE:=xr829 rf test tools
- <span class="hljs-keyword">endef</span>
- <span class="hljs-keyword">define</span> Package/xr829-rftest/description
- <span class="hljs-variable">$(<span class="hljs-built_in">call</span> Package/<span class="hljs-variable">$(PKG_NAME)</span>/description/Default)</span>
- <span class="hljs-keyword">endef</span>
- <span class="hljs-keyword">define</span> Package/xr829-rftest/install
- <span class="hljs-variable">$(INSTALL_DIR)</span> /$(1)/usr/bin
- <span class="hljs-keyword">ifeq</span> (<span class="hljs-variable">$(TARGET_ARCH)</span>, riscv)
- <span class="hljs-variable">$(INSTALL_BIN)</span> ./xr829/etf/etf_riscv_1.4.0 /$(1)/usr/bin/etf
- <span class="hljs-variable">$(INSTALL_BIN)</span> ./xr829/etf/btetf_riscv_1.0.5 /$(1)/usr/bin/btetf
- <span class="hljs-keyword">else</span>
- <span class="hljs-variable">$(INSTALL_BIN)</span> ./xr829/etf/btetf_1.4.0 /$(1)/usr/bin/btetf
- <span class="hljs-variable">$(INSTALL_BIN)</span> ./xr829/etf/etf /$(1)/usr/bin/etf
- <span class="hljs-variable">$(INSTALL_BIN)</span> ./xr829/etf/xrbt_testmode_1.4.0 /$(1)/usr/bin/xrbt_testmode
- <span class="hljs-keyword">endif</span>
- <span class="hljs-keyword">endef</span>
- <span class="hljs-variable">$(<span class="hljs-built_in">eval</span> $(<span class="hljs-built_in">call</span> BuildPackage,xr829-rftest)</span>)
- </code></pre><pre class="markdown-highlight"><code class="hljs shell">make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Utilities > rf <span class="hljs-built_in">test</span> tool</span></code></pre>
复制代码
5)iperf 工具配置
- make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Network</span>
复制代码
6)wpa 工具配置
wpa 工具包括 wpa-supplicant 服务的和 wpa-cli 客户端
- make menuconfig
- <span class="hljs-meta">></span><span class="bash"> Network</span>
复制代码
6. 测试验证
wifi 的基础功能可以通过下面的步骤进行验证:
• 加载 wifi 驱动,启动 wpa_supplicant
• 扫描测试
• 联网测试
• 查看 ip 地址
• ping 百度测试
6.1 加载 wifi 驱动,启动 wpa_supplicant
1). 系统上电后使用 insmod 命令加载驱动,使用 lsmod 查看驱动是否已经加载成功。部分系统已经使用自动化脚本自动加载不需手动加载。 2). 确保 wpa_supplicant 是否起来,使用 ps 命令查看wpa_supplicant 是否起来,大部分系统由自动化脚本启动,没有启动的可以手动启动。 3). 使用 wifimanager 进行测试,Tina 系统提供了一套测试 wifi 用的测试 demo(wifimanager),wifimanager 是封装了 wpa_cli 的一套接口但使用更简单。用户可以使用这套测试 demo 来进行测试,下面只介绍 2 个 demo 其他 demo 可以参考 wifimanager 的使用说明文档。
6.2 扫描测试
wifi_scan_results_test 是 wifimanager 用于扫描 AP 用的,在控制台中输入该命令后有以下类似打印说明扫描功能正常。
- fa:8c:21:2f:2d:98 5240 -64 [<span class="hljs-string">WPA2-PSK-CCMP</span>][<span class="hljs-symbol">WPA2-PSK-CCMP</span>][<span class="hljs-string">ESS</span>] NNN
- f2:c5:d3:02:df:97 5180 -65 [<span class="hljs-string">WPA2-PSK-CCMP</span>][<span class="hljs-symbol">ESS</span>] nnn
- 7c:b5:9b:3b:2b:45 5765 -57 [<span class="hljs-string">WPA2-PSK-CCMP</span>][<span class="hljs-symbol">ESS</span>] XXX
- fa:8c:21:2f:2d:96 2417 -58 [<span class="hljs-string">WPA2-PSK-CCMP</span>][<span class="hljs-symbol">ESS</span>] xxx
复制代码
6.3 联网测试
使用命令 wifi_connect_ap_test 命令可以进行联网测试。该命令是 wifimanager 用于连接 AP用的,使用方法如下:
- wifi_connect_ap_test ssid passwd (例如:wifi_connect_ap_test AWTest <span class="hljs-number">1</span>qaz@WSX)
- 连接成功会有 <span class="hljs-keyword">connect</span> success 的 <span class="hljs-keyword">log</span> 出现。
复制代码
6.4 查看 ip 地址
使用 ifconfig 命令可以查看到获取到的 ip 值,该命令是标准命令,更详细说明请百度。
6.5 ping 百度测试
即使获取到了 ip 地址也不能说明基本功能已通,一般使用 ping 命令去进行测试 (前提 AP 是能连外网的)ping 百度测试:
- <span class="hljs-selector-tag">ping</span> <span class="hljs-selector-tag">www</span><span class="hljs-selector-class">.baidu</span><span class="hljs-selector-class">.com</span>
复制代码
如果出现下面类似的 log,说明网络基本功能已通
- <span class="hljs-attribute">PING</span> www.a.shifen.com (<span class="hljs-number">36.152.44.95</span>) <span class="hljs-number">56</span>(<span class="hljs-number">84</span>) bytes of data.
- <span class="hljs-number">64</span> bytes from <span class="hljs-number">36.152.44.95</span> (<span class="hljs-number">36.152.44.95</span>): icmp_seq=<span class="hljs-number">1</span> ttl=<span class="hljs-number">56</span> time=<span class="hljs-number">10</span>.<span class="hljs-number">5</span> ms
- <span class="hljs-number">64</span> bytes from <span class="hljs-number">36.152.44.95</span> (<span class="hljs-number">36.152.44.95</span>): icmp_seq=<span class="hljs-number">2</span> ttl=<span class="hljs-number">56</span> time=<span class="hljs-number">11</span>.<span class="hljs-number">8</span> ms
- <span class="hljs-number">64</span> bytes from <span class="hljs-number">36.152.44.95</span> (<span class="hljs-number">36.152.44.95</span>): icmp_seq=<span class="hljs-number">3</span> ttl=<span class="hljs-number">56</span> time=<span class="hljs-number">10</span>.<span class="hljs-number">7</span> ms
复制代码
至此【网络专题1】就分享完了,希望对大家有一定的帮助。 今天是2021最后一天,辞旧迎新,祝大家新年快乐,身体健康,阖家幸福!
|