Using NFV Access SDKs Enea NFV Access comes with two standard SDKs which can be used to develop user-applications and kernel modules for both host and guest images. A standard SDK consists of: Cross-Development Toolchain: cross-compiler and cross-debugger Libraries, Headers and Symbols that are specific to the image Environment Setup Script which defines the environment variables To install the SDK on your host development machine, there are two installation scripts available under the Download section on portal.enea.com. They have self explanatory names. inteld1521/sdk/enea-glibc-x86_64-enea-image-virtualization-host-sdkcorei7-64-toolchain-7.0.sh - for host applications. qemux86-64/sdk/enea-glibc-x86_64-enea-image-virtualization-guestsdk-core2-64-toolchain-7.0.sh - for guest applications. After installing the SDK, a developer will be able to compile and generate executables for the preferred target machine. Cross-gdb (x86_64-enea-linux-gdb) is created by the Cross-Development toolchain. It can be used to debug applications on the target platform from the development workstation. For kernel debugging, ftrace and kgdb are enabled on the host sdk image. Various user-space tools helpful in the development process, are also provided. The tools include LatencyTop, Perf, CrossTap, OProfile, Lttng-ust and GDBserver.
Installing the Cross-Compilation Toolchain Before cross-compiling applications for your target, you need to install the corresponding toolchain on your workstation. To do that, simply run the installer and follow the steps included with it: $ ./enea-glibc-x86_64-enea-image-virtualization-guest-sdk-core2-64-toolchain-7.0.shWhen prompted, select to install the toolchain in the desired directory, referred to as sdkdir. A default path where the toolchain will be installed will be shown in the prompt. The installer unpacks the environment setup script in sdkdir and the toolchain under sdkdir/sysroots. Choose a unique directory for each toolchain. Installing a second toolchain of any type in the same directory as a previously installed one will break the $PATH variable of the first one. Setup the toolchain environment for your target by sourcing the environment-setup script. Example: $ source sdkdir/environment-setup-core2-64-enea-linux
Cross-Compiling Applications from Command Line Once the environment-setup script is sourced, you can make your applications as per usual and get them compiled for your target. Below you see how to cross-compile from command line. Create a Makefile for your application. Example: a simple Makefile and application: helloworld:helloworld.o $(CC) -o helloworld helloworld.o clean: rm -f *.o helloworld #include stdio.h; int main(void) { printf("Hello World\n"); return 0; } Run make to cross-compile your application according to the environment set up: $ make Deploy the helloworld program to your target and run it: # ./helloworld hello world
Cross-Compiling Kernel Modules Before cross-compiling kernle modules, you need to make sure the installed toolchain includes the kernel source tree, which should be available at: sdkdir/sysroots/targetarch-enea-linux/usr/src/kernel. Once the environment-setup script is sourced, you can make your kernel modules as usual and get them compiled for your target. Below you see how to cross-compile a kernel module. Create a Makefile for the kernel module. Example: a simple Makefile and kernel module: obj-m := hello.o PWD := $(shell pwd) KERNEL_SRC := full path to kernel source tree all: scripts $(MAKE) -C $(KERNEL_SRC) M=$(PWD) LDFLAGS="" modules scripts: $(MAKE) -C $(KERNEL_SRC) scripts clean: $(MAKE) -C $(KERNEL_SRC) M=$(PWD) LDFLAGS="" clean #include linux/module.h /* Needed by all modules */ #include linux/kernel.h /* Needed for KERN_INFO */ #include linux/init.h /* Needed for the macros */ static int __init hello_start(void) { printk(KERN_INFO "Loading hello module...\n"); printk(KERN_INFO "Hello, world\n"); return 0; } static void __exit hello_end(void) { printk(KERN_INFO "Goodbye, world\n"); } module_init(hello_start); module_exit(hello_end); MODULE_LICENSE("GPL"); Run make to cross-compile your kernel module according to the environment set up: $ make Deploy the kernel module hello.ko to your target and install/remove it: # insmod hello.ko # rmmod hello.ko # dmesg [...] Loading hello module... [...] Hello, world [...] Goodbye, world
Deploying your artifacts
Deploying on host You can use ssh to deploy your artifacts on the host target. For this you will need a network connection to the target, to use scp to copy to the desired location. # scp helloworld root@<target_ip_address>:/tmp
Deploying on guest You can deploy your artifacts onto the guest VM running on the target, by using TAP Networking. You can use the /etc/qemu-ifup script to create the tap interface on the host and attach it to the existing virtual bridge (virbr0). This bridge interface is created by the libvirt library and can be used to connect to the outside network. To be able to transfer files to the guest via scp, port forwarding should be enabled on the host. The script sets iptables rules to forward traffic from a host port to the guest default SSH port (22). Follow the steps below to create this setup: On the host, run the qemu-ifup script located in /etc directory: # /etc/qemu-ifup –t tap0 –a 192.168.122.10 –p 1050 –g 22 tap0 - the tap interface name which will be created and added to the virtual bridge (virbr0). 192.168.122.10 - the IP address of the guest virtual network device. It has to be in the same network with the IP address of the virbr0 interface. 1050 - the host port which is set to forward traffic from the host to the guest. 22 - the default SSH guest port used in port forwarding. Launch the virtual machine specifying the newly created tap interface: -device e1000,netdev=net0 \ -netdev tap,id=net0,ifname=tap0,script=no,downscript=no On the guest, after logging, configure the virtual network device and set the default gateway as the virbr0 ip address: ip addr add 192.168.122.10/24 dev enp0s2 ip link set enp0s2 up ip route add default via 192.168.122.1 dev enp0s2 Now you can use scp from your development machine to deploy your artifacts on the guest, by giving the host port for forwarding as a command parameter: scp -P 1050 helloworld root@target_ip_address:/tmp On the host, after finishing the deployment session and stopping the virtual machine, you can use the qemu-ifdown script to clean up the configuration on host. The following command will remove the tap interface and all the iptables rules for the specific ip address: # /etc/qemu-ifdown –t tap0 –a 192.168.122.10If we need to remove only a particular port forwarding rule from iptables, this should be run: # /etc/qemu-ifdown –t tap0 –a 192.168.122.10 –p 1050 –g 22
Cross-Debugging on Enea NFV Access The cross-debugger (x86_64-enea-linux-gdb) is created when installing the SDK on the development machine. It is helpful for debugging both the kernel and user-applications. In order to perform this task, we need the following tools to be available on the target machine: Kgdb – for kernel cross-debugging GDBServer – for application cross-debugging The Host Development image provides both of these tools and has to be booted on the target machine for cross-debugging sessions.
User-application Cross-Debugging on Host To debug a user-application on host, a TCP connection has to be established between the host and development machines. GDBserver is the program which runs on the target machine and allows you to run GDB on your workstation. Below you can find how a simple helloworld application can be debugged using GDBServer and cross-gdb. On target, launch the GDBServer, specifying how to communicate with GDB and the name of your program:# gdbserver :<port_no> /tmp/helloworldThe target will now be listening on the port given as a parameter to the gdbserver. On the development machine, from the <sdkdir>, start the cross-gdb:# x86_64-enea-linux-gdb <path_to_the_program>/helloworldConnect the GDB to the target: (gdb) target remote <target_ip_address>:<port_no>Now remote debugging is started and the GDB commands are available to debug your program from the target machine.
User-application Cross-Debugging on Guest To debug a user-application on guest, a TCP connection has to be established between the host and development machines. Similarly, as when deploying artifacts on guest, for a cross-debugging session, TAP Networking is required. A tap interface should be added to the existing virtual bridge (virbr0), along with port forwarding rules created in iptables. In order to do this, the script /etc/qemu-ifup can pe used: On the host, run the script qemu-ifup located in /etc directory: # /etc/qemu-ifup –t tap0 –a 192.168.122.10 –p 1051 –g 1025 tap0 - the tap interface name which will be created and added to virtual bridge (virbr0). 192.168.122.10 - the IP address of the guest virtual network device. It has to be in the same network with the IP address of the virbr0 interface. 1051 – the host port which is set to forward traffic from the host to the guest and is used by gdb target remote command. 1025– the port used by GDBServer on guest for listening. Launch the virtual machine, specifying the newly created tap interface:-device e1000,netdev=net0 \ -netdev tap,id=net0,ifname=tap0,script=no,downscript=no On the guest, after logging, configure the virtual network device and set the default gateway to virbr0 ip address:ip addr add 192.168.122.10/24 dev enp0s2 ip link set enp0s2 up ip route add default via 192.168.122.1 dev enp0s2 GDBserver is the program which runs on the guest VM and allows you to run GDB on your workstation. On the guest, launch GBDserver specifying how to communicate with GDB and the name of your program: # gdbserver :1025 /tmp/helloworldThe guest is now listening on port 1025, given as a parameter to the gdbserver. On the development machine, from the <sdkdir>, start the cross-gdb:# x86_64-enea-linux-gdb <path_to_the_program>/helloworld Connect GDB to the target:(gdb) target remote <target_ip_address>:1051Now remote debugging is started and the GDB commands are available to debug your program from the guest VM. On the host, after finishing the cross-debugging session and stopping the virtual machine, you can use the qemu-ifdown script to clean up the configuration on host:# /etc/qemu-ifdown -t tap0 -a 192.168.122.10
Kernel Cross-Debugging In order to debug the kernel, a serial connection is required between the development and target machines. Debugging commands will be sent from your workstation to the target machine via a serial port. The KGDB kernel options are enabled in the Enea NFV Access Host SDK image and the tool can be used in the following way: On target, once serial communication is established, configure kgdboc after the kernel boots:# echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc In order to connect to gdb via kgdboc, the kernel must first be stopped:# echo g > /proc/sysrq-trigger Close the console to the target, eg.: Ctrl + ] for a telnet session. On your development machine, start cross-gdb using the vmlinux kernel image as a parameter. The image is located in <sdkdir>/sysroots/corei7-64-enea-linux/boot/ and should be the same as the image found in the /boot directory from the target.# x86_64-enea-linux-gdb / ./sysroots/corei7-64-enea-linux/boot/vmlinux-4.9.30-intel-pk-standard Connect GDB to the target machine using target command and the serial device:(gdb) set remotebaud 115200 (gdb) target remote /dev/ttyS0 The kernel can now be debugged in a similar manner as an application program.