summaryrefslogtreecommitdiffstats
path: root/documentation/dev-manual/dev-manual-kernel-appendix.xml
blob: 787be3df5de0fb6ff628d2422ce29357f075ce01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<appendix id='dev-manual-kernel-appendix'>

<title>Kernel Modification Example</title>

    <para>
        Kernel modification involves changing or adding configurations to an existing kernel, or 
        adding recipes to the kernel that are needed to support specific hardware features.  
        The process is similar to creating a Board Support Package (BSP) except that it invloves
        isolating your work in a kernel layer and the use of <filename>menuconfig</filename>
        to help make configuration data easily identifiable.
    </para>

    <para>
        This section presents a simple example that shows how to modify the kernel.
        The example uses a three-step approach that is convenient for making kernel modifications.
        <orderedlist>
            <listitem><para>Iteratively determine and set kernel configurations and make 
                kernel recipe changes.</para></listitem>
            <listitem><para>Apply your configuration changes to your local kernel layer.
                </para></listitem>
            <listitem><para>Push your configuration and recipe changes upstream into the 
                Yocto Project source repositories to make them available to the community.
                </para></listitem>
        </orderedlist>
    </para>

    <section id='modifying-a-kernel-example'>
        <title>Modifying a Kernel Example</title>

        <para>
            The example changes kernel configurations to support the VFAT filesystem and 
            allow the user to print out a simple text file from the mounted VFAT filesystem.
            The filesystem used will be an image filesystem rather than a filesystem on some 
            external drive such as a USB stick or external drive.
            The example uses the <filename>linux-yocto-2.6.37</filename> kernel.
        </para>

        <para>
            For a general flow of the example, see 
            <xref linkend='kernel-modification-workflow'>Kernel Modification Workflow</xref>
            earlier in this manual.
        </para>

        <section id='setting-up-yocto-project-kernel-example'>
            <title>Setting Up Yocto Project</title>

            <para>
                You need to have the Yocto Project files available on your host system.  
                You can get files through tarball extraction or by cloning the <filename>poky</filename>
                Git repository.  
                See the bulleted item
                <link linkend='local-yp-release'>Yocto Project Release</link> in
                <xref linkend='getting-setup'>Getting Setup</xref> earlier in this manual
                for information on how to get these files.
            </para>

            <para>
                Once you have the local <filename>poky</filename> Git repository set up, 
                you have many development branches from which you can work. 
                From inside the repository you can see the branch names and the tag names used 
                in the Git repository using either of the following two commands:
                <literallayout class='monospaced'>
     $ git branch -a
     $ git tag -l
                </literallayout> 
                For this example we are going to use the Yocto Project 1.1 Release, 
                which maps to the <filename>1.1</filename> branch in the repository. 
                These commands create a local branch named <filename>1.1</filename>
                that tracks the remote branch of the same name.
                <literallayout class='monospaced'>
     $ cd poky
     $ git checkout -b 1.1 origin/1.1
     Switched to a new branch '1.1'
                </literallayout>
            </para>
        </section>

        <section id='getting-a-local-copy-of-the-kernel-files'>
            <title>Getting a Local Copy of the Kernel Files</title>

            <para>
                You need to have a local copy of the Linux Yocto kernel files on your system.
                Yocto Project files available on your host system.  
                You must create a local Git repository of these files.
                See the bulleted item
                <link linkend='local-kernel-files'>Linux Yocto Kernel</link> in  
                <xref linkend='getting-setup'>Getting Setup</xref> earlier in this manual
                for information on how to get these files.
            </para>
        </section>

        <section id='create-a-layer-for-your-kernel-work'>
            <title>Create a Layer for Your Kernel Work</title>

            <para>
                It is always good to isolate your work using your own layer.
                Doing so allows you to experiment and easily start over should things go wrong. 
                This example uses a layer named <filename>meta-vfatsupport</filename>.
            </para>

            <para>
                When you set up a layer for kernel work you should follow general layout
                guidelines layers. 
                For example, if you were creating a BSP you would want to follow the layout
                described in the
                <ulink url='http://www.yoctoproject.org/docs/1.1/bsp-guide/bsp-guide.html#bsp-filelayout'>
                Example Filesystem Layout</ulink> section of the Board Support Package (BSP) Development
                Guide.
                For kernel layers, you can start with a skeleton layer 
                named <filename>meta-skeleton</filename> found in your local 
                Yocto Project file directory structure (the <filename>poky</filename> Git 
                repository or the directory structure resulting from unpacking the Yocto Project
                release tarball).
            </para>

            <para>  
                To create your kernel layer simply copy the <filename>meta-skeleton</filename>
                layer and rename it <filename>meta-vfatsupport</filename>. 
                The following command sets up the layer inside the <filename>poky</filename>
                Git repository:
                <literallayout class='monospaced'>
     $ cd ~/poky
     $ cp -r meta-skeleton meta-vfatsupport
                </literallayout>
            </para>

            <para>
                In the new layer you will find areas for configuration changes 
                (<filename>conf</filename>) and recipe changes (<filename>recipes-skeleton</filename>).
            </para>

            <para>
                You need to modify the structure a bit for your work. 
                These commands add some further structure and names that the Yocto Project build
                environment expect:
                <literallayout class='monospaced'>
     $ mkdir meta-vfatsupport/images
     $ mkdir meta-vfatsupport/recipes-bsp
     $ mv meta-vfatsupport/recipes-skeleton meta-vfatsupport/recipes-kernel
     $ mkdir meta-vfatsupport/recipes-kernel/linux
     $ mkdir meta-vfatsupport/recipes-kernel/linux/linux-yocto
                </literallayout>
            </para>

            <para>
                The last piece you need for your layer is a 
                <filename>linux-yocto_git.bbappend</filename> file inside
                <filename>meta-vfatsupport/recipes-kernel/linux</filename>.
                This file needs the following content to make the build process aware of the 
                new layer's location:
                <literallayout class='monospaced'>
     FILESEXTRAPATHS := "${THISDIR}/${PN}"
                </literallayout>
            </para>

            <para>
                [WRITER'S NOTE:  We need a better <filename>meta-skeleton</filename> layer 
                that is part of <filename>poky</filename>.
                It should have a structure that includes <filename>images</filename>,
                <filename>recipes-bsp</filename>, <filename>recipes-kernel</filename>, and 
                so forth.
                For now this step of the example is brute-forcing the structure with shell 
                commands to set up the minimum structure and include the 
                <filename>.bbappend</filename> file.
            </para>
        </section>

        <section id='prepare-to-use-menuconfig'>
            <title>Prepare to use <filename>menuconfig</filename></title>
            
            <para>
                The <filename>menuconfig</filename> tool provides an interactive method with which
                to set kernel configurations.
                In order to use <filename>menuconfig</filename> from within the BitBake environment
                you need to source an environment setup script.
                This script is located in the local Yocto Project file structure and is called
                <filename>oe-init-build-env</filename>.
            </para>

            <para>
                The following command sets up the environment:
                <literallayout class='monospaced'>
     $ cd ~/poky
     $ source oe-init-build-env
                </literallayout>
            </para>
        </section>

        <section id='make-configuration-changes-to-the-kernel'>
            <title>Make Configuration Changes to the Kernel</title>
            
            <para>
                After setting up the environment to run <filename>menuconfig</filename> you are ready 
                to use the tool to interactively change the kernel configuration.
                In this example we are basing our changes on the <filename>linux-yocto-2.6.37</filename>
                kernel.
                The Yocto Project build environment recognizes this kernel as 
                <filename>linux-yocto</filename>.
                Thus, the following command from the shell in which you previously sourced the 
                environment initialization script launches <filename>menuconfig</filename>:
                <literallayout class='monospaced'>
     $ bitbake linux-yocto -c menuconfig
                </literallayout>
            </para>

            <para>
                [WRITER'S NOTE: Stuff from here down are crib notes]
            </para>

            <para>
                Once menuconfig fires up you see all kinds of categories that you can interactively
                investigate.
                If they have an "M" in it then the feature is "modularized".
                I guess that means that means that it needs to be manually linked in when the 
                kernel is booted??? (Not sure).
                If they have an "*" then the feature is automatically part of the kernel.]
            </para>

            <para>
                So the tmp/work/ area was created in poky and there is a .config file in there and
                a .config.old file.  
                The old one must have been created when I exited from menuconfig after poking around 
                a bit.
                Nope - appears to just be created automatically.
            </para>

            <para>
                A good practice is to first determine what configurations you have for the kernel.
                You can see the results by looking in the .config file in the build/tmp/work/qemux86-poky-linux area
                of the local YP files. 
                There is a directory named linux-yocto-2.6.37* in the directory.
                In that directory is a directory named linux-qemux86-standard-build.
                In that directory you will find a file named .config that is the configuration file
                for the kernel that will be used when you build the kernel.
                You can open that file up and examine it. 
                If you do a search for "VFAT" you will see that that particular configuration is not 
                enabled for the kernel.
                This means that you cannot print a VFAT text file, or for that matter, even mount one
                from the image if you were to build it at this point.
            </para>

            <para>
                You can prove the point by actually trying it at this point.
                Here are the commands:
                <literallayout class='monospaced'>
     $ mkdir ~/vfat-test
     $ cd ~/vfat-test
     $ dd if=/dev/zero of=vfat.img bs=1024 count=5000  [creates a 5MB disk image]
     5+0 records in
     5+0 records out
     5242880 bytes (5.2 MB) copied, 0.00798912 s, 656 MB/s
     $ ls -lah   [lists the contents of the new image. l=long, a=all, h=human readable]
     total 5.1M
     drwxr-xr-x  2 srifenbark scottrif 4.0K 2011-08-01 08:18 .
     drwxr-xr-x 66 srifenbark scottrif 4.0K 2011-08-01 08:14 ..
     -rw-r--r--  1 srifenbark scottrif 5.0M 2011-08-01 08:18 vfat.img
     $ mkfs.vfat vfat.img                      [formats the disk image]
     mkfs.vfat 3.0.7 (24 Dec 2009)
     $ mkdir mnt                               [mounts the disk image]
     $ sudo su                                 [gives you root privilege]
     # mount -o loop vfat.img mnt              [mounts it as a loop device]
     # ls mnt                                  [shows nothing in mnt]
     # mount                                   [lists the mounted filesystems - note/dev/loop0]
     /dev/sda1 on / type ext4 (rw,errors=remount-ro)
     proc on /proc type proc (rw,noexec,nosuid,nodev)
     none on /sys type sysfs (rw,noexec,nosuid,nodev)
     none on /sys/fs/fuse/connections type fusectl (rw)
     none on /sys/kernel/debug type debugfs (rw)
     none on /sys/kernel/security type securityfs (rw)
     none on /dev type devtmpfs (rw,mode=0755)
     none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
     none on /dev/shm type tmpfs (rw,nosuid,nodev)
     none on /var/run type tmpfs (rw,nosuid,mode=0755)
     none on /var/lock type tmpfs (rw,noexec,nosuid,nodev)
     none on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
     binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)
     gvfs-fuse-daemon on /home/scottrif/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=srifenbark)
     /dev/loop0 on /home/scottrif/vfat-test/mnt type vfat (rw)
     # echo "hello world" > mnt/hello.txt    [creates a text file in the mounted VFAT system]
     # ls mnt                                [verifies the file is there]
     hello.txt
     # cat mnt/hello.txt                     [displays the contents of the file created]
     hello world 
     # umount mnt                            [unmounts the system and destroys the loop]
     # exit                                  [gets out of privileged user mode]
     exit

     $ lsmod                                 [this stuff Darren did to show me ]
     Module                  Size  Used by   [the status of modules in the regular linux kernel]
     nls_iso8859_1           4633  0 
     nls_cp437               6351  0 
     vfat                   10866  0 
     fat                    55350  1 vfat
     snd_hda_codec_atihdmi     3023  1 
     binfmt_misc             7960  1 
     snd_hda_codec_realtek   279008  1 
     ppdev                   6375  0 
     snd_hda_intel          25805  2 
     fbcon                  39270  71 
     tileblit                2487  1 fbcon
     font                    8053  1 fbcon
     bitblit                 5811  1 fbcon
     snd_hda_codec          85759  3 snd_hda_codec_atihdmi,snd_hda_codec_realtek,snd_hda_intel
     softcursor              1565  1 bitblit
     snd_seq_dummy           1782  0 
     snd_hwdep               6924  1 snd_hda_codec
     vga16fb                12757  0 
     snd_pcm_oss            41394  0 
     snd_mixer_oss          16299  1 snd_pcm_oss
     snd_pcm                87946  3 snd_hda_intel,snd_hda_codec,snd_pcm_oss
     vgastate                9857  1 vga16fb
     snd_seq_oss            31191  0 
     snd_seq_midi            5829  0 
     snd_rawmidi            23420  1 snd_seq_midi
     radeon                744506  3 
     snd_seq_midi_event      7267  2 snd_seq_oss,snd_seq_midi
     ttm                    61007  1 radeon
     snd_seq                57481  6 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_seq_midi_event
     drm_kms_helper         30742  1 radeon
     snd_timer              23649  2 snd_pcm,snd_seq
     snd_seq_device          6888  5 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_rawmidi,snd_seq
     usb_storage            50377  0 
     snd                    71283  16 \
                                      snd_hda_codec_realtek,snd_hda_intel,snd_hda_codec, \
                                      snd_hwdep,snd_pcm_oss,snd_mixer_oss,snd_pcm, \
                                      snd_seq_oss,snd_rawmidi,snd_seq,snd_timer,snd_seq_device
     soundcore               8052  1 snd
     psmouse                65040  0 
     drm                   198886  5 radeon,ttm,drm_kms_helper
     i2c_algo_bit            6024  1 radeon
     serio_raw               4918  0 
     snd_page_alloc          8500  2 snd_hda_intel,snd_pcm
     dell_wmi                2177  0 
     dcdbas                  6886  0 
     lp                      9336  0 
     parport                37160  2 ppdev,lp
     usbhid                 41116  0 
     ohci1394               30260  0 
     hid                    83888  1 usbhid
     ieee1394               94771  1 ohci1394
     tg3                   122382  0
                </literallayout>
            </para>
        </section>
    </section>
</appendix>


<!--

EXTRA STUFF I MIGHT NEED BUT NOW SURE RIGHT NOW.

In the standard layer structure you have several areas that you need to examine or 
                    modify.
                    For this example the layer contains four areas:
                    <itemizedlist>
                        <listitem><para><emphasis><filename>conf</filename></emphasis> - Contains the 
                        <filename>layer.conf</filename> that identifies the location of the recipe files. 
                        </para></listitem>
                        <listitem><para><emphasis><filename>images</filename></emphasis> - Contains the 
                        image recipe file. 
                        This recipe includes the base image you will be using and specifies other 
                        packages the image might need.</para></listitem>
                        <listitem><para><emphasis><filename>recipes-bsp</filename></emphasis> - Contains 
                        recipes specific to the hardware for which you are developing the kernel.
                        </para></listitem>
                        <listitem><para><emphasis><filename>recipes-kernel</filename></emphasis> - Contains the 
                        "append" files that add information to the main recipe kernel.  
                        </para></listitem>
                    </itemizedlist>
                </para>

                <para>
                    Let's take a look at the <filename>layer.conf</filename> in the 
                    <filename>conf</filename> directory first.
                    This configuration file enables the Yocto Project build system to locate and 
                    use the information in your new layer.
                </para>

                <para>
                    The variable <filename>BBPATH</filename> needs to include the path to your layer
                    as follows:
                    <literallayout class='monospaced'>
     BBPATH := "${BBPATH}:${LAYERDIR}"
                    </literallayout>
                    And, the variable <filename>BBFILES</filename> needs to be modified to include your 
                    recipe and append files:
                    <literallayout class='monospaced'>
     BBFILES := "${BBFILES} ${LAYERDIR}/images/*.bb \ 
        ${LAYERDIR}/images/*.bbappend \
        ${LAYERDIR}/recipes-*/*/*.bb \
        ${LAYERDIR}/recipes-*/*/*.bbappend"
                    </literallayout>
                    Finally, you need to be sure to use your layer name in these variables at the 
                    end of the file:
                    <literallayout class='monospaced'>
     BBFILE_COLLECTIONS += "elc"
     BBFILE_PATTERN_elc := "^${LAYERDIR}/"
     BBFILE_PRIORITY_elc = "9"
                   </literallayout>
                </para>

                <para>
                    The <filename>images</filename> directory contains an append file that helps 
                    further define the image.
                    In our example, the base image is <filename>core-image-minimal</filename>.  
                    The image does, however, need some additional modules that we are using
                    for this example.
                    These modules support the amixer functionality.
                    Here is the append file:
                    <literallayout class='monospaced'>
     require recipes-core/images/poky-image-minimal.bb

     IMAGE_INSTALL += "dropbear alsa-utils-aplay alsa-utils-alsamixer"
     IMAGE_INSTALL_append_qemux86 += " kernel-module-snd-ens1370 \
        kernel-module-snd-rawmidi kernel-module-loop kernel-module-nls-cp437 \
        kernel-module-nls-iso8859-1 qemux86-audio alsa-utils-amixer"

     LICENSE = "MIT"
                   </literallayout>
               </para>

               <para>
                   While the focus of this example is not on the BSP, it is worth mentioning that the
                   <filename>recipes-bsp</filename> directory has the recipes and append files for 
                   features that the hardware requires. 
                   In this example, there is a script and a recipe to support the 
                   <filename>amixer</filename> functionality in QEMU.
                   It is beyond the scope of this manual to go too deeply into the script.
                   Suffice it to say that the script tests for the presence of the mixer, sets up 
                   default mixer values, enables the mixer, unmutes master and then 
                   sets the volume to 100.
               </para>

               <para>
                   The recipe <filename>qemu86-audio.bb</filename> installs and runs the 
                   <filename>amixer</filename> when the system boots.
                   Here is the recipe:
                   <literallayout class='monospaced'>
     SUMMARY = "Provide a basic init script to enable audio"
     DESCRIPTION = "Set the volume and unmute the Front mixer setting during boot."
     SECTION = "base"
     LICENSE = "MIT"
     LIC_FILES_CHKSUM = "file://${POKYBASE}/LICENSE;md5=3f40d7994397109285ec7b81fdeb3b58"

     PR = "r4"

     inherit update-rc.d

     RDEPENDS = "alsa-utils-amixer"

     SRC_URI = "file://qemux86-audio"

     INITSCRIPT_NAME = "qemux86-audio"
     INITSCRIPT_PARAMS = "defaults 90"

     do_install() {
	     install -d ${D}${sysconfdir} \
     	           ${D}${sysconfdir}/init.d
     	install -m 0755 ${WORKDIR}/qemux86-audio ${D}${sysconfdir}/init.d
             cat ${WORKDIR}/${INITSCRIPT_NAME} | \
                 sed -e 's,/etc,${sysconfdir},g' \
                     -e 's,/usr/sbin,${sbindir},g' \
                     -e 's,/var,${localstatedir},g' \
                     -e 's,/usr/bin,${bindir},g' \
                     -e 's,/usr,${prefix},g' > ${D}${sysconfdir}/init.d/${INITSCRIPT_NAME}
             chmod 755 ${D}${sysconfdir}/init.d/${INITSCRIPT_NAME}
     }
                </literallayout>
                </para>

                <para>
                    The last area to look at is <filename>recipes-kernel</filename>.
                    This area holds configuration fragments and kernel append files.
                    The append file must have the same name as the kernel recipe, which is 
                    <filename>linux-yocto-2.6.37</filename> in this example.
                    The file can <filename>SRC_URI</filename> statements to point to configuration 
                    fragments you might have in the layer. 
                    The file can also contain <filename>KERNEL_FEATURES</filename> statements that specify
                    included kernel configurations that ship with the Yocto Project.
                </para>
-->

<!--
vim: expandtab tw=80 ts=4
-->