diff options
author | Richard Purdie <richard@openedhand.com> | 2008-02-26 11:31:34 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2008-02-26 11:31:34 +0000 |
commit | 882e9cd2affb773eec8b1d387ab4e3b5cbdc0994 (patch) | |
tree | f023b2ce9abf3b894a81986e0a00e23d77b55e66 /handbook/development.xml | |
parent | 7197110f46511492a48cd359b3ddf75b60ea47c8 (diff) | |
download | poky-882e9cd2affb773eec8b1d387ab4e3b5cbdc0994.tar.gz |
Add Poky handbook
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3865 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'handbook/development.xml')
-rw-r--r-- | handbook/development.xml | 815 |
1 files changed, 815 insertions, 0 deletions
diff --git a/handbook/development.xml b/handbook/development.xml new file mode 100644 index 0000000000..c56c69ca79 --- /dev/null +++ b/handbook/development.xml | |||
@@ -0,0 +1,815 @@ | |||
1 | <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" | ||
2 | "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> | ||
3 | |||
4 | <chapter id="platdev"> | ||
5 | <title>Platform Development with Poky</title> | ||
6 | |||
7 | <section id="platdev-appdev"> | ||
8 | <title>Software development</title> | ||
9 | <para> | ||
10 | Poky supports several methods of software development. These different | ||
11 | forms of development are explained below and can be switched | ||
12 | between as needed. | ||
13 | </para> | ||
14 | |||
15 | <section id="platdev-appdev-external-sdk"> | ||
16 | <title>Developing externally using the Poky SDK</title> | ||
17 | |||
18 | <para> | ||
19 | The meta-toolchain and meta-toolchain-sdk targets (<link linkend='ref-images'>see | ||
20 | the images section</link>) build tarballs which contain toolchains and | ||
21 | libraries suitable for application development outside Poky. These unpack into the | ||
22 | <filename class="directory">/usr/local/poky</filename> directory and contain | ||
23 | a setup script, e.g. | ||
24 | <filename>/usr/local/poky/eabi-glibc/arm/environment-setup</filename> which | ||
25 | can be sourced to initialise a suitable environment. After sourcing this, the | ||
26 | compiler, QEMU scripts, QEMU binary, a special version of pkgconfig and other | ||
27 | useful utilities are added to the PATH. Variables to assist pkgconfig and | ||
28 | autotools are also set so that, for example, configure can find pre-generated test | ||
29 | results for tests which need target hardware to run. | ||
30 | </para> | ||
31 | |||
32 | <para> | ||
33 | Using the toolchain with autotool enabled packages is straightforward, just pass the | ||
34 | appropriate host option to configure e.g. "./configure --host=arm-poky-linux-gnueabi". | ||
35 | For other projects it is usually a case of ensuring the cross tools are used e.g. | ||
36 | CC=arm-poky-linux-gnueabi-gcc and LD=arm-poky-linux-gnueabi-ld. | ||
37 | </para> | ||
38 | </section> | ||
39 | |||
40 | <section id="platdev-appdev-qemu"> | ||
41 | <title>Developing externally in QEMU</title> | ||
42 | <para> | ||
43 | Running Poky QEMU images is covered in the <link | ||
44 | linkend='intro-quickstart-qemu'>Running an Image</link> section. | ||
45 | </para> | ||
46 | <para> | ||
47 | Poky's QEMU images contain a complete native toolchain. This means | ||
48 | that applications can be developed within QEMU in the same was as a | ||
49 | normal system. Using qemux86 on an x86 machine is fast since the | ||
50 | guest and host architectures match, qemuarm is slower but gives | ||
51 | faithful emulation of ARM specific issues. To speed things up these | ||
52 | images support using distcc to call a cross-compiler outside the | ||
53 | emulated system too. If <command>runqemu</command> was used to start | ||
54 | QEMU, and distccd is present on the host system, any bitbake cross | ||
55 | compiling toolchain available from the build system will automatically | ||
56 | be used from within qemu simply by calling distcc | ||
57 | (<command>export CC="distcc"</command> can be set in the enviroment). | ||
58 | Alterntatively, if a suitable SDK/toolchain is present in | ||
59 | <filename class="directory">/usr/local/poky</filename> it will also | ||
60 | automatically be used. | ||
61 | </para> | ||
62 | |||
63 | <para> | ||
64 | There are several options for connecting into the emulated system. | ||
65 | QEMU provides a framebuffer interface which has standard consoles | ||
66 | available. There is also a serial connection available which has a | ||
67 | console to the system running on it and IP networking as standard. | ||
68 | The images have a dropbear ssh server running with the root password | ||
69 | disabled allowing standard ssh and scp commands to work. The images | ||
70 | also contain an NFS server exporting the guest's root filesystem | ||
71 | allowing that to be made available to the host. | ||
72 | </para> | ||
73 | </section> | ||
74 | |||
75 | <section id="platdev-appdev-chroot"> | ||
76 | <title>Developing externally in a chroot</title> | ||
77 | <para> | ||
78 | If you have a system that matches the architecture of the Poky machine you're using, | ||
79 | such as qemux86, you can run binaries directly from the image on the host system | ||
80 | using a chroot combined with tools like <ulink url='http://projects.o-hand.com/xephyr'>Xephyr</ulink>. | ||
81 | </para> | ||
82 | <para> | ||
83 | Poky has some scripts to make using its qemux86 images within a chroot easier. To use | ||
84 | these you need to install the poky-scripts package or otherwise obtain the | ||
85 | <filename>poky-chroot-setup</filename> and <filename>poky-chroot-run</filename> scripts. | ||
86 | You also need Xephyr and chrootuid binaries available. To initialize a system use the setup script: | ||
87 | </para> | ||
88 | <para> | ||
89 | <literallayout class='monospaced'> | ||
90 | # poky-chroot-setup <qemux86-rootfs.tgz> <target-directory> | ||
91 | </literallayout> | ||
92 | </para> | ||
93 | <para> | ||
94 | which will unpack the specified qemux86 rootfs tarball into the target-directory. | ||
95 | You can then start the system with: | ||
96 | </para> | ||
97 | <para> | ||
98 | <literallayout class='monospaced'> | ||
99 | # poky-chroot-run <target-directory> <command> | ||
100 | </literallayout> | ||
101 | </para> | ||
102 | <para> | ||
103 | where the target-directory is the place the rootfs was unpacked to and command is | ||
104 | an optional command to run. If no command is specified, the system will drop you | ||
105 | within a bash shell. A Xephyr window will be displayed containing the emulated | ||
106 | system and you may be asked for a password since some of the commands used for | ||
107 | bind mounting directories need to be run using sudo. | ||
108 | </para> | ||
109 | <para> | ||
110 | There are limits as to how far the the realism of the chroot environment extends. | ||
111 | It is useful for simple development work or quick tests but full system emulation | ||
112 | with QEMU offers a much more realistic environment for more complex development | ||
113 | tasks. Note that chroot support within Poky is still experimental. | ||
114 | </para> | ||
115 | </section> | ||
116 | |||
117 | <section id="platdev-appdev-insitu"> | ||
118 | <title>Developing in Poky directly</title> | ||
119 | <para> | ||
120 | Working directly in Poky is a fast and effective development technique. | ||
121 | The idea is that you can directly edit files in | ||
122 | <glossterm><link linkend='var-WORKDIR'>WORKDIR</link></glossterm> | ||
123 | or the source directory <glossterm><link linkend='var-S'>S</link></glossterm> | ||
124 | and then force specific tasks to rerun in order to test the changes. | ||
125 | An example session working on the matchbox-desktop package might | ||
126 | look like this: | ||
127 | </para> | ||
128 | |||
129 | <para> | ||
130 | <literallayout class='monospaced'> | ||
131 | $ bitbake matchbox-desktop | ||
132 | $ sh | ||
133 | $ cd tmp/work/armv5te-poky-linux-gnueabi/matchbox-desktop-2.0+svnr1708-r0/ | ||
134 | $ cd matchbox-desktop-2 | ||
135 | $ vi src/main.c | ||
136 | $ exit | ||
137 | $ bitbake matchbox-desktop -c compile -f | ||
138 | $ bitbake matchbox-desktop | ||
139 | </literallayout> | ||
140 | </para> | ||
141 | |||
142 | <para> | ||
143 | Here, we build the package, change into the work directory for the package, | ||
144 | change a file, then recompile the package. Instead of using sh like this, | ||
145 | you can also use two different terminals. The risk with working like this | ||
146 | is that a command like unpack could wipe out the changes you've made to the | ||
147 | work directory so you need to work carefully. | ||
148 | </para> | ||
149 | |||
150 | <para> | ||
151 | It is useful when making changes directly to the work directory files to do | ||
152 | so using quilt as detailed in the <link linkend='usingpoky-modifying-packages-quilt'> | ||
153 | modifying packages with quilt</link> section. The resulting patches can be copied | ||
154 | into the recipe directory and used directly in the <glossterm><link | ||
155 | linkend='var-SRC_URI'>SRC_URI</link></glossterm>. | ||
156 | </para> | ||
157 | <para> | ||
158 | For a review of the skills used in this section see Sections <link | ||
159 | linkend="usingpoky-components-bitbake">2.1.1</link> and <link | ||
160 | linkend="usingpoky-debugging-taskrunning">2.4.2</link>. | ||
161 | </para> | ||
162 | |||
163 | </section> | ||
164 | |||
165 | <section id="platdev-appdev-devshell"> | ||
166 | <title>Developing with 'devshell'</title> | ||
167 | |||
168 | <para> | ||
169 | When debugging certain commands or even to just edit packages, the | ||
170 | 'devshell' can be a useful tool. To start it you run a command like: | ||
171 | </para> | ||
172 | |||
173 | <para> | ||
174 | <literallayout class='monospaced'> | ||
175 | $ bitbake matchbox-desktop -c devshell | ||
176 | </literallayout> | ||
177 | </para> | ||
178 | |||
179 | <para> | ||
180 | which will open a terminal with a shell prompt within the Poky | ||
181 | environment. This means PATH is setup to include the cross toolchain, | ||
182 | the pkgconfig variables are setup to find the right .pc files, | ||
183 | configure will be able to find the Poky site files etc. Within this | ||
184 | environment, you can run configure or compile command as if they | ||
185 | were being run by Poky itself. You are also changed into the | ||
186 | source (<glossterm><link linkend='var-S'>S</link></glossterm>) | ||
187 | directory automatically. When finished with the shell just exit it | ||
188 | or close the terminal window. | ||
189 | </para> | ||
190 | |||
191 | <para> | ||
192 | The default shell used by devshell is the gnome-terminal. Other | ||
193 | forms of terminal can also be used by setting the <glossterm> | ||
194 | <link linkend='var-TERMCMD'>TERMCMD</link></glossterm> and <glossterm> | ||
195 | <link linkend='var-TERMCMDRUN'>TERMCMDRUN</link></glossterm> variables | ||
196 | in local.conf. For examples of the other options available, see | ||
197 | <filename>meta/conf/bitbake.conf</filename>. An external shell is | ||
198 | launched rather than opening directly into the original terminal | ||
199 | window to make interaction with bitbakes multiple threads easier | ||
200 | and also allow a client/server split of bitbake in the future | ||
201 | (devshell will still work over X11 forwarding or similar). | ||
202 | </para> | ||
203 | |||
204 | <para> | ||
205 | It is worth remembering that inside devshell you need to use the full | ||
206 | compiler name such as <command>arm-poky-linux-gnueabi-gcc</command> | ||
207 | instead of just <command>gcc</command> and the same applies to other | ||
208 | applications from gcc, bintuils, libtool etc. Poky will have setup | ||
209 | environmental variables such as CC to assist applications, such as make, | ||
210 | find the correct tools. | ||
211 | </para> | ||
212 | |||
213 | </section> | ||
214 | |||
215 | <section id="platdev-appdev-srcrev"> | ||
216 | <title>Developing within Poky with an external SCM based package</title> | ||
217 | |||
218 | <para> | ||
219 | If you're working on a recipe which pulls from an external SCM it | ||
220 | is possible to have Poky notice new changes added to the | ||
221 | SCM and then build the latest version. This only works for SCMs | ||
222 | where its possible to get a sensible revision number for changes. | ||
223 | Currently it works for svn, git and bzr repositories. | ||
224 | </para> | ||
225 | |||
226 | <para> | ||
227 | To enable this behaviour it is simply a case of adding <glossterm> | ||
228 | <link linkend='var-SRCREV'>SRCREV</link></glossterm>_pn-<glossterm> | ||
229 | <link linkend='var-PN'>PN</link></glossterm> = "${AUTOREV}" to | ||
230 | local.conf where <glossterm><link linkend='var-PN'>PN</link></glossterm> | ||
231 | is the name of the package for which you want to enable automatic source | ||
232 | revision updating. | ||
233 | </para> | ||
234 | </section> | ||
235 | |||
236 | <section id="platdev-appdev-external-anjuta"> | ||
237 | <title>Developing externally using the Anjuta plugin</title> | ||
238 | |||
239 | <para> | ||
240 | An Anjuta IDE plugin exists to make developing software within the Poky framework | ||
241 | easier for the application developer. It presents a graphical IDE from which the | ||
242 | developer can cross compile an application then deploy and execute the output in a QEMU | ||
243 | emulation session. It also supports cross debugging and profiling. | ||
244 | </para> | ||
245 | |||
246 | <para> | ||
247 | To use the plugin, a toolchain and SDK built by Poky is required along with Anjuta and the Anjuta | ||
248 | plugin. The Poky Anjuta plugin is available from the OpenedHand SVN repository located at | ||
249 | http://svn.o-hand.com/repos/anjuta-poky/trunk/anjuta-plugin-sdk/; a web interface | ||
250 | to the repository can be accessed at <ulink url='http://svn.o-hand.com/view/anjuta-poky/'/>. | ||
251 | See the README file contained in the project for more information | ||
252 | about the dependencies and how to get them along with details of | ||
253 | the prebuilt packages. | ||
254 | </para> | ||
255 | |||
256 | <section id="platdev-appdev-external-anjuta-setup"> | ||
257 | <title>Setting up the Anjuta plugin</title> | ||
258 | |||
259 | <para>Extract the tarball for the toolchain into / as root. The | ||
260 | toolchain will be installed into | ||
261 | <filename class="directory">/usr/local/poky</filename>.</para> | ||
262 | |||
263 | <para>To use the plugin, first open or create an existing | ||
264 | project. If creating a new project the "C GTK+" project type | ||
265 | will allow itself to be cross-compiled. However you should be | ||
266 | aware that this uses glade for the UI.</para> | ||
267 | |||
268 | <para>To activate the plugin go | ||
269 | <menuchoice><guimenu>Edit</guimenu><guimenuitem>Preferences</guimenuitem></menuchoice>, | ||
270 | then choose <guilabel>General</guilabel> from the left hand side. Choose the | ||
271 | Installed plugins tab, scroll down to <guilabel>Poky | ||
272 | SDK</guilabel> and check the | ||
273 | box. The plugin is now activated but first it must be | ||
274 | configured.</para> </section> | ||
275 | |||
276 | <section id="platdev-appdev-external-anjuta-configuration"> | ||
277 | <title>Configuring the Anjuta plugin</title> | ||
278 | |||
279 | <para>The configuration options for the SDK can be found by choosing | ||
280 | the <guilabel>Poky SDK</guilabel> icon from the left hand side. The following options | ||
281 | need to be set:</para> | ||
282 | |||
283 | <itemizedlist> | ||
284 | |||
285 | <listitem><para><guilabel>SDK root</guilabel>: this is the root directory of the SDK | ||
286 | for an ARM EABI SDK this will be <filename | ||
287 | class="directory">/usr/local/poky/eabi-glibc/arm</filename>. | ||
288 | This directory will contain directories named like "bin", | ||
289 | "include", "var", etc. With the file chooser it is important | ||
290 | to enter into the "arm" subdirectory for this | ||
291 | example.</para></listitem> | ||
292 | |||
293 | <listitem><para><guilabel>Toolchain triplet</guilabel>: this is the cross compile | ||
294 | triplet, e.g. "arm-poky-linux-gnueabi".</para></listitem> | ||
295 | |||
296 | <listitem><para><guilabel>Kernel</guilabel>: use the file chooser to select the kernel | ||
297 | to use with QEMU</para></listitem> | ||
298 | |||
299 | <listitem><para><guilabel>Root filesystem</guilabel>: use the file chooser to select | ||
300 | the root filesystem image, this should be an image (not a | ||
301 | tarball)</para></listitem> | ||
302 | </itemizedlist> | ||
303 | |||
304 | </section> | ||
305 | |||
306 | <section id="platdev-appdev-external-anjuta-usage"> | ||
307 | <title>Using the Anjuta plugin</title> | ||
308 | |||
309 | <para>As an example, cross-compiling a project, deploying it into | ||
310 | QEMU and running a debugger against it and then doing a system | ||
311 | wide profile.</para> | ||
312 | |||
313 | <para>Choose <menuchoice><guimenu>Build</guimenu><guimenuitem>Run | ||
314 | Configure</guimenuitem></menuchoice> or | ||
315 | <menuchoice><guimenu>Build</guimenu><guimenuitem>Run | ||
316 | Autogenerate</guimenuitem></menuchoice> to run "configure" | ||
317 | (or to run "autogen") for the project. This passes command line | ||
318 | arguments to instruct it to cross-compile.</para> | ||
319 | |||
320 | <para>Next do | ||
321 | <menuchoice><guimenu>Build</guimenu><guimenuitem>Build | ||
322 | Project</guimenuitem></menuchoice> to build and compile the | ||
323 | project. If you have previously built the project in the same | ||
324 | tree without using the cross-compiler you may find that your | ||
325 | project fails to link. Simply do | ||
326 | <menuchoice><guimenu>Build</guimenu><guimenuitem>Clean | ||
327 | Project</guimenuitem></menuchoice> to remove the old | ||
328 | binaries. You may then try building again.</para> | ||
329 | |||
330 | <para>Next start QEMU by using | ||
331 | <menuchoice><guimenu>Tools</guimenu><guimenuitem>Start | ||
332 | QEMU</guimenuitem></menuchoice>, this will start QEMU and | ||
333 | will show any error messages in the message view. Once Poky has | ||
334 | fully booted within QEMU you may now deploy into it.</para> | ||
335 | |||
336 | <para>Once built and QEMU is running, choose | ||
337 | <menuchoice><guimenu>Tools</guimenu><guimenuitem>Deploy</guimenuitem></menuchoice>, | ||
338 | this will install the package into a temporary directory and | ||
339 | then copy using rsync over SSH into the target. Progress and | ||
340 | messages will be shown in the message view.</para> | ||
341 | |||
342 | <para>To debug a program installed into onto the target choose | ||
343 | <menuchoice><guimenu>Tools</guimenu><guimenuitem>Debug | ||
344 | remote</guimenuitem></menuchoice>. This prompts for the | ||
345 | local binary to debug and also the command line to run on the | ||
346 | target. The command line to run should include the full path to | ||
347 | the to binary installed in the target. This will start a | ||
348 | gdbserver over SSH on the target and also an instance of a | ||
349 | cross-gdb in a local terminal. This will be preloaded to connect | ||
350 | to the server and use the <guilabel>SDK root</guilabel> to find | ||
351 | symbols. This gdb will connect to the target and load in | ||
352 | various libraries and the target program. You should setup any | ||
353 | breakpoints or watchpoints now since you might not be able to | ||
354 | interrupt the execution later. You may stop | ||
355 | the debugger on the target using | ||
356 | <menuchoice><guimenu>Tools</guimenu><guimenuitem>Stop | ||
357 | debugger</guimenuitem></menuchoice>.</para> | ||
358 | |||
359 | <para>It is also possible to execute a command in the target over | ||
360 | SSH, the appropriate environment will be be set for the | ||
361 | execution. Choose | ||
362 | <menuchoice><guimenu>Tools</guimenu><guimenuitem>Run | ||
363 | remote</guimenuitem></menuchoice> to do this. This will open | ||
364 | a terminal with the SSH command inside.</para> | ||
365 | |||
366 | <para>To do a system wide profile against the system running in | ||
367 | QEMU choose | ||
368 | <menuchoice><guimenu>Tools</guimenu><guimenuitem>Profile | ||
369 | remote</guimenuitem></menuchoice>. This will start up | ||
370 | OProfileUI with the appropriate parameters to connect to the | ||
371 | server running inside QEMU and will also supply the path to the | ||
372 | debug information necessary to get a useful profile.</para> | ||
373 | |||
374 | </section> | ||
375 | </section> | ||
376 | </section> | ||
377 | |||
378 | <section id="platdev-gdb-remotedebug"> | ||
379 | <title>Debugging with GDB Remotely</title> | ||
380 | |||
381 | <para> | ||
382 | <ulink url="http://sourceware.org/gdb/">GDB</ulink> (The GNU Project Debugger) | ||
383 | allows you to examine running programs to understand and fix problems and | ||
384 | also to perform postmortem style analsys of program crashes. It is available | ||
385 | as a package within poky and installed by default in sdk images. It works best | ||
386 | when -dbg packages for the application being debugged are installed as the | ||
387 | extra symbols give more meaningful output from GDB. | ||
388 | </para> | ||
389 | |||
390 | <para> | ||
391 | Sometimes, due to memory or disk space constraints, it is not possible | ||
392 | to use GDB directly on the remote target to debug applications. This is | ||
393 | due to the fact that | ||
394 | GDB needs to load the debugging information and the binaries of the | ||
395 | process being debugged. GDB then needs to perform many | ||
396 | computations to locate information such as function names, variable | ||
397 | names and values, stack traces, etc. even before starting the debugging | ||
398 | process. This places load on the target system and can alter the | ||
399 | characteristics of the program being debugged. | ||
400 | </para> | ||
401 | <para> | ||
402 | This is where GDBSERVER comes into play as it runs on the remote target | ||
403 | and does not load any debugging information from the debugged process. | ||
404 | Instead, the debugging information processing is done by a GDB instance | ||
405 | running on a distant computer - the host GDB. The host GDB then sends | ||
406 | control commands to GDBSERVER to make it stop or start the debugged | ||
407 | program, as well as read or write some memory regions of that debugged | ||
408 | program. All the debugging information loading and processing as well | ||
409 | as the heavy debugging duty is done by the host GDB, giving the | ||
410 | GDBSERVER running on the target a chance to remain small and fast. | ||
411 | </para> | ||
412 | <para> | ||
413 | As the host GDB is responsible for loading the debugging information and | ||
414 | doing the necessary processing to make actual debugging happen, the | ||
415 | user has to make sure it can access the unstripped binaries complete | ||
416 | with their debugging information and compiled with no optimisations. The | ||
417 | host GDB must also have local access to all the libraries used by the | ||
418 | debugged program. On the remote target the binaries can remain stripped | ||
419 | as GDBSERVER does not need any debugging information there. However they | ||
420 | must also be compiled without optimisation matching the host's binaries. | ||
421 | </para> | ||
422 | |||
423 | <para> | ||
424 | The binary being debugged on the remote target machine is hence referred | ||
425 | to as the 'inferior' in keeping with GDB documentation and terminology. | ||
426 | Further documentation on GDB, is available on | ||
427 | <ulink url="http://sourceware.org/gdb/documentation/">on their site</ulink>. | ||
428 | </para> | ||
429 | |||
430 | <section id="platdev-gdb-remotedebug-launch-gdbserver"> | ||
431 | <title>Launching GDBSERVER on the target</title> | ||
432 | <para> | ||
433 | First, make sure gdbserver is installed on the target. If not, | ||
434 | install the gdbserver package (which needs the libthread-db1 | ||
435 | package). | ||
436 | </para> | ||
437 | <para> | ||
438 | To launch GDBSERVER on the target and make it ready to "debug" a | ||
439 | program located at <emphasis>/path/to/inferior</emphasis>, connect | ||
440 | to the target and launch: | ||
441 | <programlisting>$ gdbserver localhost:2345 /path/to/inferior</programlisting> | ||
442 | After that, gdbserver should be listening on port 2345 for debugging | ||
443 | commands coming from a remote GDB process running on the host computer. | ||
444 | Communication between the GDBSERVER and the host GDB will be done using | ||
445 | TCP. To use other communication protocols please refer to the | ||
446 | GDBSERVER documentation. | ||
447 | </para> | ||
448 | </section> | ||
449 | |||
450 | <section id="platdev-gdb-remotedebug-launch-gdb"> | ||
451 | <title>Launching GDB on the host computer</title> | ||
452 | |||
453 | <para> | ||
454 | Running GDB on the host computer takes a number of stages, described in the | ||
455 | following sections. | ||
456 | </para> | ||
457 | |||
458 | <section id="platdev-gdb-remotedebug-launch-gdb-buildcross"> | ||
459 | <title>Build the cross GDB package</title> | ||
460 | <para> | ||
461 | A suitable gdb cross binary is required which runs on your host computer but | ||
462 | knows about the the ABI of the remote target. This can be obtained from | ||
463 | the the Poky toolchain, e.g. | ||
464 | <filename>/usr/local/poky/eabi-glibc/arm/bin/arm-poky-linux-gnueabi-gdb</filename> | ||
465 | which "arm" is the target architecture and "linux-gnueabi" the target ABI. | ||
466 | </para> | ||
467 | |||
468 | <para> | ||
469 | Alternatively this can be built directly by Poky. To do this you would build | ||
470 | the gdb-cross package so for example you would run: | ||
471 | <programlisting>bitbake gdb-cross</programlisting> | ||
472 | Once built, the cross gdb binary can be found at | ||
473 | <programlisting>tmp/cross/bin/<target-abi>-gdb </programlisting> | ||
474 | </para> | ||
475 | |||
476 | </section> | ||
477 | <section id="platdev-gdb-remotedebug-launch-gdb-inferiorbins"> | ||
478 | |||
479 | <title>Making the inferior binaries available</title> | ||
480 | |||
481 | <para> | ||
482 | The inferior binary needs to be available to GDB complete with all debugging | ||
483 | symbols in order to get the best possible results along with any libraries | ||
484 | the inferior depends on and their debugging symbols. There are a number of | ||
485 | ways this can be done. | ||
486 | </para> | ||
487 | |||
488 | <para> | ||
489 | Perhaps the easiest is to have an 'sdk' image corresponding to the plain | ||
490 | image installed on the device. In the case of 'pky-image-sato', | ||
491 | 'poky-image-sdk' would contain suitable symbols. The sdk images already | ||
492 | have the debugging symbols installed so its just a question expanding the | ||
493 | archive to some location and telling GDB where this is. | ||
494 | </para> | ||
495 | |||
496 | <para> | ||
497 | Alternatively, poky can build a custom directory of files for a specific | ||
498 | debugging purpose by reusing its tmp/rootfs directory, on the host computer | ||
499 | in a slightly different way to normal. This directory contains the contents | ||
500 | of the last built image. This process assumes the image running on the | ||
501 | target was the last image to be built by Poky, the package <emphasis>foo</emphasis> | ||
502 | contains the inferior binary to be debugged has been built without without | ||
503 | optimisation and has debugging information available. | ||
504 | </para> | ||
505 | <para> | ||
506 | Firstly you want to install the <emphasis>foo</emphasis> package to tmp/rootfs | ||
507 | by doing: | ||
508 | </para> | ||
509 | <programlisting>tmp/staging/i686-linux/usr/bin/ipkg-cl -f \ | ||
510 | tmp/work/<target-abi>/poky-image-sato-1.0-r0/temp/ipkg.conf -o \ | ||
511 | tmp/rootfs/ update</programlisting> | ||
512 | <para> | ||
513 | then, | ||
514 | </para> | ||
515 | <programlisting>tmp/staging/i686-linux/usr/bin/ipkg-cl -f \ | ||
516 | tmp/work/<target-abi>/poky-image-sato-1.0-r0/temp/ipkg.conf \ | ||
517 | -o tmp/rootfs install foo | ||
518 | |||
519 | tmp/staging/i686-linux/usr/bin/ipkg-cl -f \ | ||
520 | tmp/work/<target-abi>/poky-image-sato-1.0-r0/temp/ipkg.conf \ | ||
521 | -o tmp/rootfs install foo-dbg</programlisting> | ||
522 | <para> | ||
523 | which installs the debugging information too. | ||
524 | </para> | ||
525 | |||
526 | </section> | ||
527 | <section id="platdev-gdb-remotedebug-launch-gdb-launchhost"> | ||
528 | |||
529 | <title>Launch the host GDB</title> | ||
530 | <para> | ||
531 | To launch the host GDB, run the cross gdb binary identified above with | ||
532 | the inferior binary specified on the commandline: | ||
533 | <programlisting><target-abi>-gdb rootfs/usr/bin/foo</programlisting> | ||
534 | This loads the binary of program <emphasis>foo</emphasis> | ||
535 | as well as its debugging information. Once the gdb prompt | ||
536 | appears, you must instruct GDB to load all the libraries | ||
537 | of the inferior from tmp/rootfs: | ||
538 | <programlisting>set solib-absolute-prefix /path/to/tmp/rootfs</programlisting> | ||
539 | where <filename>/path/to/tmp/rootfs</filename> must be | ||
540 | the absolute path to <filename>tmp/rootfs</filename> or wherever the | ||
541 | binaries with debugging information are located. | ||
542 | </para> | ||
543 | <para> | ||
544 | Now, tell GDB to connect to the GDBSERVER running on the remote target: | ||
545 | <programlisting>target remote remote-target-ip-address:2345</programlisting> | ||
546 | Where remote-target-ip-address is the IP address of the | ||
547 | remote target where the GDBSERVER is running. 2345 is the | ||
548 | port on which the GDBSERVER is running. | ||
549 | </para> | ||
550 | |||
551 | </section> | ||
552 | <section id="platdev-gdb-remotedebug-launch-gdb-using"> | ||
553 | |||
554 | <title>Using the Debugger</title> | ||
555 | <para> | ||
556 | Debugging can now proceed as normal, as if the debugging were being done on the | ||
557 | local machine, for example to tell GDB to break in the <emphasis>main</emphasis> | ||
558 | function, for instance: | ||
559 | <programlisting>break main</programlisting> | ||
560 | and then to tell GDB to "continue" the inferior execution, | ||
561 | <programlisting>continue</programlisting> | ||
562 | </para> | ||
563 | <para> | ||
564 | For more information about using GDB please see the | ||
565 | project's online documentation at <ulink | ||
566 | url="http://sourceware.org/gdb/download/onlinedocs/"/>. | ||
567 | </para> | ||
568 | </section> | ||
569 | </section> | ||
570 | |||
571 | </section> | ||
572 | |||
573 | <section id="platdev-oprofile"> | ||
574 | <title>Profiling with OProfile</title> | ||
575 | |||
576 | <para> | ||
577 | <ulink url="http://oprofile.sourceforge.net/">OProfile</ulink> is a | ||
578 | statistical profiler well suited to finding performance | ||
579 | bottlenecks in both userspace software and the kernel. It provides | ||
580 | answers to questions like "Which functions does my application spend | ||
581 | the most time in when doing X?". Poky is well integrated with OProfile | ||
582 | to make profiling applications on target hardware straightforward. | ||
583 | </para> | ||
584 | |||
585 | <para> | ||
586 | To use OProfile you need an image with OProfile installed. The easiest | ||
587 | way to do this is with "tools-profile" in <glossterm><link | ||
588 | linkend='var-IMAGE_FEATURES'>IMAGE_FEATURES</link></glossterm>. You also | ||
589 | need debugging symbols to be available on the system where the analysis | ||
590 | will take place. This can be achieved with "dbg-pkgs" in <glossterm><link | ||
591 | linkend='var-IMAGE_FEATURES'>IMAGE_FEATURES</link></glossterm> or by | ||
592 | installing the appropriate -dbg packages. For | ||
593 | successful call graph analysis the binaries must preserve the frame | ||
594 | pointer register and hence should be compiled with the | ||
595 | "-fno-omit-framepointer" flag. In Poky this can be achieved with | ||
596 | <glossterm><link linkend='var-SELECTED_OPTIMIZATION'>SELECTED_OPTIMIZATION | ||
597 | </link></glossterm> = "-fexpensive-optimizations -fno-omit-framepointer | ||
598 | -frename-registers -O2" or by setting <glossterm><link | ||
599 | linkend='var-DEBUG_BUILD'>DEBUG_BUILD</link></glossterm> = "1" in | ||
600 | local.conf (the latter will also add extra debug information making the | ||
601 | debug packages large). | ||
602 | </para> | ||
603 | |||
604 | <section id="platdev-oprofile-target"> | ||
605 | <title>Profiling on the target</title> | ||
606 | |||
607 | <para> | ||
608 | All the profiling work can be performed on the target device. A | ||
609 | simple OProfile session might look like: | ||
610 | </para> | ||
611 | |||
612 | <para> | ||
613 | <literallayout class='monospaced'> | ||
614 | # opcontrol --reset | ||
615 | # opcontrol --start --separate=lib --no-vmlinux -c 5 | ||
616 | [do whatever is being profiled] | ||
617 | # opcontrol --stop | ||
618 | $ opreport -cl | ||
619 | </literallayout> | ||
620 | </para> | ||
621 | |||
622 | <para> | ||
623 | Here, the reset command clears any previously profiled data, | ||
624 | OProfile is then started. The options used to start OProfile mean | ||
625 | dynamic library data is kept separately per application, kernel | ||
626 | profiling is disabled and callgraphing is enabled up to 5 levels | ||
627 | deep. To profile the kernel, you would specify the | ||
628 | <parameter>--vmlinux=/path/to/vmlinux</parameter> option (the vmlinux file is usually in | ||
629 | <filename class="directory">/boot/</filename> in Poky and must match the running kernel). The profile is | ||
630 | then stopped and the results viewed with opreport with options | ||
631 | to see the separate library symbols and callgraph information. | ||
632 | </para> | ||
633 | <para> | ||
634 | Callgraphing means OProfile not only logs infomation about which | ||
635 | functions time is being spent in but also which functions | ||
636 | called those functions (their parents) and which functions that | ||
637 | function calls (its children). The higher the callgraphing depth, | ||
638 | the more accurate the results but this also increased the loging | ||
639 | overhead so it should be used with caution. On ARM, binaries need | ||
640 | to have the frame pointer enabled for callgraphing to work (compile | ||
641 | with the gcc option -fno-omit-framepointer). | ||
642 | </para> | ||
643 | <para> | ||
644 | For more information on using OProfile please see the OProfile | ||
645 | online documentation at <ulink | ||
646 | url="http://oprofile.sourceforge.net/docs/"/>. | ||
647 | </para> | ||
648 | </section> | ||
649 | |||
650 | <section id="platdev-oprofile-oprofileui"> | ||
651 | <title>Using OProfileUI</title> | ||
652 | |||
653 | <para> | ||
654 | A graphical user interface for OProfile is also available. You can | ||
655 | either use prebuilt Debian packages from the <ulink | ||
656 | url='http://debian.o-hand.com/'>OpenedHand repository</ulink> or | ||
657 | download and build from svn at | ||
658 | http://svn.o-hand.com/repos/oprofileui/trunk/. If the | ||
659 | "tools-profile" image feature is selected, all necessary binaries | ||
660 | are installed onto the target device for OProfileUI interaction. | ||
661 | </para> | ||
662 | |||
663 | <para> | ||
664 | In order to convert the data in the sample format from the target | ||
665 | to the host the <filename>opimport</filename> program is needed. | ||
666 | This is not included in standard Debian OProfile packages but an | ||
667 | OProfile package with this addition is also available from the <ulink | ||
668 | url='http://debian.o-hand.com/'>OpenedHand repository</ulink>. | ||
669 | We recommend using OProfile 0.9.3 or greater. Other patches to | ||
670 | OProfile may be needed for recent OProfileUI features, but Poky | ||
671 | usually includes all needed patches on the target device. Please | ||
672 | see the <ulink | ||
673 | url='http://svn.o-hand.com/repos/oprofileui/trunk/README'> | ||
674 | OProfileUI README</ulink> for up to date information, and the | ||
675 | <ulink url="http://labs.o-hand.com/oprofileui">OProfileUI website | ||
676 | </ulink> for more information on the OProfileUI project. | ||
677 | </para> | ||
678 | |||
679 | <section id="platdev-oprofile-oprofileui-online"> | ||
680 | <title>Online mode</title> | ||
681 | |||
682 | <para> | ||
683 | This assumes a working network connection with the target | ||
684 | hardware. In this case you just need to run <command> | ||
685 | "oprofile-server"</command> on the device. By default it listens | ||
686 | on port 4224. This can be changed with the <parameter>--port</parameter> command line | ||
687 | option. | ||
688 | |||
689 | </para> | ||
690 | |||
691 | <para> | ||
692 | The client program is called <command>oprofile-viewer</command>. The | ||
693 | UI is relatively straightforward, the key functionality is accessed | ||
694 | through the buttons on the toolbar (which are duplicated in the | ||
695 | menus.) These buttons are: | ||
696 | </para> | ||
697 | |||
698 | <itemizedlist> | ||
699 | <listitem> | ||
700 | <para> | ||
701 | Connect - connect to the remote host, the IP address or hostname for the | ||
702 | target can be supplied here. | ||
703 | </para> | ||
704 | </listitem> | ||
705 | <listitem> | ||
706 | <para> | ||
707 | Disconnect - disconnect from the target. | ||
708 | </para> | ||
709 | </listitem> | ||
710 | <listitem> | ||
711 | <para> | ||
712 | Start - start the profiling on the device. | ||
713 | </para> | ||
714 | </listitem> | ||
715 | <listitem> | ||
716 | <para> | ||
717 | Stop - stop the profiling on the device and download the data to the local | ||
718 | host. This will generate the profile and show it in the viewer. | ||
719 | </para> | ||
720 | </listitem> | ||
721 | <listitem> | ||
722 | <para> | ||
723 | Download - download the data from the target, generate the profile and show it | ||
724 | in the viewer. | ||
725 | </para> | ||
726 | </listitem> | ||
727 | <listitem> | ||
728 | <para> | ||
729 | Reset - reset the sample data on the device. This will remove the sample | ||
730 | information that was collected on a previous sampling run. Ensure you do this | ||
731 | if you do not want to include old sample information. | ||
732 | </para> | ||
733 | </listitem> | ||
734 | <listitem> | ||
735 | <para> | ||
736 | Save - save the data downloaded from the target to another directory for later | ||
737 | examination. | ||
738 | </para> | ||
739 | </listitem> | ||
740 | <listitem> | ||
741 | <para> | ||
742 | Open - load data that was previously saved. | ||
743 | </para> | ||
744 | </listitem> | ||
745 | </itemizedlist> | ||
746 | |||
747 | <para> | ||
748 | The behaviour of the client is to download the complete 'profile archive' from | ||
749 | the target to the host for processing. This archive is a directory containing | ||
750 | the sample data, the object files and the debug information for said object | ||
751 | files. This archive is then converted using a script included in this | ||
752 | distribution ('oparchconv') that uses 'opimport' to convert the archive from | ||
753 | the target to something that can be processed on the host. | ||
754 | </para> | ||
755 | |||
756 | <para> | ||
757 | Downloaded archives are kept in /tmp and cleared up when they are no longer in | ||
758 | use. | ||
759 | </para> | ||
760 | |||
761 | <para> | ||
762 | If you wish to profile into the kernel, this is possible, you just need to ensure | ||
763 | a vmlinux file matching the running kernel is available. In Poky this is usually | ||
764 | located in /boot/vmlinux-KERNELVERSION, where KERNEL-version is the version of | ||
765 | the kernel e.g. 2.6.23. Poky generates separate vmlinux packages for each kernel | ||
766 | it builds so it should be a question of just ensuring a matching package is | ||
767 | installed (<command> ipkg install kernel-vmlinux</command>. These are automatically | ||
768 | installed into development and profiling images alongside OProfile. There is a | ||
769 | configuration option within the OProfileUI settings page where the location of | ||
770 | the vmlinux file can be entered. | ||
771 | </para> | ||
772 | |||
773 | <para> | ||
774 | Waiting for debug symbols to transfer from the device can be slow and it's not | ||
775 | always necessary to actually have them on device for OProfile use. All that is | ||
776 | needed is a copy of the filesystem with the debug symbols present on the viewer | ||
777 | system. The <link linkend='platdev-gdb-remotedebug-launch-gdb'>GDB remote debug | ||
778 | section</link> covers how to create such a directory with Poky and the location | ||
779 | of this directory can again be specified in the OProfileUI settings dialog. If | ||
780 | specified, it will be used where the file checksums match those on the system | ||
781 | being profiled. | ||
782 | </para> | ||
783 | </section> | ||
784 | <section id="platdev-oprofile-oprofileui-offline"> | ||
785 | <title>Offline mode</title> | ||
786 | |||
787 | <para> | ||
788 | If no network access to the target is available an archive for processing in | ||
789 | 'oprofile-viewer' can be generated with the following set of command. | ||
790 | </para> | ||
791 | |||
792 | <para> | ||
793 | <literallayout class='monospaced'> | ||
794 | # opcontrol --reset | ||
795 | # opcontrol --start --separate=lib --no-vmlinux -c 5 | ||
796 | [do whatever is being profiled] | ||
797 | # opcontrol --stop | ||
798 | # oparchive -o my_archive | ||
799 | </literallayout> | ||
800 | </para> | ||
801 | |||
802 | <para> | ||
803 | Where my_archive is the name of the archive directory where you would like the | ||
804 | profile archive to be kept. The directory will be created for you. This can | ||
805 | then be copied to another host and loaded using 'oprofile-viewer''s open | ||
806 | functionality. The archive will be converted if necessary. | ||
807 | </para> | ||
808 | </section> | ||
809 | </section> | ||
810 | </section> | ||
811 | |||
812 | </chapter> | ||
813 | <!-- | ||
814 | vim: expandtab tw=80 ts=4 | ||
815 | --> | ||