Compile Driver for ESPRESSObin
The following instructions shows how to prepare BLACK bean on ESPRESSObin running Linux with ath10k driver. We recommend using Debian or Ubuntu. It also might be possible to compile on OSX. Compiling directly on a Windows platform is not supported. However, if all you have available is a windows machine then we would recommend to set up a Linux based virtual machine.
Before compiling ath10k drivers for ESPRESSObin, you have to prepare the kernel and a buildroot file system. Official guides listed below:
Also make sure to install required packages as listed on ESPRESSObin build system requirements
sudo apt-get update sudo apt-get install sed make binutils build-essential gcc g++ bash patch gzip bzip2 perl tar cpio python unzip rsync zlib1g-dev gawk ccache gettext libssl-dev xsltproc bc file lib32ncurses5-dev
Prepare toolchain
1. Download the toolchain (place at /home/user/toolchain
):
mkdir -p toolchain && cd toolchain wget https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/aarch64-linux-gnu/gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu.tar.xz
2. Extract the archive:
tar -xvf gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu.tar.xz
3. Add toolchain to path. Change your path to toolchain accordingly:
export PATH=$PATH:/home/${USER}/toolchain/gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu/bin
Prepare kernel sources
1. Download the sources (place at /home/user/kernel/4.14.22/
):
mkdir -p kernel/4.14.22 && cd kernel/4.14.22/ git clone https://github.com/MarvellEmbeddedProcessors/linux-marvell.git -b linux-4.14.22-armada-18.09 .
2. Export the environment variables:
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu-
3. Create default kernel configuration file:
make mvebu_v8_lsp_defconfig
4. Add cfg80211 module to kernel configure file:
make menuconfig
In the menu config enable the following (press space to enable, symbol [M] for modules or [*] for built-in modules will appear):
[*] Networking support -> Wireless [*] Wireless -> cfg80211 - wireless configuration API [*] Wireless -> nl80211 testmode command [*] Wireless -> cfg80211 wireless extensions compatibility [*] Wireless -> Generic IEEE 802.11 Networking Stack (mac80211)
[*] Device Drivers -> Network device support -> Wireless LAN -> Atheros/Qualcomm devices [M] Atheros 802.11ac wireless cards support [M] Atheros ath10k PCI support
[*] Device Drivers -> Network device support -> Wireless LAN
[*] General setup -> Kernel->user space relay support (formerly relayfs)
Then save and exit.
5. Start building kernel:
make -j$(nproc)
Once the build process finishes, your Image
will be located in arch/arm64/boot/
while device tree blob (armada-3720-community.dtb) will be placed at arch/arm64/boot/dts/marvell/
.
Prepare buildroot file system
1. Download the sources:
mkdir ~/buildroot && cd ~/buildroot/ git clone -b buildroot-2015.11-16.08 https://github.com/MarvellEmbeddedProcessors/buildroot-marvell .
2. Create default configuration file:
make mvebu_armv8_le_defconfig
3. Configure buildroot:
make menuconfig
In menuconfig, select toolchain and enable the following (note that some of these settings might be pre-configured already):
[*] Toolchain Type -> External toolchain
[*] Toolchain -> Custom toolchain
[*] Toolchain origin -> Pre-installed toolchain)
Change /user/
to your own.
[*] Toolchain path -> /home/user/toolchain/gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu/
[*] Toolchain prefix -> aarch64-linux-gnu
[*] External toolchain gcc version --> 5.x
[*] External toolchain kernel headers series -> 4.0.x(
After setting up the toolchain, additionaly can add other packages:
[*] Target packages -> Networking applications -> iw
[*] Target packages -> Networking applications -> wpa_supplicant
Save the '.config' and exit.
4. Change the FIO_SITE variable to use correct repository server:
nano package/fio/fio.mk
Change 8 line from:
FIO_SITE = https://fossies.org/linux/misc
to:
FIO_SITE = https://github.com/axboe/fio/archive
5. Start building root file system:
make -j$(nproc)
If the build process finishes successfully, your images will be placed in output/images/
.
If you get the gdate.c:2497:7: error, see https://github.com/widora/openwrt_widora/issues/12
For ./buildtools/bin/waf", line 76 error, visit http://git.catalyst.net.nz/gw?p=samba.git;a=commitdiff_plain;h=edb109f6
For host-lzop-1.03/.stamp_configured' failed, visit https://raw.githubusercontent.com/openembedded/openembedded-core/master/meta/recipes-support/lzop/lzop/lzop-1.03-gcc6.patch
Prepare USB drive
Prepare USB drive to format it and boot from it. Any USB drive above 1GB of storage will do.
1. Wipe the USB drive (must have at least 1GB storage, also double check USB label with fdisk -l (in our case - /dev/sdb):
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=100
2. Create partition:
(echo n; echo p; echo 1; echo ''; echo ''; echo w) | sudo fdisk /dev/sdb
3. Create file system:
sudo mkfs.ext4 /dev/sdb1
4. Create directory and mount the USB drive:
sudo mkdir -p /mnt/usb sudo mount /dev/sdb1 /mnt/usb
5. Select mounted directory and extract the file system:
cd /mnt/usb sudo tar -xvf /home/user/buildroot/output/images/rootfs.tar.gz
6. Make boot directory then copy the kernel and device tree:
sudo mkdir -p boot sudo cp /home/user/kernel/4.14.22/arch/arm64/boot/Image /mnt/usb/boot/ sudo cp /home/user/kernel/4.14.22/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtb /mnt/usb/boot/armada-3720-community.dtb
7. Install modules:
cd /home/user/kernel/4.14.22/ make INSTALL_MOD_PATH=~/tmp/ modules_install sudo cp -r ~/tmp/* /mnt/usb/
8. Copy binary files from this repo:
mkdir -p /mnt/usb/lib/firmware/ath10k/QCA9377/hw1.0/ cp ath10k-firmware/QCA9377/hw1.0/WLAN.TF.1.0/firmware-5.bin_WLAN.TF.1.0-00002-QCATFSWPZ-5 /mnt/usb/lib/firmware/ath10k/QCA9377/hw1.0/firmware-5.bin cp ath10k-firmware/QCA9377/hw1.0/board.bin /mnt/usb/lib/firmware/ath10k/QCA9377/hw1.0/ cp ath10k-firmware/QCA9377/hw1.0/board-2.bin /mnt/usb/lib/firmware/ath10k/QCA9377/hw1.0/
9. Go to USB drive and do sync
cd /mnt/usb sync
10. Change working directory and unmount the USB drive
cd sudo umount /mnt/usb
Booting from USB
1. Connect USB cable to ESPRESSObin and check, how connection is named
dmesg | tail
The output should be similar to:
[86000.246258] pl2303 2-1.3:1.0: device disconnected [86001.904945] usb 2-1.3: new full-speed USB device number 11 using ehci-pci [86002.057267] pl2303 2-1.3:1.0: pl2303 converter detected [86002.059323] usb 2-1.3: pl2303 converter now attached to ttyUSB0
Our device: ttyUSB0
2. Connect to device (serial in this case):
picocom -b 115200 /dev/ttyUSB0
3. Plug the external power to the board and enter bootloader:
While booting, keep repeatedly pressing ESC until you're inside the bootloader.
4. Plug in USB device into USB2 port and verify that it's recognized (execute command inside bootloader):
usb start
Should see: ext4ls usb 0:1 boot
5. Set environment variables (execute command inside bootloader):
setenv image_name boot/Image setenv fdt_name boot/armada-3720-community.dtb setenv bootusb 'usb start;ext4load usb 0:1 $kernel_addr $image_name;ext4load usb 0:1 $fdt_addr $fdt_name;setenv bootargs $console root=/dev/sda1 rw rootwait; booti $kernel_addr - $fdt_addr' saveenv
6. Begin booting from USB (execute command inside bootloader):
run bootusb
7. Login and insert module: If everything was done correctly, should be greeted with:
Welcome to Buildroot buildroot login:
The default login name is root
, no password.
Welcome to Buildroot buildroot login: root
To insert modules, use modprobe command:
modprobe ath modprobe ath10k_core modprobe ath10_pci
The interfaces wlan0
should be created:
# ip l 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 32:22:84:41:5d:8f brd ff:ff:ff:ff:ff:ff 3: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 532 link/ether f0:ad:4e:04:96:3a brd ff:ff:ff:ff:ff:ff 4: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1 link/sit 0.0.0.0 brd 0.0.0.0 5: wan@eth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop switchid 00000000 state DOWN mode DEFAULT group default qlen 1000 link/ether f0:ad:4e:04:96:3a brd ff:ff:ff:ff:ff:ff 6: lan0@eth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop switchid 00000000 state DOWN mode DEFAULT group default qlen 1000 link/ether f0:ad:4e:04:96:3a brd ff:ff:ff:ff:ff:ff 7: lan1@eth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop switchid 00000000 state DOWN mode DEFAULT group default qlen 1000 link/ether f0:ad:4e:04:96:3a brd ff:ff:ff:ff:ff:ff 8: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether c4:93:00:0f:93:6a brd ff:ff:ff:ff:ff:ff 9: p2p0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether c6:93:00:90:93:6a brd ff:ff:ff:ff:ff:ff
Possible issue
When you choose to compile Atheros 802.11ac wireless cards support, Atheros ath10k PCI support modules into kernel, you will probably get this error. It is because system root filesystem is not mounted at driver initialization stage. Driver will fail to load firmware files that usually stored on root filesystem, because system will not find it.
[ 3.794813] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/cal-pci-0000:00:00.0.bin failed with error -2 [ 3.794813] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/cal-pci-0000:00:00.0.bin failed with error -2 [ 3.794848] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-6.bin failed with error -2 [ 3.794848] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-6.bin failed with error -2 [ 3.794881] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-5.bin failed with error -2 [ 3.794881] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-5.bin failed with error -2 [ 3.794914] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-4.bin failed with error -2 [ 3.794914] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-4.bin failed with error -2 [ 3.794949] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-3.bin failed with error -2 [ 3.794949] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-3.bin failed with error -2 [ 3.794983] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-2.bin failed with error -2 [ 3.794983] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-2.bin failed with error -2 [ 3.794990] ath10k_pci 0000:00:00.0: Failed to find firmware-N.bin (N between 2 and 6) from ath10k/QCA9377/hw1.0: -2 [ 3.794990] ath10k_pci 0000:00:00.0: Failed to find firmware-N.bin (N between 2 and 6) from ath10k/QCA9377/hw1.0: -2 [ 3.794995] ath10k_pci 0000:00:00.0: could not fetch firmware files (-2) [ 3.794995] ath10k_pci 0000:00:00.0: could not fetch firmware files (-2) [ 3.795017] ath10k_pci 0000:00:00.0: could not probe fw (-2) [ 3.795017] ath10k_pci 0000:00:00.0: could not probe fw (-2)
Workaround here is to unbind pci device after system boots, and then again bind it. Go to ath10k_pci folder
# cd /sys/bus/pci/drivers/ath10k_pci
Check for device pci address, which is 0000:00:00.0
# ls 0000:00:00.0 bind module new_id remove_id uevent unbind
Unbind it and then bind.
# echo "0000:00:00.0" > unbind # echo "0000:00:00.0" > bind
After these steps, module should be loaded correctly.
[ 1527.336741] ath10k_pci 0000:00:00.0: pci irq msi oper_irq_mode 2 irq_mode 0 reset_mode 0 [ 1527.666879] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/pre-cal-pci-0000:00:00.0.bin failed with error -2 [ 1527.677745] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/cal-pci-0000:00:00.0.bin failed with error -2 [ 1527.688547] ath10k_pci 0000:00:00.0: Direct firmware load for ath10k/QCA9377/hw1.0/firmware-6.bin failed with error -2 [ 1527.700995] ath10k_pci 0000:00:00.0: qca9377 hw1.1 target 0x05020001 chip_id 0x003821ff sub 0000:0000 [ 1527.710565] ath10k_pci 0000:00:00.0: kconfig debug 0 debugfs 0 tracing 0 dfs 0 testmode 1 [ 1527.721142] ath10k_pci 0000:00:00.0: firmware ver WLAN.TF.1.0-00002-QCATFSWPZ-5 api 5 features ignore-otp crc32 c3e0d04f [ 1527.796015] ath10k_pci 0000:00:00.0: failed to fetch board data for bus=pci,vendor=168c,device=0042,subsystem-vendor=0000,subsystem-device=0000 from ath10k/QCA9377/hw1.0/board-2.bin [ 1527.812963] ath10k_pci 0000:00:00.0: board_file api 1 bmi_id N/A crc32 544289f7 [ 1528.447934] ath10k_pci 0000:00:00.0: htt-ver 3.44 wmi-op 4 htt-op 3 cal otp max-sta 32 raw 0 hwcrypto 1