File: ghosh.html

package info (click to toggle)
lg-issue70 1-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,228 kB
  • ctags: 146
  • sloc: makefile: 36; perl: 29; sh: 4
file content (606 lines) | stat: -rw-r--r-- 30,450 bytes parent folder | download
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
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
<!--startcut  ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Bootstrapping a Linux system - an Analysis LG #70</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->

<CENTER>
<A HREF="http://www.linuxgazette.com/">
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png" 
	WIDTH="600" HEIGHT="124" border="0"></A> 
<BR>

<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="chung.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc70.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue70/ghosh.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="ghosh2.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>

<!--endcut ============================================================-->

<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>

<P> <HR> <P> 
<!--===================================================================-->

<center>
<H1><font color="maroon">Bootstrapping a Linux system - an Analysis</font></H1>
<H4>By <a href="mailto:subhasish_ghosh@linuxmail.org">Subhasish Ghosh</a></H4>
</center>
<P> <HR> <P>  

<!-- END header -->




<p>Everyday millions of Linux users all over the world switch on
their computers, wait for a few seconds (or minutes depending on
their CPU speeds) to see their favorite operating system booting,
and finally get the &quot;<strong>login</strong>&quot; prompt.
That's it. It causes immense pleasure just to log into your
favorite operating system and work. Doesn't it? Well, as for me,
surely it does. (Though I need to switch on my own computer after
every two months, cause I let it run all the time!). </p>

<p>As many of the readers must have noticed, when the computer is
bootstrapping itself, a lot of messages come up on the screen.
These can be viewed later by issuing the command: cat
/var/log/dmesg | more (cause it usually produces a lot of
output). Now, the question is: Hey, what do these messages mean
in reality? That's easy to answer: Look into any Linux textbook,
and you will find it's mentioned something like this: &quot;it
refers to the Kernel Boot messages&quot; and so on. But, is that
all? And what is meant by &quot;Kernel Boot messages&quot;? </p>

<p>Life has taught me a lot of things. Patience is one of them.
And to understand the internal workings of Linux requires a lot
of patience and sacrifice cause it requires the proper
understanding of the &quot;Linux Kernel Architecture&quot;. Most
Linux users don't have either that much time to understand the
&quot;Linux Kernel Architecture&quot;, or maybe are not that much
interested in it, while some may have other important things to
do in life.</p>

<p>I am <strong>NOT</strong> going to explain the &quot;Linux
Kernel Architecture&quot; in this article cause it would require
a whole book to do so. Rather, in this article, I explain in
detail one of the most fundamental concepts of a computer-system
- <strong>Bootstrapping</strong> a computer running Linux. In
other words, I would explain (at least try to do so) the entire
process from the time one switches on the computer till the
&quot;login&quot; prompt appears on the screen (assuming he/she
is using CLI mode). In short, we would see how the Linux Kernel,
and thus the whole system, is &quot;bootstrapped&quot;. </p>

<p>Please Note: </p>

<ol>
    <li>A basic understanding of the internal workings and
        operations of the Linux Kernel is assumed on behalf of
        the readers.</li>
    <li>All the files mentioned in this article refer to Linux
        Kernel 2.4.2-2. Though the files are common for all Linux
        Kernels and can be found on any Linux system, I have used
        Red Hat Linux 7.1 Distribution Release.</li>
</ol>

<p><font size="5"><strong>1. Bootstrapping. What's that?</strong></font></p>

<p>Traditionally, the term &quot;<strong>bootstrap</strong>&quot;
refers to a person who tries to stand up (usually while lying
down cause he was tired!) by pulling his/her own boots. In
operating systems, the term refers to the process in which a part
of the operating system is brought into the Main Memory, with the
processor executing it. The internal data structures of the Linux
Kernel are also initialized, values are set to the constituent
variable(s), and processes are created (that usually spawn other
significant processes later). Computer bootstrapping is a long
and complicated task, cause when the computer is switched on, all
the hardware devices are in a unpredictable state, while the RAM
is inactive and in a random state. Thus, the thing to be kept in
mind is, the process called &quot;bootstrapping&quot; is highly
dependent on the computer architecture. </p>

<p>Please note: </p>

<ol>
    <li>Here we discuss IBM's PC architecture.</li>
    <li>A friend of mine who lives nearby kicks his CPU to
        start it.  I call this &quot;bootslapping&quot; instead of
        &quot;bootstrapping&quot;.  But the process
        described here still applies! </li>
</ol>

<p><font size="5"><strong>2. BIOS. What's that? What does it do?</strong></font>
</p>

<p>When a computer is powered on, initially, it's practically
useless. Cause the RAM chips contain random data, aren't
initialized, and there's no operating system present. To begin
the &quot;bootstrapping&quot;, a special hardware circuit raises
the logical value of the RESET pin of the CPU. Then, some CPU
registers, which include registers like <strong>cs</strong> (a
Segmentation Register - code segment register, which points to a
segment containing program instructions) and <strong>eip</strong>
( when a processor-detected exception is generated by the CPU,
that is, in other words, an exception raised by the CPU when the
CPU detects an anomalous condition while executing an
instruction, they are further of three types, namely
&quot;faults&quot;, &quot;traps&quot; and &quot;aborts&quot;,
depending on the value of the eip register that is saved on the
Kernel Mode stack when the CPU control unit raises the
exception.) are set to fixed values. Then, the code found at
physical address 0xfffffff0 is executed. This address is mapped
by the hardware to some read-only, permanent memory-chip, a
special kind of memory which is usually called <strong>ROM</strong>
(Read-Only Memory). <strong>BIOS</strong> (Basic Input/Output
System) is a set of programs that is stored in ROM. It consists
of several interrupt-driven low-level procedures used by various
operating systems to handle the hardware devices that constitute
the computer-system. Microsoft DOS is one such OS. </p>

<p>The question that now comes up is: Then, does Linux use the
BIOS to initialize the hardware devices attached to the computer
system? Or, is it anything else that performs the same task? If
yes, what's it? Well, the answer is not that simple, cause the
answer needs to be understood carefully. Starting with the 80386
model, Intel microprocessors perform address translation (from
Logical Address --&gt; Linear Address --&gt; Physical Address) in
two different ways called the &quot;<strong>Real mode</strong>&quot;
and &quot;<strong>Protected mode</strong>&quot;. Real mode exists
mainly to maintain processor compatibility with older models. In
fact, all BIOS procedures are executed in Real mode. But, the
Linux Kernel executes in the Protected mode and NOT in the Real
mode. Thus, once initialized, Linux does NOT make any use of BIOS
but provides its own device drivers for every hardware device on
the computer. </p>

<p>The question that now comes up is: When Linux uses
&quot;Protected mode&quot;, why can't BIOS use the same mode?
BIOS uses the Real mode, cause it utilizes Real mode addresses
for its operation, and Real mode addresses are the only ones
available when the computer is switched on. A Real mode address
is a seg segment and an off offset; thus the corresponding
physical address is given by seg*(2*8)+off. (Please note: Since a
Segment Descriptor is 8 bytes long, its relative address inside
the GDT or the LDT is obtained by multiplying the most
significant 13 bits of the Segment Selector by 8).</p>

<p>So, does this mean Linux never uses BIOS during the entire
process of &quot;bootstrapping&quot;? Well, the answer is <strong>No</strong>,
Linux is forced to use BIOS in the bootstrapping phase when it
has to retrieve the Kernel image from disk or some other external
device.</p>

<p>To sum up this section, let's look closely at the main
operations that the BIOS performs during the bootstrapping
sequence. They are as follows: </p>

<ol>
    <li>It carries out an exhaustive series of tests on the
        hardware. This is to check what devices are present,
        which are working properly and which aren't. This step is
        usually called POST (Power-On Self-Test). The version
        banner and a series of messages are displayed during this
        step. (Remember my friend who uses
        &quot;bootslapping&quot; instead of
        &quot;bootstrapping&quot;? Well, the POST on his system
        doesn't show any errors!!)</li>
    <li>Then, it initializes the Hardware. This step is a very
        significant one, cause it guarantees that all hardware
        devices are operating without conflicts on the IRQ lines
        and I/O ports. When this step's about to be over, it
        displays a table of installed PCI devices.</li>
    <li>Then comes the turn of the &quot;operating system&quot;.
        The BIOS searches for the operating system to boot.
        Depending on the BIOS setting, this step may want to
        access the boot sector of a floppy disk, any hard disk or
        any CD-ROM in the system.</li>
    <li>As soon as a valid device is found, the BIOS copies the contents
        of its first sector into RAM, starting from the physical
        address 0x00007c00, then jumps to that address and
        executes the code just loaded. That's all. These are the
        operations that the BIOS is scheduled to perform. Once
        this is over, it's the Boot Loader that takes over. So,
        let's now move on to the next section.</li>
</ol>

<p><font size="5"><strong>3. Boot Loader. What's that? What does
it do?</strong></font></p>

<p>The BIOS invokes (note: NOT executes) a special program whose
main (rather only) task is to load the image of an operating
system Kernel into RAM. This program is called the <strong>Boot
Loader</strong>. Before we proceed any further, let's take a
brief look in the different ways a system can be booted:</p>

<ul>
    <li>Booting Linux from a Floppy disk </li>
    <li>Booting Linux from a Hard disk </li>
</ul>

<p><font size="4"><em><strong>1. Booting Linux from a Floppy disk
:</strong></em></font> When booting from a floppy disk, the
instructions stored in the first sector of the floppy disk is
loaded in RAM and executed. These instructions then copy all the
remaining sectors containing the Kernel image into RAM. </p>

<p><font size="4"><em><strong>2. Booting Linux from a Hard disk :</strong></em></font>
When booting from the hard disk, the booting procedure is
different. The first sector of the hard disk, called the Mater
Boot Record (MBR) includes the partition table and a small
program. This program loads the first sector of the partition
containing the operating system to be started. Linux is highly
flexible and sophisticated piece of software, thus it replaces
this small program in the MBR with a sophisticated program called
LILO (LInux boot LOader). LILO allows users to select the
operating system to be booted. </p>

<p>Now, let's take a more deeper and detailed look into these 2
different ways of booting a system. </p>

<p><font size="5"><strong>4. Booting Linux from Floppy Disk.</strong></font>
</p>

<p>The Linux Kernel fits into a single 1.44-MB floppy disk. (In
fact, there exists a type of Red Hat Linux installation known as
&quot;stripped-off&quot; type, which requires approx. 2 MB
physical RAM and approx. 1.44 MB hard disk space for running a
Red Hat Linux system. That's what Linux is all about, after all.
Isn't it?) But the only way to store a Linux Kernel on a single
floppy disk is to compress the &quot;Linux Kernel Image&quot;.
The point to remember here is that, compressing is done at
compile time, while decompressing is done at boot time by the
loader.</p>

<p>When you're booting Linux from a floppy disk, the boot loader in case of
booting Linux from a floppy disk is very simple. It has been coded in the
assembly-language file
/usr/src/linux-2.4.2/arch/i386/boot/bootsect.S. When we
compile the Linux Kernel source, and obtain a new kernel image, the executable
code yielded by this assembly language file is place at the beginning of the
Kernel image file. This makes it easy to produce a floppy disk containing the
Linux Kernel.</p>

<p>Copying the kernel image starting from the first sector of the
disk can create the floppy. When the BIOS loads the first sector
of the floppy disk, it actually copies the code of the boot
loader. The boot loader, which is invoked by BIOS (by jumping to
the physical address 0x00007c00) performs the following
operations:</p>

<ol>
    <li>Moves itself from address 0x00007c00 to address
        0x00090000.</li>
    <li>Using address 0x00003ff4, sets up the &quot;Real
        Mode&quot; stack.</li>
    <li>Sets up the disk parameter table. This is used by BIOS to
        handle the floppy device driver.</li>
    <li>Displays the message &quot;Loading&quot; by invoking a
        BIOS procedure.</li>
    <li>Then, invokes a BIOS procedure to load the setup( ) code
        of the Kernel Image from the floppy disk. It puts this
        into RAM starting from address 0x00090200.</li>
    <li>Invokes a BIOS procedure finally. This procedure loads
        the rest of the Kernel image from the floppy disk and
        puts the image in RAM starting from either address
        0x00010000 (called &quot;low address&quot; for small
        Kernel Images compiled with &quot;make zImage&quot;) or
        address 0x00100000 (called &quot;high address&quot; for
        big Kernel Images compiled with &quot;make
        bzImage&quot;).</li>
    <li>Then, it finally jumps to the setup( ) code. </li>
</ol>

<p><font size="5"><strong>5. Booting Linux from Hard Disk.</strong></font></p>

<p>The Linux Kernel is mostly loaded from the hard disk. This
requires a two-stage boot loader. On Intel systems, the most
commonly used Linux boot loader is named LILO. For other
architectures, other Linux boot loaders exist. LILO may either be
installed on the MBR (Please note: During Red Hat Linux
Installation there comes a step where the user has to either
write LILO to the MBR or put it in the boot sector) or in the
boot sector of an active disk partition.</p>

<p>LILO is broken into 2 parts, otherwise it would be too large
to fit into the MBR. The MBR or the disk partition boot sector
includes a small boot loader, which is loaded into RAM starting
from address 0x00007c00 by the BIOS. This small program moves
itself to the address 0x0009a000, then sets up the Real Mode
stack, and then finally loads the second part of the LILO boot
loader. (Please note: The Real Mode stack ranges from 0x0009b000
to 0x0009a200).</p>

<p>The second part of LILO reads all the available operating
systems from disk and offers the user a prompt so that he/she can
choose any one of them from that available list. After the user
has chosen any one Kernel (on my system, one can opt for any 1
Linux Kernel out of 8 Custom Kernels!) to be loaded, the boot
loader may either copy the boot sector of the corresponding
partition into RAM and execute it or directly copy the Kernel
image into RAM.</p>

<p>Since the Linux Kernel image must be booted, the Linux boot
loader performs essentially the same operations as the boot
loader integrated into the Kernel image. The boot loader, which
is invoked by BIOS (by jumping to the physical address
0x00007c00) performs the following operations:</p>

<ol>
    <li>Moves itself from address 0x00007c00 to address
        0x00090000.</li>
    <li>Using address 0x00003ff4, sets up the &quot;Real
        Mode&quot; stack.</li>
    <li>Sets up the disk parameter table. This is used by BIOS to
        handle the hard disk device driver.</li>
    <li>Displays the message &quot;Loading Linux&quot; by
        invoking a BIOS procedure.</li>
    <li>Then, invokes a BIOS procedure to load the setup( ) code
        of the Kernel Image. It puts this into RAM starting from
        address 0x00090200.</li>
    <li>Invokes a BIOS procedure finally. This procedure loads
        the rest of the Kernel image and puts the image in RAM
        starting from either address 0x00010000 (called &quot;low
        address&quot; for small Kernel Images compiled with
        &quot;make zImage&quot;) or address 0x00100000 (called
        &quot;high address&quot; for big Kernel Images compiled
        with &quot;make bzImage&quot;).</li>
    <li>Then, it finally jumps to the setup( ) code. </li>
</ol>

<p><font size="5"><strong>6. The setup( ) function. What does it
do?</strong></font> </p>

<p>Now, time has come to take a deeper look into some of the
essential assembly language functions that are indispensable for
the &quot;bootstrapping&quot; process. Here we look at the setup(
) function.</p>

<p>The setup( ) function can be found in the file
/usr/src/linux-2.4.2/arch/i386/boot/setup.S. The code of the
setup( ) assembly language function is placed by the linker
immediately after the integrated boot loader of the Kernel, that
is, at offset 0x200 of the Kernel Image file. This allows the
boot loader to locate the code easily and copy it onto the RAM
starting from the physical address 0x00090200.</p>

<p>Now the question that comes up is: What does this setup( )
function do? As its name suggests, it's supposed to set up
something. But what? And how?</p>

<p>As we all know, for the kernel to operate properly, all the
hardware devices in the computer must be detected, and then
initialized in an orderly fashion. What the setup( ) function
does is initialize all the hardware devices and thus creates
an environment for the Kernel to operate in.</p>

<p>But, hang on a second. Didn't we see a few minutes earlier,
that the BIOS was supposed to do all this stuff? Yeah, you are
right. 100%. Although the BIOS already initialized most hardware,
the Linux Kernel does <em><strong>NOT</strong></em> rely on it
and initializes all of the hardware in its own fashion. But, if
someone asks, well, why does Linux operate in such a way? The
answer to this question is both very easy yet extremely difficult
to explain. The Linux Kernel had been so designed to enhance
portability and robustness. This is one of the many features that
makes the Linux Kernel the best out of all the Unix and Unix-like
Kernels available and makes it unique in so many ways. A proper
understanding of why and exactly how the Linux Kernel implements
this feature is beyond the scope of this topic and would require
an extremely detailed coverage of the essential features of the
Linux Kernel Architecture.</p>

<p>The setup( ) code mainly performs the following tasks:</p>

<ol>
    <li>First, total amount of physical RAM available to the
        system is detected. It invokes a BIOS procedure for
        detecting the RAM.</li>
    <li>Sets the Keyboard repeat delay and rate.</li>
    <li>The Video adapter card is detected.</li>
    <li>The Disk Controller is reinitialized and hard disk
        parameters are determined.</li>
    <li>Checks for an IBM Micro Channel bus (MCA).</li>
    <li>Checks for a PS/2 pointing device (bus mouse).</li>
    <li>Checks for Advanced Power Management (APM) BIOS support.</li>
    <li>Now checks the position of the Kernel Image loaded in
        RAM. If loaded &quot;low&quot; in RAM (when using zImage,
        at physical address 0x00010000) it is moved to
        &quot;high&quot; in RAM (at physical address 0x00001000).
        But, if the Kernel image is a &quot;bzImage&quot; loaded
        in &quot;high&quot; of RAM already, then it's NOT moved
        anywhere.</li>
    <li>Sets up the Interrupt Descriptor Table (IDT) and a Global
        Descriptor Table (GDT).</li>
    <li>If floating point unit (fpu) is present, it's now reset
        at this step.</li>
    <li>PIC (Programmable Interrupt Controller) is reprogrammed
        at this step.</li>
    <li>The CPU is switched from &quot;Real mode&quot; to
        &quot;Protected mode&quot; by setting the PE bit in the
        cr0 status register.</li>
    <li>Jumps to the stratup_32( ) assembly language function.</li>
</ol>

<p>Now from here on, the going gets a bit tougher as the
&quot;bootstrap&quot; process gets a bit more complicated. I hope
you put aside everything and carefully try to understand from
here on.</p>

<p><font size="5"><strong>7. The startup_32( ) function - 1st
function. What does it do?</strong></font></p>

<p>Okay, let's get to the confusing point straight away. There
exist <strong>two</strong> functions called <strong>startup_32()</strong>. 
Although both these two startup_32()
functions are assembly language functions and are required for
&quot;bootstrap&quot; process, they are totally different
functions. The one we refer to here is coded in
/usr/src/linux-2.4.2/arch/i386/boot/compressed/head.S file. After
setup() code is executed, the function has been moved either to
physical address 0x00100000 or to physical address 0x00001000,
depending on whether the Kernel Image was loaded &quot;high&quot;
or &quot;low&quot; in RAM.</p>

<p>This function when executes, performs the following
operations:</p>

<ol>
    <li>The segmentation registers are initialized along with a
        provisional stack.</li>
    <li>The area of uninitialized data of the Kernel is filled
        with zeroes. It is identified by symbols _edata and _end.</li>
    <li>It then executes a function decompress_kernel( ). This
        function is used to decompress the Linux Kernel image. As
        a result, the &quot;Uncompressing Linux . . .&quot;
        message is displayed on the screen. After the Linux
        Kernel image has been decompressed correctly, the
        &quot;OK, booting the kernel.&quot; message is shown. One
        very significant question here is: Okay, we understand
        the Linux Kernel image is decompressed. But, where is it
        loaded? The answer is: If the Linux Kernel image was
        loaded &quot;low&quot;, then the decompressed kernel is
        placed at physical address 0x00100000. Otherwise, if the
        Linux Kernel image was loaded &quot;high&quot;, the
        decompressed kernel is placed in a temporary buffer
        located after the compressed image. The decompressed
        kernel image is then finally moved to its final position,
        which starts at physical address 0x00100000.</li>
    <li>Finally code execution jumps to the physical address
        0x00100000.</li>
</ol>

<p>Now, after the 4th operation (as mentioned above is over),
code execution is taken over by the other startup_32( ) function.
In other words, the second one takes over the bootstrapping
process.</p>

<p><font size="5"><strong>8. The startup_32( ) function - 2nd
function. What does it do?</strong></font></p>

<p>The decompressed Linux kernel image begins with another
startup_32( ) function. This function exists in
/usr/src/linux-2.4.2/arch/i386/kernel/head.S file.</p>

<p>The question that must come up here is: Hey, using two
different functions having the same name&#133; Doesn't this cause
problem? The answer is: Well,<strong> no</strong> it doesn't at
all. Cause both functions are executed by jumping to their
initial physical addresses and hence they are executed in their
own execution environments. No problem at all!</p>

<p>Now, let's look at the second startup_32( ) function
functionality. What does it do? This function when executes, it
essentially sets up the execution environment for the first Linux
process (process 0). The function performs the following
operations:</p>

<ol>
    <li>The segmentation registers are initialized with their
        final values.</li>
    <li>Sets up the Kernel Mode stack for process 0.</li>
    <li>It then invokes and executes a function setup_idt( ) that
        fills the IDT (Interrupt Descriptor Table) with null
        interrupt handlers.</li>
    <li>The system parameters obtained from BIOS is put in the
        first page frame.</li>
    <li>The &quot;Model&quot; of the processor is identified.</li>
    <li>Loads the gdtr and idtr registers with the addresses of
        the GDT and IDT tables.</li>
    <li>It finally makes a jump to the start_kernel( ) function.</li>
</ol>

<p><font size="5"><strong>9. The start_kernel( ) function. What
does it do?</strong></font></p>

<p>The start_kernel( ) function completes the &quot;<strong>initialization</strong>&quot;
of the Linux Kernel. All the essential Kernel components are
initialized when this function executes. And this in fact is the
last step of the entire &quot;bootstrapping&quot; process.</p>

<p>The following takes place when this function executes:</p>

<ol>
    <li>The paging_init( ) function is executed that initializes
        the Page Tables.</li>
    <li>The mem_init( ) function is executed that initializes the
        Page Descriptors.</li>
    <li>The trap_init( ) and init_IRQ( ) functions are executed
        that initializes the IDT for the final time.</li>
    <li>The kmem_cache_init( ) and kmem_cache_sizes_init ( )
        functions are executed that initializes the Slab
        Allocator.</li>
    <li>The time_init( ) function is executed that initializes
        the System Date &amp; Time.</li>
    <li>The Kernel thread for process 1 is created by invoking
        the kernel_thread( ) function. This in turn creates the
        other kernel threads and executes /sbin/init program.</li>
</ol>

<p>The &quot;Linux version 2.4.2 &#133;&quot; message is
displayed right after the beginning of start_kernel( ). Many
other messages are displayed also. At the very end, the very
familiar login prompt appears on the console. This tells the user
that the Linux Kernel is up and running, and just raring to
go&#133;. And dominate the world!</p>

<p><font size="5"><strong>10. Conclusion</strong></font></p>

<p>This sums up our long and tedious journey of the entire &quot;<em><strong>bootstrapping</strong></em>&quot;
process of a Linux system, or in other words, of a computer
system running Linux operating system. As the readers would
rightly note, I have NOT explained most of the other components
and terms that I have had used. A few include IDT, GDT, eip
register, cs register and so on. The full explanation of all
these terms would make it impossible to complete the article in
just a few pages, and would make the entire topic rather very
boring. So, I really hope the readers would understand the fact
that in this article I provide everyone with a glimpse of the
processes and other various things that take place when a Linux
system boots. In depth coverage of all the associated functions
like paging_init( ) and mem_init( ) is beyond the scope of this
topic.</p>


<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P> 
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Subhasish Ghosh</H4>
<EM>I am
20 years old, currently a computer-systems engineering student in
India. I am a Microsoft Certified Professional (MCP), MSCD, MCP
certified on NT 4.0, recently completed Red Hat Linux Certified
Engineer (RHCE) Training. I have been working with Linux for a
long time, have had programmed using C, C++, VC++, VB, COM, DCOM,
MFC, ATL 3.0, Perl, Python and Linux programming using GTK+.
Currently busy learning the Linux Kernel Architecture in detail
and doing Linux Kernel Programming.</EM>

<!-- *** END bio *** -->

<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P --> 
<H5 ALIGN=center>

Copyright &copy; 2001, Subhasish Ghosh.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR> 
Published in Issue 70 of <i>Linux Gazette</i>, September 2001</H5>
<!-- *** END copyright *** -->

<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="chung.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc70.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue70/ghosh.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="ghosh2.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->