logo资料库

《Understanding the Linux Kernel》PDF.pdf

第1页 / 共542页
第2页 / 共542页
第3页 / 共542页
第4页 / 共542页
第5页 / 共542页
第6页 / 共542页
第7页 / 共542页
第8页 / 共542页
资料共542页,剩余部分请下载后查看
Cover
Table of Contents
Preface
The Audience for This Book
Organization of the Material
Overview of the Book
Background Information
Conventions in This Book
How to Contact Us
Acknowledgments
1. Introduction
1.1 Linux Versus Other Unix-Like Kernels
1.2 Hardware Dependency
1.3 Linux Versions
1.4 Basic Operating System Concepts
1.5 An Overview of the Unix Filesystem
1.6 An Overview of Unix Kernels
2. Memory Addressing
2.1 Memory Addresses
2.2 Segmentation in Hardware
2.3 Segmentation in Linux
2.4 Paging in Hardware
2.5 Paging in Linux
2.6 Anticipating Linux 2.4
3. Processes
3.1 Process Descriptor
3.2 Process Switching
3.3 Creating Processes
3.4 Destroying Processes
3.5 Anticipating Linux 2.4
4. Interrupts and Exceptions
4.1 The Role of Interrupt Signals
4.2 Interrupts and Exceptions
4.3 Nested Execution of Exception and Interrupt Handlers
4.4 Initializing the Interrupt Descriptor Table
4.5 Exception Handling
4.6 Interrupt Handling
4.7 Returning from Interrupts and Exceptions
4.8 Anticipating Linux 2.4
5. Timing Measurements
5.1 Hardware Clocks
5.2 The Timer Interrupt Handler
5.3 PIT's Interrupt Service Routine
5.4 The TIMER_BH Bottom Half Functions
5.5 System Calls Related to Timing Measurements
5.6 Anticipating Linux 2.4
6. Memory Management
6.1 Page Frame Management
6.2 Memory Area Management
6.3 Noncontiguous Memory Area Management
6.4 Anticipating Linux 2.4
7. Process Address Space
7.1 The Process's Address Space
7.2 The Memory Descriptor
7.3 Memory Regions
7.4 Page Fault Exception Handler
7.5 Creating and Deleting a Process Address Space
7.6 Managing the Heap
7.7 Anticipating Linux 2.4
8. System Calls
8.1 POSIX APIs and System Calls
8.2 System Call Handler and Service Routines
8.3 Wrapper Routines
8.4 Anticipating Linux 2.4
9. Signals
9.1 The Role of Signals
9.2 Sending a Signal
9.3 Receiving a Signal
9.4 Real-Time Signals
9.5 System Calls Related to Signal Handling
9.6 Anticipating Linux 2.4
10. Process Scheduling
10.1 Scheduling Policy
10.2 The Scheduling Algorithm
10.3 System Calls Related to Scheduling
10.4 Anticipating Linux 2.4
11. Kernel Synchronization
11.1 Kernel Control Paths
11.2 Synchronization Techniques
11.3 The SMP Architecture
11.4 The Linux/SMP Kernel
11.5 Anticipating Linux 2.4
12. The Virtual Filesystem
12.1 The Role of the VFS
12.2 VFS Data Structures
12.3 Filesystem Mounting
12.4 Pathname Lookup
12.5 Implementations of VFS System Calls
12.6 File Locking
12.7 Anticipating Linux 2.4
13. Managing I/O Devices
13.1 I/O Architecture
13.2 Associating Files with I/O Devices
13.3 Device Drivers
13.4 Character Device Handling
13.5 Block Device Handling
13.6 Page I/O Operations
13.7 Anticipating Linux 2.4
14. Disk Caches
14.1 The Buffer Cache
14.2 The Page Cache
14.3 Anticipating Linux 2.4
15. Accessing Regular Files
15.1 Reading and Writing a Regular File
15.2 Memory Mapping
15.3 Anticipating Linux 2.4
16. Swapping: Methods for Freeing Memory
16.1 What Is Swapping?
16.2 Swap Area
16.3 The Swap Cache
16.4 Transferring Swap Pages
16.5 Page Swap-Out
16.6 Page Swap-In
16.7 Freeing Page Frames
16.8 Anticipating Linux 2.4
17. The Ext2 Filesystem
17.1 General Characteristics
17.2 Disk Data Structures
17.3 Memory Data Structures
17.4 Creating the Filesystem
17.5 Ext2 Methods
17.6 Managing Disk Space
17.7 Reading and Writing an Ext2 Regular File
17.8 Anticipating Linux 2.4
18. Process Communication
18.1 Pipes
18.2 FIFOs
18.3 System V IPC
18.4 Anticipating Linux 2.4
19. Program Execution
19.1 Executable Files
19.2 Executable Formats
19.3 Execution Domains
19.4 The exec-like Functions
19.5 Anticipating Linux 2.4
A. System Startup
A.1 Prehistoric Age: The BIOS
A.2 Ancient Age: The Boot Loader
A.3 Middle Ages: The setup( ) Function
A.4 Renaissance: The startup_32( ) Functions
A.5 Modern Age: The start_kernel( ) Function
B. Modules
B.1 To Be (a Module) or Not to Be?
B.2 Module Implementation
B.3 Linking and Unlinking Modules
B.4 Linking Modules on Demand
C. Source Code Structure
Colophon
Understanding the Linux Kernel Daniel P. Bovet Marco Cesati Publisher: O'Reilly First Edition October 2000 ISBN: 0-596-00002-2, 702 pages Understanding the Linux Kernel helps readers understand how Linux performs best and how it meets the challenge of different environments. The authors introduce each topic by explaining its importance, and show how kernel operations relate to the utilities that are familiar to Unix programmers and users.
Table of Contents Preface .......................................................... 1 The Audience for This Book .......................................... 1 Organization of the Material .......................................... 1 Overview of the Book .............................................. 3 Background Information ............................................. 4 Conventions in This Book ........................................... 4 How to Contact Us ................................................. 4 Acknowledgments ................................................. 5 1. Introduction .................................................... 6 1.1 Linux Versus Other Unix-Like Kernels ............................... 6 1.2 Hardware Dependency .......................................... 10 1.3 Linux Versions ................................................ 11 1.4 Basic Operating System Concepts .................................. 12 1.5 An Overview of the Unix Filesystem ................................ 16 1.6 An Overview of Unix Kernels ..................................... 22 2. Memory Addressing ............................................. 2.1 Memory Addresses ............................................. 2.2 Segmentation in Hardware ....................................... 2.3 Segmentation in Linux .......................................... 2.4 Paging in Hardware ............................................ 2.5 Paging in Linux ............................................... 2.6 Anticipating Linux 2.4 .......................................... 3. Processes ...................................................... 3.1 Process Descriptor ............................................. 3.2 Process Switching ............................................. 3.3 Creating Processes ............................................. 3.4 Destroying Processes ........................................... 3.5 Anticipating Linux 2.4 .......................................... 4. Interrupts and Exceptions ......................................... 4.1 The Role of Interrupt Signals ...................................... 4.2 Interrupts and Exceptions ........................................ 4.3 Nested Execution of Exception and Interrupt Handlers .................. 4.4 Initializing the Interrupt Descriptor Table ............................ 4.5 Exception Handling ........................................... 4.6 Interrupt Handling ............................................ 4.7 Returning from Interrupts and Exceptions ........................... 4.8 Anticipating Linux 2.4 ......................................... 5. Timing Measurements ........................................... 5.1 Hardware Clocks ............................................. 5.2 The Timer Interrupt Handler ..................................... 5.3 PIT's Interrupt Service Routine ................................... 5.4 The TIMER_BH Bottom Half Functions ............................ 5.5 System Calls Related to Timing Measurements ........................ 5.6 Anticipating Linux 2.4 ......................................... 96 96 97 106 107 109 112 126 129 131 131 133 134 136 145 148 36 36 37 41 44 52 63 64 64 78 86 93 94
6. Memory Management ........................................... 6.1 Page Frame Management ....................................... 6.2 Memory Area Management ...................................... 6.3 Noncontiguous Memory Area Management .......................... 6.4 Anticipating Linux 2.4 ......................................... 7. Process Address Space .......................................... 7.1 The Process's Address Space ..................................... 7.2 The Memory Descriptor ........................................ 7.3 Memory Regions ............................................. 7.4 Page Fault Exception Handler .................................... 7.5 Creating and Deleting a Process Address Space ....................... 7.6 Managing the Heap ............................................ 7.7 Anticipating Linux 2.4 ......................................... 8. System Calls .................................................. 8.1 POSIX APIs and System Calls ................................... 8.2 System Call Handler and Service Routines ........................... 8.3 Wrapper Routines ............................................. 8.4 Anticipating Linux 2.4 ......................................... 9. Signals ....................................................... 9.1 The Role of Signals ........................................... 9.2 Sending a Signal .............................................. 9.3 Receiving a Signal ............................................ 9.4 Real-Time Signals ............................................ 9.5 System Calls Related to Signal Handling ............................ 9.6 Anticipating Linux 2.4 ......................................... 10. Process Scheduling ............................................ 10.1 Scheduling Policy ............................................ 10.2 The Scheduling Algorithm ..................................... 10.3 System Calls Related to Scheduling ............................... 10.4 Anticipating Linux 2.4 ........................................ 11. Kernel Synchronization ......................................... 11.1 Kernel Control Paths .......................................... 11.2 Synchronization Techniques .................................... 11.3 The SMP Architecture ........................................ 11.4 The Linux/SMP Kernel ........................................ 11.5 Anticipating Linux 2.4 ........................................ 12. The Virtual Filesystem ......................................... 12.1 The Role of the VFS .......................................... 12.2 VFS Data Structures .......................................... 12.3 Filesystem Mounting ......................................... 12.4 Pathname Lookup ............................................ 12.5 Implementations of VFS System Calls ............................. 12.6 File Locking ................................................ 12.7 Anticipating Linux 2.4 ........................................ 149 149 160 176 181 183 183 185 186 201 212 214 216 217 217 218 229 230 231 231 239 242 251 252 257 258 258 261 272 276 277 277 278 286 290 302 303 303 308 324 329 333 337 342
13. Managing I/O Devices .......................................... 13.1 I/O Architecture ............................................. 13.2 Associating Files with I/O Devices ............................... 13.3 Device Drivers .............................................. 13.4 Character Device Handling ..................................... 13.5 Block Device Handling ........................................ 13.6 Page I/O Operations .......................................... 13.7 Anticipating Linux 2.4 ........................................ 14. Disk Caches .................................................. 14.1 The Buffer Cache ............................................ 14.2 The Page Cache ............................................. 14.3 Anticipating Linux 2.4 ........................................ 15. Accessing Regular Files ......................................... 15.1 Reading and Writing a Regular File ............................... 15.2 Memory Mapping ............................................ 15.3 Anticipating Linux 2.4 ........................................ 16. Swapping: Methods for Freeing Memory ........................... 16.1 What Is Swapping? ........................................... 16.2 Swap Area ................................................. 16.3 The Swap Cache ............................................. 16.4 Transferring Swap Pages ....................................... 16.5 Page Swap-Out .............................................. 16.6 Page Swap-In ............................................... 16.7 Freeing Page Frames .......................................... 16.8 Anticipating Linux 2.4 ........................................ 17. The Ext2 Filesystem ........................................... 17.1 General Characteristics ........................................ 17.2 Disk Data Structures .......................................... 17.3 Memory Data Structures ....................................... 17.4 Creating the Filesystem ........................................ 17.5 Ext2 Methods ............................................... 17.6 Managing Disk Space ......................................... 17.7 Reading and Writing an Ext2 Regular File .......................... 17.8 Anticipating Linux 2.4 ........................................ 18. Process Communication ........................................ 18.1 Pipes ..................................................... 18.2 FIFOs .................................................... 18.3 System V IPC ............................................... 18.4 Anticipating Linux 2.4 ........................................ 19. Program Execution ............................................ 19.1 Executable Files ............................................. 19.2 Executable Formats .......................................... 19.3 Execution Domains ........................................... 19.4 The exec-like Functions ....................................... 19.5 Anticipating Linux 2.4 ........................................ 343 343 348 353 360 361 377 380 382 383 396 398 400 400 408 416 417 417 420 429 433 437 442 444 450 451 451 453 459 463 464 466 473 475 476 477 483 486 499 500 500 512 514 515 519
A. System Startup ................................................ A.1 Prehistoric Age: The BIOS ...................................... A.2 Ancient Age: The Boot Loader ................................... A.3 Middle Ages: The setup( ) Function ............................... A.4 Renaissance: The startup_32( ) Functions ........................... A.5 Modern Age: The start_kernel( ) Function ........................... B. Modules ..................................................... B.1 To Be (a Module) or Not to Be? .................................. B.2 Module Implementation ........................................ B.3 Linking and Unlinking Modules .................................. B.4 Linking Modules on Demand .................................... C. Source Code Structure .......................................... Colophon ...................................................... 520 520 521 523 523 524 526 526 527 529 531 533 536
Understanding the Linux Kernel Preface In the spring semester of 1997, we taught a course on operating systems based on Linux 2.0. The idea was to encourage students to read the source code. To achieve this, we assigned term projects consisting of making changes to the kernel and performing tests on the modified version. We also wrote course notes for our students about a few critical features of Linux like task switching and task scheduling. We continued along this line in the spring semester of 1998, but we moved on to the Linux 2.1 development version. Our course notes were becoming larger and larger. In July, 1998 we contacted O'Reilly & Associates, suggesting they publish a whole book on the Linux kernel. The real work started in the fall of 1998 and lasted about a year and a half. We read thousands of lines of code, trying to make sense of them. After all this work, we can say that it was worth the effort. We learned a lot of things you don't find in books, and we hope we have succeeded in conveying some of this information in the following pages. The Audience for This Book All people curious about how Linux works and why it is so efficient will find answers here. After reading the book, you will find your way through the many thousands of lines of code, distinguishing between crucial data structures and secondary ones—in short, becoming a true Linux hacker. Our work might be considered a guided tour of the Linux kernel: most of the significant data structures and many algorithms and programming tricks used in the kernel are discussed; in many cases, the relevant fragments of code are discussed line by line. Of course, you should have the Linux source code on hand and should be willing to spend some effort deciphering some of the functions that are not, for sake of brevity, fully described. On another level, the book will give valuable insights to people who want to know more about the critical design issues in a modern operating system. It is not specifically addressed to system administrators or programmers; it is mostly for people who want to understand how things really work inside the machine! Like any good guide, we try to go beyond superficial features. We offer background, such as the history of major features and the reasons they were used. Organization of the Material When starting to write this book, we were faced with a critical decision: should we refer to a specific hardware platform or skip the hardware-dependent details and concentrate on the pure hardware-independent parts of the kernel? Others books on Linux kernel internals have chosen the latter approach; we decided to adopt the former one for the following reasons: • Efficient kernels take advantage of most available hardware features, such as addressing techniques, caches, processor exceptions, special instructions, processor control registers, and so on. If we want to convince you that the kernel indeed does 1
Understanding the Linux Kernel quite a good job in performing a specific task, we must first tell what kind of support comes from the hardware. • Even if a large portion of a Unix kernel source code is processor-independent and coded in C language, a small and critical part is coded in assembly language. A thorough knowledge of the kernel thus requires the study of a few assembly language fragments that interact with the hardware. When covering hardware features, our strategy will be quite simple: just sketch the features that are totally hardware-driven while detailing those that need some software support. In fact, we are interested in kernel design rather than in computer architecture. The next step consisted of selecting the computer system to be described: although Linux is now running on several kinds of personal computers and workstations, we decided to concentrate on the very popular and cheap IBM-compatible personal computers—thus, on the Intel 80x86 microprocessors and on some support chips included in these personal computers. The term Intel 80x86 microprocessor will be used in the forthcoming chapters to denote the Intel 80386, 80486, Pentium, Pentium Pro, Pentium II, and Pentium III microprocessors or compatible models. In a few cases, explicit references will be made to specific models. One more choice was the order followed in studying Linux components. We tried to follow a bottom-up approach: start with topics that are hardware-dependent and end with those that are totally hardware-independent. In fact, we'll make many references to the Intel 80x86 microprocessors in the first part of the book, while the rest of it is relatively hardware- independent. Two significant exceptions are made in Chapter 11, and Chapter 13. In practice, following a bottom-up approach is not as simple as it looks, since the areas of memory management, process management, and filesystem are intertwined; a few forward references—that is, references to topics yet to be explained—are unavoidable. Each chapter starts with a theoretical overview of the topics covered. The material is then presented according to the bottom-up approach. We start with the data structures needed to support the functionalities described in the chapter. Then we usually move from the lowest level of functions to higher levels, often ending by showing how system calls issued by user applications are supported. Level of Description Linux source code for all supported architectures is contained in about 4500 C and Assembly files stored in about 270 subdirectories; it consists of about 2 million lines of code, which occupy more than 58 megabytes of disk space. Of course, this book can cover a very small portion of that code. Just to figure out how big the Linux source is, consider that the whole source code of the book you are reading occupies less than 2 megabytes of disk space. Therefore, in order to list all code, without commenting on it, we would need more than 25 books like this![1] [1] Nevertheless, Linux is a tiny operating system when compared with other commercial giants. Microsoft Windows 2000, for example, reportedly has more than 30 million lines of code. Linux is also small when compared to some popular applications; Netscape Communicator 5 browser, for example, has about 17 million lines of code. So we had to make some choices about the parts to be described. This is a rough assessment of our decisions: 2
分享到:
收藏