OpenWrt DPDK build
编译OpenWrt系统
准备编译环境
系统为CentOS7.x mini
$ sudo yum groupinstall "Development Tools"
$ sudo yum install ncurses-devel
$ sudo yum install python3
$ sudo yum install zlib-static openssl-devel wget
下载代码
$ git clone https://git.openwrt.org/openwrt/openwrt.git
$ cd openwrt/
$ ./scripts/feeds update -a
$ ./scripts/feeds install -a
配置
$ make menuconfig
OpenWrt configuration
- Select [x86] in [Target System]
- Select [x86_64] in [Subtarget]
- Select [Build the OpenWrt SDK] for cross-compilation environment
- Select [Use glibc] in [Advanced configuration options] (for evelopers) then [ToolChain Options] and [C Library implementation]
Kernel configuration
- CONFIG_VFIO_IOMMU_TYPE1=y
- CONFIG_VFIO_VIRQFD=y
- CONFIG_VFIO=y
- CONFIG_VFIO_NOIOMMU=y
- CONFIG_VFIO_PCI=y
- CONFIG_VFIO_PCI_MMAP=y
- CONFIG_HUGETLBFS=y
- CONFIG_HUGETLB_PAGE=y
- CONFIG_PROC_PAGE_MONITOR=y
$ vi .config
CONFIG_KERNEL_CONFIG_VFIO_IOMMU_TYPE1=y
CONFIG_KERNEL_CONFIG_VFIO_VIRQFD=y
CONFIG_KERNEL_CONFIG_VFIO=y
CONFIG_KERNEL_CONFIG_VFIO_NOIOMMU=y
CONFIG_KERNEL_CONFIG_VFIO_PCI=y
CONFIG_KERNEL_CONFIG_VFIO_PCI_MMAP=y
CONFIG_KERNEL_CONFIG_HUGETLBFS=y
CONFIG_KERNEL_CONFIG_HUGETLB_PAGE=y
CONFIG_KERNEL_CONFIG_PROC_PAGE_MONITOR=y
CONFIG_KERNEL_CONFIG_UIO=y
$ vi config/Config-kernel.in
config KERNEL_CONFIG_VFIO_IOMMU_TYPE1
bool "KERNEL_CONFIG_VFIO_IOMMU_TYPE1"
default y
config KERNEL_CONFIG_VFIO_VIRQFD
bool "KERNEL_CONFIG_VFIO_VIRQFD"
default y
config KERNEL_CONFIG_VFIO
bool "KERNEL_CONFIG_VFIO"
default y
config KERNEL_CONFIG_VFIO_NOIOMMU
bool "KERNEL_CONFIG_VFIO_NOIOMMU"
default y
config KERNEL_CONFIG_VFIO_PCI
bool "KERNEL_CONFIG_VFIO_PCI"
default y
config KERNEL_CONFIG_VFIO_PCI_MMAP
bool "KERNEL_CONFIG_VFIO_PCI_MMAP"
default y
config KERNEL_CONFIG_HUGETLBFS
bool "KERNEL_CONFIG_HUGETLBFS"
default y
config KERNEL_CONFIG_HUGETLB_PAGE
bool "KERNEL_CONFIG_HUGETLB_PAGE"
default y
config KERNEL_CONFIG_PROC_PAGE_MONITOR
bool "KERNEL_CONFIG_PROC_PAGE_MONITOR"
default y
config KERNEL_CONFIG_UIO
bool "KERNEL_CONFIG_UIO"
default y
config KERNEL_NUMA_BALANCING
bool "KERNEL_CONFIG_NUMA_BALANCING"
default y
config KERNEL_NUMA_BALANCING
bool "KERNEL_CONFIG_NUMA_BALANCING"
default y
config KERNEL_NUMA
bool "KERNEL_CONFIG_NUMA"
default y
config KERNEL_AMD_NUMA
bool "KERNEL_CONFIG_AMD_NUMA"
default y
config KERNEL_X86_64_ACPI_NUMA
bool "KERNEL_CONFIG_X86_64_ACPI_NUMA"
default y
config KERNEL_USE_PERCPU_NUMA_NODE_ID
bool "KERNEL_CONFIG_USE_PERCPU_NUMA_NODE_ID"
default y
config KERNEL_ACPI_NUMA
bool "KERNEL_CONFIG_ACPI_NUMA"
default y
准备编译代码文件
$ make download V=s
编译
$ make -j1 V=sc
NUMA is required to run DPDK in x86.
For compiling the NUMA lib, run libtool –version to ensure the libtool version >= 2.2, otherwise the compilation will fail with errors.
git clone https://github.com/numactl/numactl.git
cd numactl
git checkout v2.0.13 -b v2.0.13
./autogen.sh
autoconf -i
export PATH=<OpenWrt SDK>/glibc/openwrt-sdk-x86-64_gcc-8.3.0_glibc.Linux-x86_64/staging_dir/toolchain-x86_64_gcc-8.3.0_glibc/bin/:$PATH
./configure CC=x86_64-openwrt-linux-gnu-gcc --prefix=<OpenWrt SDK toolchain dir>
make install
编译DPDK
$ tar -xvf /opt/dl/dpdk-18.02.1.tar.gz
$ export STAGING_DIR=<OpenWrt sdk>/glibc/openwrt-sdk-x86-64_gcc-8.3.0_glibc.Linux-x86_64/staging_dir
$ export RTE_SDK=`pwd`
$ export RTE_KERNELDIR=<OpenWrt Root>/build_dir/target-x86_64_glibc/linux-x86_64/linux-4.19.81/
$ export RTE_TARGET=x86_64-native-linuxapp-gcc
/* 编译动态库版本 */
$ sed -i "s/^CONFIG_RTE_BUILD_SHARED_LIB=n/CONFIG_RTE_BUILD_SHARED_LIB=y/g" config/common_base
/* D525(march=atom) 这类处理器指令集不全(SSE4_1 SSE4_2)需要修改配置 J1900不缺少(SSE4_1 SSE4_2)
/* 根本代码中的说明dpdk需要sse4_1的_mm_testz_si128函数,而支持sse4_1的最小 march=corei7 所以J1900最终应该是使用corei7编译 并不能使用默认native因为还是有部分指令集有缺失 */
$ sed -i "s/native/corei7/g" mk/machine/native/rte.vars.mk
$ make config T=x86_64-native-linuxapp-gcc O=x86_64-native-linuxapp-gcc
$ make EXTRA_CLFAGS="-D_GNU_SOURCE" CROSS=x86_64-openwrt-linux-gnu- O=x86_64-native-linuxapp-gcc
$ cd examples
$ make EXTRA_CLFAGS="-D_GNU_SOURCE" CROSS=x86_64-openwrt-linux-gnu-
编译例子
把DPDK由静态库方式改为编译成动态库后,原本正常的应用程序就不能运行了。 在初始化的时候,rte_eth_dev_count()总是返回0,而用dpdk_nic_bind.py –status查看端口是绑定成功的。
DPDK编译成动态库后,PMD的各个驱动就单独编译成了一个个的.so文件,而在应用程序中没有指定需要链接的.so文件,因此就导致了检测不到端口的问题。
PMD有好几种驱动,为了更好的移植性,建议在Makefile中指定链接所有驱动的.so文件, LDLIBS += -lrte_pmd_e1000 -lrte_pmd_i40e -lrte_pmd_ixgbe
如果应用运行在虚拟机环境的话,还需要指定librte_pmd_virtio_uio.so和librte_pmd_vmxnet3_uio.so。
$ vi mk/rte.app.mk
ifeq ($(LINK_USING_CC),1)
O_TO_EXE = $(CC) -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $(OBJS-y) -lrte_pmd_e1000 $(call linkerprefix, \
$(LDLIBS) $(LDFLAGS) $(LDFLAGS_$(@)) $(EXTRA_LDFLAGS) \
$(MAPFLAGS))
else
O_TO_EXE = $(LD) -o $@ $(OBJS-y) \
$(LDLIBS) $(LDFLAGS) $(LDFLAGS_$(@)) $(EXTRA_LDFLAGS) \
$(MAPFLAGS)
endif