Compile Driver for Linux (ESPRESSObin)
The following instructions cover the driver compiling process for RED bean on devices running Linux. 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 qcacld 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.4.52/
):
mkdir -p kernel/4.4.52 && cd kernel/4.4.52/ git clone -b linux-4.4.52-armada-17.06 https://github.com/MarvellEmbeddedProcessors/linux-marvell .
2. Apply official ESPRESSObin kernel patches:
wget -O kernel_patches.zip "wiki.espressobin.net/tiki-download_file.php?fileId=150" unzip kernel_patches.zip git apply kernel_patches/0001-fix-regulator-armada-37xx-overwrite-CPU-voltage-valu.patch git apply kernel_patches/0002-fix-ARM64-dts-marvell-armada-37xx-update-CPU-voltage.patch
3. Get the latest qcacld-2.0 sources from 8devices:
git clone https://github.com/8devices/qcacld-2.0.git -b caf-wlan/LNX.LEH.4.2.2.2 ~/qcacld-2.0
4. Copy and apply qcacld driver patches:
cp ~/qcacld-2.0/patches/Marvell-ESPRESSObin/0003-qcacld-gpio-stdio-voltage.patch . cp ~/qcacld-2.0/patches/Marvell-ESPRESSObin/0004-qcacld-64bit-kernel.patch . git apply 0003-qcacld-gpio-stdio-voltage.patch git apply 0004-qcacld-64bit-kernel.patch
5. Export the environment variables:
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu-
6. Create default kernel configuration file:
make mvebu_v8_lsp_defconfig
7. Add cfg80211 module to kernel configure file:
make menuconfig
In the menu config enable the following (press space to enable, symbol * will appear):
* Networking support -> Wireless
* Wireless -> cfg80211
* Wireless -> nl80211
* Wireless -> cfg80211 wireless extensions compatibility
* Wireless -> Generic IEEE 802.11 Networking Stack (mac80211)
Then save and exit.
8. 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. Apply ESPRESSObin patch to buildroot:
cp ~/qcacld-2.0/patches/Marvell-ESPRESSObin/Buildroot-fio-reop.patch . patch -p1 < Buildroot-fio-reop.patch
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
Building qcacld driver
1. Download the sources:
git clone https://github.com/8devices/qcacld-2.0.git -b caf-wlan/LNX.LEH.4.2.2.2 cd qcacld-2.0
2. Edit variables in the make file ARCH, KERNEL_SRC, CROSS_COMPILE accordingly (also change /user/
to your own):
ARCH = arm64 KERNEL_SRC = /home/user/kernel/4.4.52 CROSS_COMPILE = /home/user/toolchain/gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
3. Start building the qcacld driver:
make -j$(nproc)
If the build process completes successfully, then you should be able to locate wlan-sdio.ko
in qcacld-2.0
directory
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.4.52/arch/arm64/boot/Image /mnt/usb/boot/ sudo cp /home/user/kernel/4.4.52/arch/arm64/boot/dts/marvell/armada-3720-community.dtb /mnt/usb/boot/
7. Copy compiled qcacld driver to root folder:
sudo cp ~/qcacld-2.0/wlan-sdio.ko /mnt/usb/ sudo cp -r ~/qcacld-2.0/firmware/sdio/. /mnt/usb/
8. 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 sould 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 module, use insmod wlan-sdio.ko
command:
insmod wlan-sdio.ko
The interfaces wlan0
and p2p0
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