diff options
Diffstat (limited to 'doc/book-enea-nfv-access-guide/doc/using_nfv_access_sdks.xml')
-rw-r--r-- | doc/book-enea-nfv-access-guide/doc/using_nfv_access_sdks.xml | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/doc/book-enea-nfv-access-guide/doc/using_nfv_access_sdks.xml b/doc/book-enea-nfv-access-guide/doc/using_nfv_access_sdks.xml deleted file mode 100644 index df5df43..0000000 --- a/doc/book-enea-nfv-access-guide/doc/using_nfv_access_sdks.xml +++ /dev/null | |||
@@ -1,473 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="ISO-8859-1"?> | ||
2 | <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" | ||
3 | "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> | ||
4 | <chapter id="workflow"> | ||
5 | <title>Using Enea NFV Access SDKs</title> | ||
6 | |||
7 | <para>Enea NFV Access comes with a standard SDK which can be used to develop | ||
8 | user-applications and kernel modules for both host and guest images.</para> | ||
9 | |||
10 | <para>The standard SDK consists of:</para> | ||
11 | |||
12 | <itemizedlist> | ||
13 | <listitem> | ||
14 | <para>Cross-Development Toolchain: cross-compiler and | ||
15 | cross-debugger</para> | ||
16 | </listitem> | ||
17 | |||
18 | <listitem> | ||
19 | <para>Libraries, Headers and Symbols that are specific to the | ||
20 | image</para> | ||
21 | </listitem> | ||
22 | |||
23 | <listitem> | ||
24 | <para>Environment Setup Script which defines the environment | ||
25 | variables</para> | ||
26 | </listitem> | ||
27 | </itemizedlist> | ||
28 | |||
29 | <para>To install the SDK on your host development machine, there is an | ||
30 | installation script available under the Download section on <ulink | ||
31 | url="https://portal.enea.com/">portal.enea.com</ulink>:</para> | ||
32 | |||
33 | <itemizedlist> | ||
34 | <listitem> | ||
35 | <para>aarch/install/install-sdk.sh</para> | ||
36 | </listitem> | ||
37 | </itemizedlist> | ||
38 | |||
39 | <para>After installing the SDK, a developer will be able to compile and | ||
40 | generate executables for the preferred target machine. Cross-gdb | ||
41 | (<filename>enea-linux-gdb</filename>) is created by the Cross-Development | ||
42 | toolchain. It can be used to debug applications on the target platform from | ||
43 | the development workstation. For kernel debugging, <command>ftrace</command> | ||
44 | and <command>kgdb</command> are enabled on the host sdk image.</para> | ||
45 | |||
46 | <para>Various user-space tools helpful in the development process, are also | ||
47 | provided. The tools include <emphasis role="bold">LatencyTop</emphasis>, | ||
48 | <emphasis role="bold">Perf</emphasis>, <emphasis | ||
49 | role="bold">CrossTap</emphasis>, <emphasis role="bold">OProfile</emphasis>, | ||
50 | <emphasis role="bold">Lttng-ust</emphasis> and <emphasis | ||
51 | role="bold">GDBserver</emphasis>.</para> | ||
52 | |||
53 | <section id="install-crosscomp"> | ||
54 | <title>Installing the Cross-Compilation Toolchain</title> | ||
55 | |||
56 | <para>Before cross-compiling applications for your target, you need to | ||
57 | install the corresponding toolchain on your workstation. To do that, | ||
58 | simply run the installer and follow the steps included with it:</para> | ||
59 | |||
60 | <orderedlist> | ||
61 | <listitem> | ||
62 | <para><programlisting>$ ./install-sdk.sh</programlisting>When | ||
63 | prompted, select to install the toolchain in the desired directory, | ||
64 | referred to as <literal>sdkdir</literal>.</para> | ||
65 | |||
66 | <para>A default path where the toolchain will be installed will be | ||
67 | shown in the prompt. The installer unpacks the environment setup | ||
68 | script in <literal>sdkdir</literal> and the toolchain under | ||
69 | <literal>sdkdir/sysroots</literal>.</para> | ||
70 | |||
71 | <note> | ||
72 | <para>Choose a unique directory for each toolchain. Installing a | ||
73 | second toolchain of any type in the same directory as a previously | ||
74 | installed one will break the <literal>$PATH</literal> variable of | ||
75 | the first one.</para> | ||
76 | </note> | ||
77 | </listitem> | ||
78 | |||
79 | <listitem> | ||
80 | <para>Setup the toolchain environment for your target by sourcing the | ||
81 | environment-setup script. Example: <programlisting>$ source sdkdir/environment-setup-aarch64-enea-linux</programlisting></para> | ||
82 | </listitem> | ||
83 | </orderedlist> | ||
84 | </section> | ||
85 | |||
86 | <section id="crosscomp-apps"> | ||
87 | <title>Cross-Compiling Applications from Command Line</title> | ||
88 | |||
89 | <para>Once the environment-setup script is sourced, you can make your | ||
90 | applications as per usual and get them compiled for your target. Below you | ||
91 | see how to cross-compile from command line.</para> | ||
92 | |||
93 | <orderedlist> | ||
94 | <listitem> | ||
95 | <para>Create a Makefile for your application. Example: a simple | ||
96 | Makefile and application:</para> | ||
97 | |||
98 | <programlisting>helloworld:helloworld.o | ||
99 | $(CC) -o helloworld helloworld.o | ||
100 | clean: | ||
101 | rm -f *.o helloworld | ||
102 | #include <stdio.h> | ||
103 | int main(void) { | ||
104 | printf("Hello World\n"); | ||
105 | return 0; | ||
106 | }</programlisting> | ||
107 | </listitem> | ||
108 | |||
109 | <listitem> | ||
110 | <para>Run <command>make</command> to cross-compile your application | ||
111 | according to the environment set up:</para> | ||
112 | |||
113 | <programlisting>$ make</programlisting> | ||
114 | </listitem> | ||
115 | |||
116 | <listitem> | ||
117 | <para>Deploy the helloworld program to your target and run it:</para> | ||
118 | |||
119 | <programlisting># ./helloworld | ||
120 | hello world</programlisting> | ||
121 | </listitem> | ||
122 | </orderedlist> | ||
123 | </section> | ||
124 | |||
125 | <section id="crosscomp-kern-mod"> | ||
126 | <title>Cross-Compiling Kernel Modules</title> | ||
127 | |||
128 | <para>Before cross-compiling kernle modules, you need to make sure the | ||
129 | installed toolchain includes the kernel source tree, which should be | ||
130 | available at: | ||
131 | <literal>sdkdir/sysroots/targetarch-enea-linux/usr/src/kernel</literal>.</para> | ||
132 | |||
133 | <para>Once the environment-setup script is sourced, you can make your | ||
134 | kernel modules as usual and get them compiled for your target. Below you | ||
135 | see how to cross-compile a kernel module.</para> | ||
136 | |||
137 | <orderedlist> | ||
138 | <listitem> | ||
139 | <para>Create a Makefile for the kernel module. Example: a simple | ||
140 | Makefile and kernel module:</para> | ||
141 | |||
142 | <programlisting>obj-m := hello.o | ||
143 | PWD := $(shell pwd) | ||
144 | |||
145 | KERNEL_SRC := full path to kernel source tree | ||
146 | |||
147 | all: scripts | ||
148 | $(MAKE) -C $(KERNEL_SRC) M=$(PWD) LDFLAGS="" modules | ||
149 | scripts: | ||
150 | $(MAKE) -C $(KERNEL_SRC) scripts | ||
151 | clean: | ||
152 | $(MAKE) -C $(KERNEL_SRC) M=$(PWD) LDFLAGS="" clean | ||
153 | #include <linux/module.h> /* Needed by all modules */ | ||
154 | #include <linux/kernel.h> /* Needed for KERN_INFO */ | ||
155 | #include <linux/init.h> /* Needed for the macros */ | ||
156 | |||
157 | static int __init hello_start(void) | ||
158 | { | ||
159 | printk(KERN_INFO "Loading hello module...\n"); | ||
160 | printk(KERN_INFO "Hello, world\n"); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static void __exit hello_end(void) | ||
165 | { | ||
166 | printk(KERN_INFO "Goodbye, world\n"); | ||
167 | } | ||
168 | |||
169 | module_init(hello_start); | ||
170 | module_exit(hello_end); | ||
171 | |||
172 | MODULE_LICENSE("GPL");</programlisting> | ||
173 | </listitem> | ||
174 | |||
175 | <listitem> | ||
176 | <para>Run <command>make</command> to cross-compile your kernel module | ||
177 | according to the environment set up:</para> | ||
178 | |||
179 | <programlisting>$ make</programlisting> | ||
180 | </listitem> | ||
181 | |||
182 | <listitem> | ||
183 | <para>Deploy the kernel module <literal>hello.ko</literal> to your | ||
184 | target and install/remove it:</para> | ||
185 | |||
186 | <programlisting># insmod hello.ko | ||
187 | # rmmod hello.ko</programlisting> | ||
188 | </listitem> | ||
189 | </orderedlist> | ||
190 | |||
191 | <para>If you build a module using the SDK for development image, and | ||
192 | insert to the release image you will get error when running | ||
193 | <literal>rmmod</literal>: <programlisting>root@cn8304:~# rmmod hello.ko <<<<<<<<< | ||
194 | rmmod: ERROR: could not remove module hello.ko: Device or resource busy</programlisting></para> | ||
195 | </section> | ||
196 | |||
197 | <section id="deploy-artifacts"> | ||
198 | <title>Deploying your artifacts</title> | ||
199 | |||
200 | <section id="deploy_onhost"> | ||
201 | <title>Deploying on host</title> | ||
202 | |||
203 | <para>You can use <literal>ssh</literal> to deploy your artifacts on the | ||
204 | host target. For this you will need a network connection to the target, | ||
205 | to use <literal>scp</literal> to copy to the desired location.</para> | ||
206 | |||
207 | <para><programlisting>$ scp helloworld root@<target_ip_address>:/tmp</programlisting></para> | ||
208 | </section> | ||
209 | |||
210 | <section id="deploy_onguest"> | ||
211 | <title>Deploying on guest</title> | ||
212 | |||
213 | <para>You can deploy your artifacts onto the guest VM running on the | ||
214 | target, by using TAP Networking. You can use the | ||
215 | <filename>/etc/qemu-ifup</filename> script to create the tap interface | ||
216 | on the host and attach it to the existing virtual bridge | ||
217 | (<literal>virbr0</literal>). This bridge interface is created by the | ||
218 | <filename>libvirt</filename> library and can be used to connect to the | ||
219 | outside network. To be able to transfer files to the guest via | ||
220 | <literal>scp</literal>, port forwarding should be enabled on the host. | ||
221 | The script sets iptables rules to forward traffic from a host port to | ||
222 | the guest default SSH port (22).</para> | ||
223 | |||
224 | <para>Follow the steps below to create this setup:</para> | ||
225 | |||
226 | <orderedlist> | ||
227 | <listitem> | ||
228 | <para>On the host, run the <literal>qemu-ifup</literal> script | ||
229 | located in <literal>/etc</literal> directory:</para> | ||
230 | |||
231 | <para><programlisting># /etc/qemu-ifup -t tap0 -a 192.168.122.10 -p 1050 -g 22</programlisting></para> | ||
232 | |||
233 | <itemizedlist> | ||
234 | <listitem> | ||
235 | <para><emphasis role="bold">tap0</emphasis> - the tap interface | ||
236 | name which will be created and added to the virtual bridge | ||
237 | (virbr0).</para> | ||
238 | </listitem> | ||
239 | |||
240 | <listitem> | ||
241 | <para><emphasis role="bold">192.168.122.10</emphasis> - the IP | ||
242 | address of the guest virtual network device. It has to be in the | ||
243 | same network with the IP address of the virbr0 interface.</para> | ||
244 | </listitem> | ||
245 | |||
246 | <listitem> | ||
247 | <para><emphasis role="bold">1050</emphasis> - the host port | ||
248 | which is set to forward traffic from the host to the | ||
249 | guest.</para> | ||
250 | </listitem> | ||
251 | |||
252 | <listitem> | ||
253 | <para><emphasis role="bold">22</emphasis> - the default SSH | ||
254 | guest port used in port forwarding.</para> | ||
255 | </listitem> | ||
256 | </itemizedlist> | ||
257 | </listitem> | ||
258 | |||
259 | <listitem> | ||
260 | <para>Launch the virtual machine specifying the newly created tap | ||
261 | interface:</para> | ||
262 | |||
263 | <para><programlisting>-device e1000,netdev=net0 \ | ||
264 | -netdev tap,id=net0,ifname=tap0,script=no,downscript=no</programlisting></para> | ||
265 | </listitem> | ||
266 | |||
267 | <listitem> | ||
268 | <para>On the guest, after logging, configure the virtual network | ||
269 | device and set the default gateway as the <literal>virbr0</literal> | ||
270 | ip address:</para> | ||
271 | |||
272 | <para><programlisting># ip addr add 192.168.122.10/24 dev enp0s2 | ||
273 | # ip link set enp0s2 up | ||
274 | # ip route add default via 192.168.122.1 dev enp0s2</programlisting></para> | ||
275 | </listitem> | ||
276 | |||
277 | <listitem> | ||
278 | <para>Now you can use <literal>scp</literal> from your development | ||
279 | machine to deploy your artifacts on the guest, by giving the host | ||
280 | port for forwarding as a command parameter: <programlisting>$ scp -P 1050 helloworld root@target_ip_address:/tmp</programlisting></para> | ||
281 | </listitem> | ||
282 | |||
283 | <listitem> | ||
284 | <para>On the host, after finishing the deployment session and | ||
285 | stopping the virtual machine, you can use the | ||
286 | <literal>qemu-ifdown</literal> script to clean up the configuration | ||
287 | on host. The following command will remove the tap interface and all | ||
288 | the iptables rules for the specific ip address: <programlisting># /etc/qemu-ifdown -t tap0 -a 192.168.122.10</programlisting>If | ||
289 | we need to remove only a particular port forwarding rule from | ||
290 | iptables, this should be run: <programlisting># /etc/qemu-ifdown -t tap0 -a 192.168.122.10 -p 1050 -g 22</programlisting></para> | ||
291 | </listitem> | ||
292 | </orderedlist> | ||
293 | </section> | ||
294 | </section> | ||
295 | |||
296 | <section id="crossdebugging"> | ||
297 | <title>Cross-Debugging on Enea NFV Access</title> | ||
298 | |||
299 | <para>The cross-debugger (<literal>aarch64-enea-linux-gdb</literal>) is | ||
300 | created when installing the SDK on the development machine. It is helpful | ||
301 | for debugging both the kernel and user-applications. In order to perform | ||
302 | this task, we need the following tools to be available on the target | ||
303 | machine:</para> | ||
304 | |||
305 | <itemizedlist> | ||
306 | <listitem> | ||
307 | <para>Kgdb - for kernel cross-debugging</para> | ||
308 | </listitem> | ||
309 | |||
310 | <listitem> | ||
311 | <para>GDBServer - for application cross-debugging</para> | ||
312 | </listitem> | ||
313 | </itemizedlist> | ||
314 | |||
315 | <para>The Host Development image provides both of these tools and has to | ||
316 | be booted on the target machine for cross-debugging sessions.</para> | ||
317 | |||
318 | <section id="ua_debug_host"> | ||
319 | <title>User-application Cross-Debugging on Host</title> | ||
320 | |||
321 | <para>To debug a user-application on host, a TCP connection has to be | ||
322 | established between the host and development machines. GDBserver is the | ||
323 | program which runs on the target machine and allows you to run GDB on | ||
324 | your workstation. Below you can find how a simple | ||
325 | <filename>helloworld</filename> application can be debugged using | ||
326 | GDBServer and cross-gdb.</para> | ||
327 | |||
328 | <para>On target, launch the GDBServer, specifying how to communicate | ||
329 | with GDB and the name of your program:<programlisting># gdbserver :<port_no> /tmp/helloworld</programlisting>The | ||
330 | target will now be listening on the port given as a parameter to the | ||
331 | gdbserver. On the development machine, from the | ||
332 | <literal><sdkdir></literal>, start the cross-gdb:<programlisting>$ aarch64-enea-linux-gdb <path_to_the_program>/helloworld</programlisting>Connect | ||
333 | the GDB to the target: <programlisting>(gdb) target remote <target_ip_address>:<port_no></programlisting>Now | ||
334 | remote debugging is started and the GDB commands are available to debug | ||
335 | your program from the target machine.</para> | ||
336 | </section> | ||
337 | |||
338 | <section id="us_debug_guest"> | ||
339 | <title>User-application Cross-Debugging on Guest</title> | ||
340 | |||
341 | <para>To debug a user-application on guest, a TCP connection has to be | ||
342 | established between the host and development machines. Similarly, as | ||
343 | when deploying artifacts on guest, for a cross-debugging session, TAP | ||
344 | Networking is required.</para> | ||
345 | |||
346 | <para>A tap interface should be added to the existing virtual bridge | ||
347 | (<literal>virbr0</literal>), along with port forwarding rules created in | ||
348 | iptables. In order to do this, the script | ||
349 | <filename>/etc/qemu-ifup</filename> can pe used:</para> | ||
350 | |||
351 | <orderedlist> | ||
352 | <listitem> | ||
353 | <para>On the host, run the script <literal>qemu-ifup</literal> | ||
354 | located in <literal>/etc</literal> directory: <programlisting># /etc/qemu-ifup -t tap0 -a 192.168.122.10 -p 1051 -g 1025</programlisting></para> | ||
355 | |||
356 | <itemizedlist> | ||
357 | <listitem> | ||
358 | <para><emphasis role="bold">tap0</emphasis> - the tap interface | ||
359 | name which will be created and added to virtual bridge | ||
360 | (virbr0).</para> | ||
361 | </listitem> | ||
362 | |||
363 | <listitem> | ||
364 | <para><emphasis role="bold">192.168.122.10</emphasis> - the IP | ||
365 | address of the guest virtual network device. It has to be in the | ||
366 | same network with the IP address of the virbr0 interface.</para> | ||
367 | </listitem> | ||
368 | |||
369 | <listitem> | ||
370 | <para><emphasis role="bold">1051</emphasis> - the host port | ||
371 | which is set to forward traffic from the host to the guest and | ||
372 | is used by gdb target remote command.</para> | ||
373 | </listitem> | ||
374 | |||
375 | <listitem> | ||
376 | <para><emphasis role="bold">1025</emphasis> - the port used by | ||
377 | GDBServer on guest for listening.</para> | ||
378 | </listitem> | ||
379 | </itemizedlist> | ||
380 | </listitem> | ||
381 | |||
382 | <listitem> | ||
383 | <para>Launch the virtual machine, specifying the newly created tap | ||
384 | interface:<programlisting>-device e1000,netdev=net0 \ | ||
385 | -netdev tap,id=net0,ifname=tap0,script=no,downscript=no</programlisting></para> | ||
386 | </listitem> | ||
387 | |||
388 | <listitem> | ||
389 | <para>On the guest, after logging, configure the virtual network | ||
390 | device and set the default gateway to virbr0 ip | ||
391 | address:<programlisting>ip addr add 192.168.122.10/24 dev enp0s2 | ||
392 | ip link set enp0s2 up | ||
393 | ip route add default via 192.168.122.1 dev enp0s2</programlisting></para> | ||
394 | </listitem> | ||
395 | |||
396 | <listitem> | ||
397 | <para>GDBserver is the program which runs on the guest VM and allows | ||
398 | you to run GDB on your workstation. On the guest, launch GBDserver | ||
399 | specifying how to communicate with GDB and the name of your program: | ||
400 | <programlisting># gdbserver :1025 /tmp/helloworld</programlisting>The | ||
401 | guest is now listening on port 1025, given as a parameter to the | ||
402 | gdbserver.</para> | ||
403 | </listitem> | ||
404 | |||
405 | <listitem> | ||
406 | <para>On the development machine, from the<filename> | ||
407 | <sdkdir></filename>, start the cross-gdb:<programlisting>$ aarch64-enea-linux-gdb <path_to_the_program>/helloworld</programlisting></para> | ||
408 | </listitem> | ||
409 | |||
410 | <listitem> | ||
411 | <para>Connect GDB to the target:<programlisting>(gdb) target remote <target_ip_address>:1051</programlisting>Now | ||
412 | remote debugging is started and the GDB commands are available to | ||
413 | debug your program from the guest VM.</para> | ||
414 | </listitem> | ||
415 | |||
416 | <listitem> | ||
417 | <para>On the host, after finishing the cross-debugging session and | ||
418 | stopping the virtual machine, you can use the | ||
419 | <filename>qemu-ifdown</filename> script to clean up the | ||
420 | configuration on host:<programlisting># /etc/qemu-ifdown -t tap0 -a 192.168.122.10</programlisting></para> | ||
421 | </listitem> | ||
422 | </orderedlist> | ||
423 | </section> | ||
424 | |||
425 | <section id="kernel_crossdebug"> | ||
426 | <title>Kernel Cross-Debugging</title> | ||
427 | |||
428 | <para>In order to debug the kernel, a serial connection is required | ||
429 | between the development and target machines. Debugging commands will be | ||
430 | sent from your workstation to the target machine via a serial | ||
431 | port.</para> | ||
432 | |||
433 | <para>The KGDB kernel options are enabled in the Enea NFV Access Host | ||
434 | SDK image and the tool can be used in the following way:</para> | ||
435 | |||
436 | <itemizedlist> | ||
437 | <listitem> | ||
438 | <para>On target, once serial communication is established, configure | ||
439 | <literal>kgdboc</literal> after the kernel boots:<programlisting># echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc</programlisting></para> | ||
440 | </listitem> | ||
441 | |||
442 | <listitem> | ||
443 | <para>In order to connect to gdb via kgdboc, the kernel must first | ||
444 | be stopped:<programlisting># echo g > /proc/sysrq-trigger</programlisting></para> | ||
445 | </listitem> | ||
446 | |||
447 | <listitem> | ||
448 | <para>Close the console to the target, eg.: <command>Ctrl + | ||
449 | ]</command> for a telnet session.</para> | ||
450 | </listitem> | ||
451 | |||
452 | <listitem> | ||
453 | <para>On your development machine, start cross-gdb using the vmlinux | ||
454 | kernel image as a parameter. The image is located in | ||
455 | <filename><sdkdir>/sysroots/aarch64-enea-linux/boot/</filename> | ||
456 | and should be the same as the image found in the | ||
457 | <literal>/boot</literal> directory from the target:<programlisting>$ aarch64-enea-linux-gdb \ | ||
458 | ./sysroots/aarch64-enea-linux/boot/ \ | ||
459 | vmlinux-4.9.0-octeontx.sdk.6.1.0.p3.build.22-cavium-tiny</programlisting></para> | ||
460 | </listitem> | ||
461 | |||
462 | <listitem> | ||
463 | <para>Connect GDB to the target machine using the target command and | ||
464 | the serial device:<programlisting>(gdb) set remotebaud 115200 | ||
465 | (gdb) target remote /dev/ttyS0</programlisting></para> | ||
466 | </listitem> | ||
467 | </itemizedlist> | ||
468 | |||
469 | <para>The kernel can now be debugged in a similar manner as an | ||
470 | application program.</para> | ||
471 | </section> | ||
472 | </section> | ||
473 | </chapter> \ No newline at end of file | ||