-
Notifications
You must be signed in to change notification settings - Fork 7
/
ch06.xml
447 lines (409 loc) · 15 KB
/
ch06.xml
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
<chapter id="LKN-upgrading">
<title>
Upgrading a kernel
</title>
<para>
Inevitably it happens, you have a custom built kernel, working just
wonderfully except for one little thing that you know is fixed in the
latest release from the kernel developers. Or a security problem is found,
and a new stable kernel release is made public. Either way, you are faced
with the issue of upgrading the kernel and you do not want to lose all the
time and effort that went into making that perfect kernel configuration.
</para>
<para>
This chapter is going to show how easy it is to update a kernel from an
older versions, while still retaining all of the configuration options from
the previous one.
</para>
<para>
First off, please back up the <filename>.config</filename> file in the
kernel source directory. You have spent some time and effort into
creating it, and it should be saved in case something goes wrong when
trying to upgrade.
<screen>
$ <userinput>cd ~/linux/linux-2.6.17.11</userinput>
$ <userinput>cp .config ../good_config</userinput>
</screen>
</para>
<para>
There are only five simple steps that are needed to upgrade a kernel from a
previously built one:
<orderedlist>
<listitem>
<para>
Get the new source code.
</para>
</listitem>
<listitem>
<para>
Apply the changes to the old source tree to bring it up to the newer level.
</para>
</listitem>
<listitem>
<para>
Reconfigure the kernel based on the previous kernel configuration.
</para>
</listitem>
<listitem>
<para>
Build the new kernel.
</para>
</listitem>
<listitem>
<para>
Install the new kernel.
</para>
</listitem>
</orderedlist>
The last two steps work the same as described before, so we will only
discuss the first three steps in this chapter.
</para>
<para>
In this chapter, we are going to assume that you have built a successful
2.6.17.9 kernel release, and want to upgrade to the 2.6.17.11 release.
</para>
<sect1>
<title>Download the new source</title>
<para>
The Linux kernel developers realize that all users do not wish to download
the entire source code to the kernel for every update. That would be a
waste of bandwidth and time. Because of this, they offer a patch
<footnote>
<para>
It is called <literal>patch</literal> because the program
<command>patch</command> takes the file and applies it to the original
tree, creating the new tree. The patch file contains a representation of
the changes that are necessary to reconstruct the new files, based on the
old ones. Patch files are readable, and contain a list of the lines that
are to be removed and the lines that are to be added, with some context
within the file showing where the changes should be made.
</para>
</footnote>
that can upgrade an older kernel release, to a newer one.
</para>
<para>
On the main <literal>kernel.org</literal> website, you will remember that
it contained a list of the current kernel versions that are available for
download:
<figure id="kernel.org-screenshot-take2">
<title>The main kernel.org web site</title>
<graphic fileref="images/kernel.org.png" scalefit="1"/>
</figure>
</para>
<para>
Previously, you used the link pointed to you by the <literal>F</literal> to
download the entire source code for the kernel. However, if you click on
the name of the kernel release, it will download a patch file instead:
<figure id="kernel.org_patch-screenshot">
<title>Downloading a patch from kernel.org</title>
<graphic fileref="images/kernel.org_patch.png" scalefit="1"/>
</figure>
This is what we want to do when upgrading. But we need to figure out what
patch to download.
</para>
<sect2>
<title>Which patch applies to which release?</title>
<para>
A kernel patch file only will upgrade the source code from one specific
release to another specific release. Here is how the different patch files
can be applied:
<itemizedlist>
<listitem>
<para>
Stable kernel patches apply to the base kernel version. This means that
the 2.6.17.10 patch will only apply to the 2.6.17 kernel release. The
2.6.17.10 kernel patch will not apply to the 2.6.17.9 kernel or any other
release.
</para>
</listitem>
<listitem>
<para>
Base kernel release patches only apply to the previous base kernel version.
This means that the 2.6.18 patch will only apply to the 2.6.17 kernel
release. It will not apply to the last 2.6.17.y kernel release, or any
other release.
</para>
</listitem>
<listitem>
<para>
Incremental patches upgrade from a specific release to the next release.
This allows developers to not have to downgrade their kernel and then
upgrade it, just to switch from the latest stable release to the next
stable release (remember that the stable release patches are only against
the base kernel, not the previous stable release.) Whenever possible, it
is recommended that you use the incremental patches to make your life
easier.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Finding the patch</title>
<para>
As we want to go from the 2.6.17.9 kernel release, to the 2.6.17.11
release, we will need to download two different patches. We will need a
patch from the 2.6.17.9 release to the 2.6.17.10 release, and then from the
2.6.17.10 release to the 2.6.17.11 release.
<footnote>
<para>
If you need to upgrade more than two versions, it is recommended as a way
to save steps, to go backwards, and then upgrade forward. In this case, we
could go backward from 2.6.17.9 to 2.6.17 and then forward from 2.6.17 to
2.6.17.11.
</para>
</footnote>
</para>
<para>
The stable and base kernel patches are located in the same directory
structure as the main source trees. All incremental patches can be found
one level lower, in the <filename>incr</filename> subdirectory. So, to
find the patch that goes from 2.6.17.9 to 2.6.17.10, we look in the
<filename>/pub/linux/kernel/v2.6/incr</filename> directory to find the
files we need:
<footnote>
<para>
In this example, we use the very good <command>lftp</command> FTP program
to download the patch files. Any ftp program or a web browser can be used
to download the same files. The important thing here is to show where the
files are located.
</para>
</footnote>
<screen>
$ <userinput>cd ~/linux</userinput>
$ <userinput>lftp ftp.kernel.org/pub/linux/kernel/v2.6/incr</userinput>
cd ok, cwd=/pub/linux/kernel/v2.6/incr
lftp ftp.kernel.org:/pub/linux/kernel/v2.6/incr> <userinput>ls *2.6.17.9*.bz2</userinput>
-rw-rw-r-- 1 536 536 2872 Aug 22 19:23 patch-2.6.17.9-10.bz2
lftp ftp.kernel.org:/pub/linux/kernel/v2.6/incr> <userinput>get patch-2.6.17.9-10.bz2</userinput>
2872 bytes transferred
lftp ftp.kernel.org:/pub/linux/kernel/v2.6/incr> <userinput>get patch-2.6.17.10-11.bz2</userinput>
7901 bytes transferred
lftp ftp.kernel.org:/pub/linux/kernel/v2.6/incr> <userinput>exit</userinput>
$ <userinput>ls -F</userinput>
good_config linux-2.6.17.9/ patch-2.6.17.10-11.bz2 patch-2.6.17.9-10.bz2
</screen>
</para>
</sect2>
</sect1>
<sect1>
<title>Applying the patch</title>
<para>
As the patches we have downloaded are compressed, the first thing to do is
uncompress them with the <command>bzip2</command> command:
<screen>
$ <userinput>bzip2 -dv patch-2.6.17.9-10.bz2</userinput>
patch-2.6.17.9-10.bz2: done
$ <userinput>bzip2 -dv patch-2.6.17.10-11.bz2</userinput>
patch-2.6.17.10-11.bz2: done
$ <userinput>ls -F</userinput>
good_config linux-2.6.17.9/ patch-2.6.17.10-11 patch-2.6.17.9-10
</screen>
</para>
<para>
Now we need to apply the patch files to the kernel directory. Go into the
directory:
<screen>
$ <userinput>cd linux-2.6.17.9</userinput>
</screen>
and run the <command>patch</command> program to apply the first patch
moving the source tree from the 2.6.17.9 to the 2.6.17.10 release:
<screen>
$ <userinput>patch -p1 < ../patch-2.6.17.9-10</userinput>
patching file Makefile
patching file block/elevator.c
patching file fs/udf/super.c
patching file fs/udf/truncate.c
patching file include/net/sctp/sctp.h
patching file include/net/sctp/sm.h
patching file net/sctp/sm_make_chunk.c
patching file net/sctp/sm_statefuns.c
patching file net/sctp/socket.c
</screen>
Verify that the patch really did work properly and that there are no errors
or warnings in the output of the patch program. It is also a good idea to
look at the <filename>Makefile</filename> of the kernel to see the kernel
version:
<screen>
$ <userinput>$ head -n 5 Makefile</userinput>
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 17
EXTRAVERSION = .10
NAME=Crazed Snow-Weasel
</screen>
</para>
<para>
Now that the kernel is at the 2.6.17.10 release level, do the same thing as
before and apply the patch to bring it up to the 2.6.17.11 level:
<screen>
$ <userinput>patch -p1 < ../patch-2.6.17.10-11</userinput>
patching file Makefile
patching file arch/ia64/kernel/sys_ia64.c
patching file arch/sparc/kernel/sys_sparc.c
patching file arch/sparc64/kernel/sys_sparc.c
patching file drivers/char/tpm/tpm_tis.c
patching file drivers/ieee1394/ohci1394.c
patching file drivers/md/dm-mpath.c
patching file drivers/md/raid1.c
patching file drivers/net/sky2.c
patching file drivers/pci/quirks.c
patching file drivers/serial/Kconfig
patching file fs/befs/linuxvfs.c
patching file fs/ext3/super.c
patching file include/asm-generic/mman.h
patching file include/asm-ia64/mman.h
patching file include/asm-sparc/mman.h
patching file include/asm-sparc64/mman.h
patching file kernel/timer.c
patching file lib/spinlock_debug.c
patching file mm/mmap.c
patching file mm/swapfile.c
patching file net/bridge/netfilter/ebt_ulog.c
patching file net/core/dst.c
patching file net/core/rtnetlink.c
patching file net/ipv4/fib_semantics.c
patching file net/ipv4/netfilter/arp_tables.c
patching file net/ipv4/netfilter/ip_tables.c
patching file net/ipv4/netfilter/ipt_ULOG.c
patching file net/ipv4/route.c
patching file net/ipx/af_ipx.c
patching file net/netfilter/nfnetlink_log.c
</screen>
Again verify that the output of the patch program did not show any errors
and look at the <filename>Makefile</filename>:
<screen>
$ <userinput>head -n 5 Makefile</userinput>
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 17
EXTRAVERSION = .11
NAME=Crazed Snow-Weasel
</screen>
</para>
<para>
Now that the source code is successfully updated to the version you wish to
use, it is a good idea to go back and change the directory name to refer to
the kernel version number so that confusion does not occur at a later time:
<screen>
$ <userinput>cd ..</userinput>
$ <userinput>mv linux-2.6.17.9 linux-2.6.17.11</userinput>
$ <userinput>ls -F</userinput>
good_config linux-2.6.17.11/ patch-2.6.17.10-11 patch-2.6.17.9-10
</screen>
</para>
</sect1>
<sect1>
<title>Reconfigure the kernel</title>
<para>
Previously, we used the <literal>make menuconfig</literal> or
<literal>gconfig</literal> or <literal>xconfig</literal> method to change
different configuration options. But once you have a working
configuration, the only thing that is necessary is to update it with any
new options that have been added to the kernel since the last release. To
do this, the <literal>make oldconfig</literal> and
<literal>make silentoldconfig</literal> options should be used.
</para>
<para>
<literal>make oldconfig</literal> takes the current kernel configuration in
the <filename>.config</filename> file, and updates it based on the new
kernel release. To do this, it prints out all configuration questions, and
provides an answer for them if the option is already handled in the
configuration file. If there is a new option, the program stops and asks
the user what the new configuration value should be set to. After
answering the prompt, the program continues on until the whole kernel
configuration is finished.
</para>
<para>
<literal>make silentoldconfig</literal> works exactly the same way as
<literal>oldconfig</literal> does, but it does not print anything to the
screen, unless it needs to ask a question about a new configuration option.
</para>
<para>
Usually, when upgrading between different versions of the stable releases,
no new configuration options are added, as this is supposed to be a
<literal>stable</literal> kernel series. If this happens, there are no new
questions that need to be answered for the kernel configuration, so the
program continues successfully without any need for user intervention. An
example of this is moving from the 2.6.17.9 to 2.6.17.11 release:
<screen>
$ <userinput>cd linux-2.6.17.11</userinput>
$ <userinput>make silentoldconfig</userinput>
scripts/kconfig/conf -s arch/i386/Kconfig
#
# using defaults found in .config
#
</screen>
</para>
<para>
An example for where a new kernel option shows up in a new release is the
following. The kernel option to enable <literal>Mutex debugging</literal>
is a new one when switching between certain kernel releases. Here is the
output when this happened:
<screen>
$ make silentoldconfig
scripts/kconfig/conf -s arch/i386/Kconfig
#
# using defaults found in .config
#
*
* Restart config...
*
*
* Kernel hacking
*
Show timing information on printks (PRINTK_TIME) [Y/n/?] y
Magic SysRq key (MAGIC_SYSRQ) [Y/n/?] y
Kernel debugging (DEBUG_KERNEL) [Y/n/?] y
Kernel log buffer size (16 => 64KB, 17 => 128KB) (LOG_BUF_SHIFT) [16] 16
Detect Soft Lockups (DETECT_SOFTLOCKUP) [Y/n/?] y
Collect scheduler statistics (SCHEDSTATS) [N/y/?] n
Debug slab memory allocations (DEBUG_SLAB) [Y/n/?] y
Memory leak debugging (DEBUG_SLAB_LEAK) [Y/n] y
Mutex debugging, deadlock detection (DEBUG_MUTEXES) [N/y/?] (NEW) <userinput>y</userinput>
</screen>
The configuration program stopped at this option and asked for the user to
choose an option. Then press <literal>y</literal> and the program
continues on:
<screen>
Spinlock debugging (DEBUG_SPINLOCK) [Y/n/?] y
Sleep-inside-spinlock checking (DEBUG_SPINLOCK_SLEEP) [Y/n/?] y
kobject debugging (DEBUG_KOBJECT) [N/y/?] n
Highmem debugging (DEBUG_HIGHMEM) [N/y/?] n
Compile the kernel with debug info (DEBUG_INFO) [N/y/?] n
Debug Filesystem (DEBUG_FS) [Y/?] y
Debug VM (DEBUG_VM) [N/y/?] n
Compile the kernel with frame pointers (FRAME_POINTER) [N/y/?] n
Compile the kernel with frame unwind information (UNWIND_INFO) [N/y/?] n
Force gcc to inline functions marked 'inline' (FORCED_INLINING) [N/y/?] n
torture tests for RCU (RCU_TORTURE_TEST) [N/m/y/?] n
Check for stack overflows (DEBUG_STACKOVERFLOW) [N/y/?] n
Stack utilization instrumentation (DEBUG_STACK_USAGE) [N/y/?] n
Stack backtraces per line (STACK_BACKTRACE_COLS) [2] 2
*
* Page alloc debug is incompatible with Software Suspend on i386
*
Write protect kernel read-only data structures (DEBUG_RODATA) [N/y/?] n
Use 4Kb for kernel stacks instead of 8Kb (4KSTACKS) [N/y/?] n
</screen>
</para>
<para>
So upgrading the kernel configuration for a new release is as simple as
using a different configuration option to <command>make</command>. With
this method, you do not need to use the graphical or text oriented
configuration programs for any new kernel update.
</para>
</sect1>
<sect1>
<title>Can't this be automated?</title>
<para>
The whole process of downloading the proper patch file, uncompressing it,
and then applying it seems to be ripe for automating. Kernel developers
being the type that like to automate repetitive tasks, the program
<command>ketchup</command> has been created to handle all of this
automatically. See <xref linkend="lkn_ketchup" /> for more details on how
this program works and how to use it.
</para>
</sect1>
</chapter>
<!-- vim: set ai tw=72 : -->