从 NanoPi M2 中编译 wifi 模块中学习内核编译

朋友送的 NanoPi M2 经过上次的折腾,算是能正常开机了,但是 NanoPi M2 自己是没有 wifi 模块的,我于是祭出了自己在 pc 上用的 腾达 U12 和开源的 rtl8812AU 驱动,想让 NanoPi M2 支持我这仅有的 usb wifi。于是又开始了我作死的折腾之旅。

NanoPi M2 性能堪忧,而且 ssh 连接会突然假死,我没办法在真机上直接编译模块。虽然后来我找到 资料,可以使用~.使得卡死的 ssh 终端复活,ssh 经常卡死找不到原因,我还是使用了交叉编译。

NanoPi M2 并不在 rtl8812AU 的配置中,幸亏在 github 上找到一个 NanoPi Neo 的交叉编译模块的 教程,结合 NanoPi M2 wiki,完成了模块编译。

交叉编译器

万万没想到,编译一个内核模块是需要内核源码支持的,而为了编译内核源码,还要 uboot 的支持,而为了能正常编译前面这两个,还要准备交叉编译环境

1
2
3
git clone https://github.com/friendlyarm/prebuilts.git -b master --depth 1
cd prebuilts/gcc-x64
cat toolchain-4.9.3-armhf.tar.gz* | sudo tar xz -C /

安装好的交叉编译器在/opt/FriendlyARM/toolchain/4.9.3/bin,所以删除的话,直接sudo rm -rf /opt/FriendlyARM,为了使其生效,还需要把路径加到PATH中,我使用的是 zsh,所以是在~/.zshrc的末尾添加

1
2
export PATH=/opt/FriendlyARM/toolchain/4.9.3/bin:$PATH
export GCC_COLORS=auto

执行一下~/.zshrc脚本让设置立即在当前 shell 窗口中生效

1
. ~/.zshrc

检查一下是否已经生效

1
arm-linux-gcc -v

编译 uboot

下载 U-Boot 源代码并编译,NanoPi M2 使用的是nanopi2-lollipop-mr1分支

1
2
3
4
5
6
7
git clone https://github.com/friendlyarm/uboot_nanopi2.git
cd uboot_nanopi2
git checkout nanopi2-lollipop-mr1
# 上面的命令也能写成
# git clone https://gitee.com/friendlyelec/prebuilts.git -b nanopi2-lollipop-mr1 --depth 1
make s5p4418_nanopi2_config
make CROSS_COMPILE=arm-linux-

做了这么多,其实只是需要U-Boot中的工具mkimage,wiki 上说可以使用sudo apt-get install u-boot-tools来安装,但是我还是乖乖自己编译吧

1
2
3
cd uboot_nanopi2
make CROSS_COMPILE=arm-linux- tools
sudo mkdir -p /usr/local/sbin && sudo cp -v tools/mkimage /usr/local/sbin

emmmm,所以想删除的话可以运行sudo rm /usr/local/sbin

编译 Linux kernel

搞了这么多,终于可以编译内核了

1
2
3
4
5
it clone https://github.com/friendlyarm/linux-3.4.y.git
cd linux-3.4.y
git checkout nanopi2-lollipop-mr1
# 同样可以使用下面的代码代替
# git clone https://github.com/friendlyarm/linux-3.4.y.git -b nanopi2-lollipop-mr1 --depth 1

编译 Ubuntu Core 内核

LCD 输出:

1
make nanopi2_core-qt_defconfig

HDMI 输出:

1
make nanopi2_core-qt_hdmi_defconfig

选择自己需要的内核配置后,使用以下命令即可编译生成 uImage。

1
2
touch .scmversion
make uImage

编译内核模块

终于,到编译rtl8812AU的时候了

1
2
3
4
5
git clone https://github.com/gnab/rtl8812au.git
cd rtl8812au
make KSRC=/home/bubao/Workspaces/linux/linux-3.4.y \
CROSS_COMPILE=arm-linux- \
ARCH=arm

编译后生成8812au.ko,检查一下

1
2
file 8812au.ko
8812au.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=a93331169d61966a05bfb2830cd65f5faa1b744e, with debug_info, not stripped

把模块发到 pi 上

1
scp 8812au.ko pi@192.168.1.11:/home/pi/

安装

1
2
3
sudo cp /home/pi/8812au.ko /lib/modules/3.4.39-s5p4418/kernel/drivers/net/wireless/8812au.ko
sudo depmod
sudo insmod /lib/modules/3.4.39-s5p4418/kernel/drivers/net/wireless/8812au.ko

报错了?

1
insmod: ERROR: could not insert module 8812au.ko: Unknown symbol in module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ dmesg | tail -n 19
[ 9.408000] Bluetooth: HCI UART driver ver 2.3
[ 9.416000] Bluetooth: HCI UART protocol H4 registered
[ 9.424000] Bluetooth: HCI UART protocol BCM registered
[ 9.436000] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 9.444000] Bluetooth: BNEP filters: protocol multicast
[ 9.452000] Bluetooth: BNEP socket layer initialized
[ 9.472000] setting PHY_BASEADDR_POWER_GATE, set 1
[ 9.480000] setting PHY_BASEADDR_PMU_ISOLATE+4, set 0
[ 9.488000] setting PHY_BASEADDR_PMU_ISOLATE+8, set 0
[ 9.496000] setting PHY_BASEADDR_PMU_ISOLATE, set 1
[ 9.504000] read PHY_BASEADDR_PMU_ISOLATE + 0xC
[ 9.512000] Wait Power UP Ack(powerUpAck=0x00000000)
[ 9.520000] setting ClockGen, set 1
[ 9.528000] setting Reset VR addr(0xf0012008)
[ 9.536000] setting PHY_BASEADDR_VR_PMU addr(0xf0072000)
[ 9.544000] Vr: VR device driver loaded(ver1.2) for s5p4418
[ 11.208000] eth0: device MAC address 9a:63:b3:25:10:7e
[ 14.988000] PHY: stmmac-0:07 - Link is Up - 1000/Full
[ 4336.044000] 8812au: Unknown symbol kernel_write (err 0)

查看一下,果然还是没加载上来呢

1
2
3
4
5
6
7
8
9
10
$lsmod
Module Size Used by
nx_vpu 351383 0
vr 142655 0
bnep 11245 0
hci_uart 14744 0
btbcm 5120 1 hci_uart
bluetooth 385422 3 bnep,btbcm,hci_uart
cfg80211 459462 0
compat 23995 4 bnep,cfg80211,hci_uart,bluetooth
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
$ modinfo 8812au.ko 
filename: /home/pi/8812au.ko
version: v4.2.3
author: Realtek Semiconductor Corp.
description: Realtek Wireless Lan Driver
license: GPL
srcversion: A0769B96B082C1E7D80256F
alias: usb:v2357p0120d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2357p011Ed*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp0823d*dc*dsc*dp*ic*isc*ip*
alias: usb:v3823p6249d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2001p3318d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDApA811d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04BBp0959d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04BBp0953d*dc*dsc*dp*ic*isc*ip*
alias: usb:v056Ep4007d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0411p029Bd*dc*dsc*dp*ic*isc*ip*
alias: usb:v0411p0242d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2019pAB32d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0846p9052d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2001p3314d*dc*dsc*dp*ic*isc*ip*
alias: usb:v7392pA813d*dc*dsc*dp*ic*isc*ip*
alias: usb:v7392pA812d*dc*dsc*dp*ic*isc*ip*
alias: usb:v7392pA811d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp8822d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp0821d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp0811d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2604p0012d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp8812d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0411p025Dd*dc*dsc*dp*ic*isc*ip*
alias: usb:v2357p0122d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2357p010Ed*dc*dsc*dp*ic*isc*ip*
alias: usb:v2357p010Dd*dc*dsc*dp*ic*isc*ip*
alias: usb:v2357p0103d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2357p0101d*dc*dsc*dp*ic*isc*ip*
alias: usb:v20F4p805Bd*dc*dsc*dp*ic*isc*ip*
alias: usb:v2001p3316d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2001p3315d*dc*dsc*dp*ic*isc*ip*
alias: usb:v07B8p8812d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2019pAB30d*dc*dsc*dp*ic*isc*ip*
alias: usb:v1740p0100d*dc*dsc*dp*ic*isc*ip*
alias: usb:v13B1p003Fd*dc*dsc*dp*ic*isc*ip*
alias: usb:v1058p0632d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2001p3313d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0586p3426d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0E66p0022d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0B05p17D2d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0409p0408d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0789p016Ed*dc*dsc*dp*ic*isc*ip*
alias: usb:v04BBp0952d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0DF6p0074d*dc*dsc*dp*ic*isc*ip*
alias: usb:v7392pA822d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2001p330Ed*dc*dsc*dp*ic*isc*ip*
alias: usb:v050Dp1109d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2604p0012d*dc*dsc*dp*ic*isc*ip*
alias: usb:v050Dp1106d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp881Cd*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp881Bd*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp881Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp8812d*dc*dsc*dp*ic*isc*ip*
depends:
vermagic: 3.4.39-s5p4418 SMP preempt mod_unload ARMv7 p2v8
parm: rtw_ips_mode:The default IPS mode (int)
parm: rtw_regulatory_id:int
parm: ifname:The default name to allocate for first interface (charp)
parm: if2name:The default name to allocate for second interface (charp)
parm: rtw_initmac:charp
parm: rtw_channel_plan:int
parm: rtw_chip_version:int
parm: rtw_rfintfs:int
parm: rtw_lbkmode:int
parm: rtw_network_mode:int
parm: rtw_channel:int
parm: rtw_mp_mode:int
parm: rtw_wmm_enable:int
parm: rtw_vrtl_carrier_sense:int
parm: rtw_vcs_type:int
parm: rtw_busy_thresh:int
parm: rtw_ht_enable:int
parm: rtw_bw_mode:int
parm: rtw_ampdu_enable:int
parm: rtw_rx_stbc:int
parm: rtw_ampdu_amsdu:int
parm: rtw_vht_enable:int
parm: rtw_lowrate_two_xmit:int
parm: rtw_rf_config:int
parm: rtw_power_mgnt:int
parm: rtw_smart_ps:int
parm: rtw_low_power:int
parm: rtw_wifi_spec:int
parm: rtw_antdiv_cfg:int
parm: rtw_antdiv_type:int
parm: rtw_enusbss:int
parm: rtw_hwpdn_mode:int
parm: rtw_hwpwrp_detect:int
parm: rtw_hw_wps_pbc:int
parm: rtw_max_roaming_times:The max roaming times to try (uint)
parm: rtw_mc2u_disable:int
parm: rtw_80211d:Enable 802.11d mechanism (int)
parm: rtw_notch_filter:0:Disable, 1:Enable, 2:Enable only for P2P (uint)
parm: rtw_led_enable:Enable status LED (int)

总结

虽然最后没能在NanoPi M2上成功驱动腾达 U12,但是还是学会很多东西的。

参考 & 资料


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!