You are previewing Linux® Kernel Primer, The: A Top-Down Approach for x86 and PowerPC Architectures.
O'Reilly logo
Linux® Kernel Primer, The: A Top-Down Approach for x86 and PowerPC Architectures

Book Description

Learn Linux kernel programming, hands-on: a uniquely effective top-down approach

The Linux® Kernel Primer is the definitive guide to Linux kernel programming. The authors' unique top-down approach makes kernel programming easier to understand by systematically tracing functionality from user space into the kernel and carefully associating kernel internals with user-level programming fundamentals. Their approach helps you build on what you already know about Linux, gaining a deep understanding of how the kernel works and how its elements fit together.

One step at a time, the authors introduce all the tools and assembly language programming techniques required to understand kernel code and control its behavior. They compare x86 and PowerPC implementations side-by-side, illuminating cryptic functionality through carefully-annotated source code examples and realistic projects. The Linux® Kernel Primer is the first book to offer in-depth coverage of the rapidly growing PowerPC Linux development platform, and the only book to thoroughly discuss kernel configuration with the Linux build system. Coverage includes

  • Data structures

  • x86 and PPC assembly language

  • Viewing kernel internals

  • Linux process model

  • User and kernel space

  • Interrupts and exceptions

  • Memory allocation and tracking

  • Tracing subsystem behavior

  • I/O interactions

  • Filesystems and file operations

  • Scheduling and synchronization

  • Kernel boot process

  • Kernel build system

  • Configuration options

  • Device drivers

  • And more...

If you know C, this book teaches you all the skills and techniques you need to succeed with Linux kernel programming. Whether you're a systems programmer, software engineer, systems analyst, test professional, open source project contributor, or simply a Linux enthusiast, you'll find it indispensable.

© Copyright Pearson Education. All rights reserved.

Table of Contents

  1. Copyright
    1. Dedication
  2. Prentice Hall: Open Source Software Development Series
  3. Foreword
  4. Acknowledgments
  5. About the Authors
  6. Preface
    1. Intended Audience
    2. Organization of Material
    3. Our Approach
    4. Conventions
  7. 1. Overview
    1. 1.1. History of UNIX
    2. 1.2. Standards and Common Interfaces
    3. 1.3. Free Software and Open Source
    4. 1.4. A Quick Survey of Linux Distributions
      1. 1.4.1. Debian
      2. 1.4.2. Red Hat/Fedora
      3. 1.4.3. Mandriva
      4. 1.4.4. SUSE
      5. 1.4.5. Gentoo
      6. 1.4.6. Yellow Dog
      7. 1.4.7. Other Distros
    5. 1.5. Kernel Release Information
    6. 1.6. Linux on Power
    7. 1.7. What Is an Operating System?
    8. 1.8. Kernel Organization
    9. 1.9. Overview of the Linux Kernel
      1. 1.9.1. User Interface
      2. 1.9.2. User Identification
      3. 1.9.3. Files and Filesystems
        1. 1.9.3.1. Directories, Files, and Pathnames
        2. 1.9.3.2. Filesystem Mounting
        3. 1.9.3.3. File Protection and Access Rights
        4. 1.9.3.4. File Modes
          1. sticky
          2. suid
          3. sgid
        5. 1.9.3.5. File Metadata
        6. 1.9.3.6. Types of Files
          1. Regular File
          2. Directory
          3. Block Devices
          4. Character Devices
          5. Link
          6. Named Pipes
          7. Sockets
        7. 1.9.3.7. Types of Filesystems
        8. 1.9.3.8. File Control
      4. 1.9.4. Processes
        1. 1.9.4.1. Process Creation and Control
        2. 1.9.4.2. Process IDs
        3. 1.9.4.3. Process Groups
        4. 1.9.4.4. Process States
        5. 1.9.4.5. Process Descriptor
        6. 1.9.4.6. Process Priority
      5. 1.9.5. System Calls
      6. 1.9.6. Linux Scheduler
      7. 1.9.7. Linux Device Drivers
    10. 1.10. Portability and Architecture Dependence
    11. Summary
    12. Exercises
  8. 2. Exploration Toolkit
    1. 2.1. Common Kernel Datatypes
      1. 2.1.1. Linked Lists
        1. Line 34
        2. Line 37
        3. Line 492
        4. Line 493
      2. 2.1.2. Searching
      3. 2.1.3. Trees
        1. 2.1.3.1. Binary Trees
        2. 2.1.3.2. Red Black Trees
    2. 2.2. Assembly
      1. 2.2.1. PowerPC
        1. 2.2.1.1. Branch Instructions
        2. 2.2.1.2. Fixed-Point Instructions
        3. 2.2.1.3. Floating-Point Instructions
      2. 2.2.2. x86
        1. 2.2.2.1. Control Instructions
          1. Line 100
          2. Line 101
          3. Line 102
          4. Line 103
          5. Line 104
        2. 2.2.2.2. Arithmetic Instructions
        3. 2.2.2.3. Data Instructions
          1. Line 100
          2. Line 101
          3. Line 102
          4. Line 103
          5. Line 104
    3. 2.3. Assembly Language Example
      1. Line 1
      2. Line 3
      3. Line 5
      4. Line 8
      5. 2.3.1. x86 Assembly Example
        1. Line 9
        2. Line 10
        3. Line 11
        4. Line 12
        5. Line 13
        6. Line 14
        7. Line 15
        8. Line 16
        9. Line 17
        10. Line 18
        11. Line 19
        12. Line 20
        13. Line 21
        14. Line 22
        15. Line 23
        16. Line 24
        17. Line 25
        18. Line 26
        19. Line 27
        20. Line 28
        21. Line 29
        22. Line 30
        23. Line 31
      6. 2.3.2. PowerPC Assembly Example
        1. Line 7
        2. Line 8
        3. Line 9
        4. Line 10
        5. Line 11
        6. Line 12
        7. Line 13
        8. Line 14
        9. Line 15
        10. Line 16
        11. Line 17
        12. Line 18
        13. Line 19
        14. Line 20
        15. Line 21
        16. Line 22
        17. Line 23
        18. Line 24
        19. Line 25
        20. Line 26
        21. Line 27
        22. Line 28
        23. Line 29
        24. Line 30
        25. Line 31
        26. Line 32
        27. Line 33
        28. Line 34
    4. 2.4. Inline Assembly
      1. 2.4.1. Ouput Operands
      2. 2.4.2. Input Operands
      3. 2.4.3. Clobbered Registers (or Clobber List)
      4. 2.4.4. Parameter Numbering
      5. 2.4.5. Constraints
      6. 2.4.6. asm
      7. 2.4.7. __volatile__
        1. Line 6
        2. Line 8
        3. Line 9
        4. Line 10
        5. Line 11
        6. Line 12
        7. Line 13
        8. Line 14
        9. Line 15
        10. Line 16
        11. Line 12
        12. Line 15
        13. Line 16
        14. Line 17
        15. Line 23
        16. Lines 17–24
        17. Line 26
        18. Line 27
        19. Line 28
        20. Line 29
        21. Line 103
        22. Line 104
        23. Line 106
        24. Line 108
        25. Lines 109–111
        26. Line 112
        27. Line 113
        28. Line 114
        29. Line 115
    5. 2.5. Quirky C Language Usage
      1. 2.5.1. asmlinkage
      2. 2.5.2. UL
      3. 2.5.3. inline
      4. 2.5.4. const and volatile
    6. 2.6. A Quick Tour of Kernel Exploration Tools
      1. 2.6.1. objdump/readelf
      2. 2.6.2. hexdump
      3. 2.6.3. nm
      4. 2.6.4. objcopy
      5. 2.6.5. ar
    7. 2.7. Kernel Speak: Listening to Kernel Messages
      1. 2.7.1. printk()
      2. 2.7.2. dmesg
      3. 2.7.3. /var/log/messages
    8. 2.8. Miscellaneous Quirks
      1. 2.8.1. __init
      2. 2.8.2. likely() and unlikely()
      3. 2.8.3. IS_ERR and PTR_ERR
      4. 2.8.4. Notifier Chains
    9. Summary
    10. Project: Hellomod
      1. Step 1: Writing the Linux Module Skeleton
        1. Line 4
        2. Line 5
        3. Line 6
        4. Line 7
        5. Lines 9–12
        6. Lines 15–18
        7. Line 20
        8. Line 21
      2. Step 2: Compiling the Module
        1. Line 1
      3. Step 3: Running the Code
    11. Exercises
  9. 3. Processes: The Principal Model of Execution
    1. 3.1. Introducing Our Program
    2. 3.2. Process Descriptor
      1. 3.2.1. Process Attribute–Related Fields
        1. 3.2.1.1. state
        2. 3.2.1.2. pid
        3. 3.2.1.3. flags
        4. 3.2.1.4. binfmt
        5. 3.2.1.5. exit_code and exit_signal
        6. 3.2.1.6. pdeath_signal
        7. 3.2.1.7. comm
        8. 3.2.1.8. ptrace
      2. 3.2.2. Scheduling Related Fields
        1. 3.2.2.1. prio
        2. 3.2.2.2. static_prio
        3. 3.2.2.3. run_list
        4. 3.2.2.4. array
        5. 3.2.2.5. sleep_avg
        6. 3.2.2.6. timestamp
        7. 3.2.2.7. interactive_credit
        8. 3.2.2.8. policy
        9. 3.2.2.9. cpus_allowed
        10. 3.2.2.10. time_slice
        11. 3.2.2.11. first_time_slice
        12. 3.2.2.12. activated
        13. 3.2.2.13. rt_priority
        14. 3.2.2.14. nivcsw and nvcsw
      3. 3.2.3. Process Relations–Related Fields
        1. 3.2.3.1. real_parent
        2. 3.2.3.2. parent
        3. 3.2.3.3. children
        4. 3.2.3.4. sibling
        5. 3.2.3.5. group_leader
      4. 3.2.4. Process Credentials–Related Fields
        1. 3.2.4.1. uid and gid
        2. 3.2.4.2. euid and egid
        3. 3.2.4.3. suid and sgid
        4. 3.2.4.4. fsuid and fsgid
        5. 3.2.4.5. group_info
      5. 3.2.5. Process Capabilities–Related Fields
        1. 3.2.5.1. cap_effective, cap_inheritable, cap_permitted, and keep_capabilities
      6. 3.2.6. Process Limitations–Related Fields
        1. 3.2.6.1. rlim
      7. 3.2.7. Filesystem- and Address Space–Related Fields
        1. 3.2.7.1. fs
        2. 3.2.7.2. files
        3. 3.2.7.3. mm
        4. 3.2.7.4. active_mm
    3. 3.3. Process Creation: fork(), vfork(), and clone() System Calls
      1. 3.3.1. fork() Function
      2. 3.3.2. vfork() Function
      3. 3.3.3. clone() Function
      4. 3.3.4. do_fork() Function
        1. Lines 1178–1183
        2. Line 1184
        3. Line 1189
        4. Lines 1194–1197
        5. Lines 1199–1205
        6. Lines 1226–1229
        7. Lines 1231–1234
        8. Lines 1236–1239
        9. Line 1248
    4. 3.4. Process Lifespan
      1. 3.4.1. Process States
      2. 3.4.2. Process State Transitions
        1. 3.4.2.1. Ready to Running
          1. TASK_RUNNING to TASK_RUNNING
        2. 3.4.2.2. Running to Ready
          1. TASK_RUNNING to TASK_RUNNING
        3. 3.4.2.3. Running to Blocked
          1. TASK_RUNNING to TASK_INTERRUPTIBLE
          2. TASK_RUNNING to TASK_UNINTERRUPTIBLE
          3. TASK_RUNNING to TASK_ZOMBIE
          4. TASK_RUNNING to TASK_STOPPED
          5. TASK_UNINTERRUPTIBLE or TASK_INTERRUPTIBLE to TASK_STOPPED
        4. 3.4.2.4. Blocked to Ready
    5. 3.5. Process Termination
      1. 3.5.1. sys_exit() Function
      2. 3.5.2. do_exit() Function
        1. Line 707
        2. Lines 711–716
        3. Line 719
        4. Lines 729–732
        5. Lines 735–742
        6. Lines 744–745
        7. Lines 747–749
        8. Line 751
        9. Line 752
        10. Line 754
        11. Line 757
      3. 3.5.3. Parent Notification and sys_wait4()
        1. Line 1031
        2. Lines 1033 and 1040
        3. Line 1037–1038
        4. Line 1042
        5. Line 1043
        6. Lines 1046 and 1094
        7. Line 1051
        8. Line 1054
        9. Line 1058–1079
        10. Line 1106
        11. Line 1107–1111
    6. 3.6. Keeping Track of Processes: Basic Scheduler Construction
      1. 3.6.1. Basic Structure
      2. 3.6.2. Waking Up from Waiting or Activation
        1. 3.6.2.1. sched_fork(): Scheduler Initialization for Newly Forked Process
          1. Line 727
          2. Line 728–730
          3. Lines 740–753
          4. Lines 754–767
          5. Lines 930–934
          6. Lines 940–947
          7. Line 948
          8. Line 749
          9. Lines 951–960
          10. Lines 311–312
          11. Line 313
          12. Line 314
          13. Line 315
          14. Line 316
    7. 3.7. Wait Queues
      1. 3.7.1. Adding to the Wait Queue
      2. 3.7.2. Waiting on the Event
        1. Line 124–126
        2. Lines 127–132
        3. Lines 133–134
      3. 3.7.3. Waking Up
        1. Line 2336
        2. Lines 2340, 2342
        3. Line 2341
        4. Line 2313
        5. Line 2315
        6. Line 2317
        7. Line 2320
        8. Line 2322
        9. Lines 2322–2325
    8. 3.8. Asynchronous Execution Flow
      1. 3.8.1. Exceptions
        1. 3.8.1.1. System Calls
          1. Line 485
          2. Line 488
      2. 3.8.2. Interrupts
        1. 3.8.2.1. Interrupt Handlers
        2. 3.8.2.2. IRQ Structures
          1. Struct irq_desc_t
          2. Line 61
          3. Line 62
          4. Line 63
          5. Line 64
          6. Lines 65–66
          7. Line 67
          8. Struct irqaction
          9. Line 36
          10. Line 37
          11. Line 39
          12. Struct hw_interrupt_type
          13. Line 41
          14. Lines 42–48
        3. 3.8.2.3. An Interrupt Example: System Timer
          1. Line 413
          2. Line 902
          3. Lines 908–910
          4. Lines 912–935
          5. Lines 941–942
          6. Line 947
          7. Line 949
          8. Line 415
          9. Line 410
          10. Lines 342–348
          11. Lines 422–426
          12. Line 431
          13. Line 437
          14. Line 419
          15. Line 317
          16. Line 351
          17. Line 72
          18. Lines 81–84
          19. Interrupt Time
          20. Processing the PowerPC External Interrupt Vector
          21. Lines 513–530
          22. Line 523
          23. Line 524
          24. Line 432
          25. Line 435
          26. Line 436
          27. Lines 441–443
          28. Line 450
          29. Lines 451–462
          30. Lines 463–465
          31. Lines 489–497
          32. Processing the PowerPC System Timer Interrupt
          33. Line 152
          34. Line 159
          35. Lines 165 and 195
          36. Line 167
          37. Line 189
          38. Line 198
          39. Line 208
          40. Processing the x86 System Timer Interrupt
          41. Line 274
          42. Line 287
          43. Line 227
          44. Line 18
          45. Line 25
    9. Summary
    10. Project: current System Variable
      1. Project Source Code
        1. Line 4
        2. Line 5
        3. Line 12
        4. Line 15
        5. Line 16
        6. Line 18
        7. Lines 32–38
      2. Running the Code
    11. Exercises
  10. 4. Memory Management
    1. 4.1. Pages
      1. 4.1.1. flags
        1. 4.1.1.1. count
        2. 4.1.1.2. list
        3. 4.1.1.3. mapping
        4. 4.1.1.4. lru
        5. 4.1.1.5. virtual
    2. 4.2. Memory Zones
      1. 4.2.1. Memory Zone Descriptor
        1. 4.2.1.1. lock
        2. 4.2.1.2. free_pages
        3. 4.2.1.3. pages_min, pages_low, and pages_high
        4. 4.2.1.4. lru_lock
        5. 4.2.1.5. active_list and inactive_list
        6. 4.2.1.6. all_unreclaimable
        7. 4.2.1.7. pages_scanned, temp_priority, and prev_priority
        8. 4.2.1.8. free_area
        9. 4.2.1.9. wait_table, wait_table_size, and wait_table_bits
      2. 4.2.2. Memory Zone Helper Functions
        1. 4.2.2.1. for_each_zone()
        2. 4.2.2.2. is_highmem() and is_normal()
    3. 4.3. Page Frames
      1. 4.3.1. Functions for Requesting Page Frames
        1. 4.3.1.1. alloc_pages() and alloc_page()
        2. 4.3.1.2. __get_free_page() and __get_dma_pages()
      2. 4.3.2. Functions for Releasing Page Frames
      3. 4.3.3. Buddy System
        1. Line 586
        2. Line 599
        3. Lines 608–628
        4. Lines 631–632
        5. Lines 635–653
        6. Lines 720–727
        7. Lines 728–730
        8. Lines 184–215
        9. Line 216
    4. 4.4. Slab Allocator
      1. 4.4.1. Cache Descriptor
        1. 4.4.1.1. lists
          1. lists.slabs_partial
          2. lists.slabs_full
          3. lists.slabs_free
          4. lists.next_reap
        2. 4.4.1.2. objsize
        3. 4.4.1.3. flags
        4. 4.4.1.4. num
        5. 4.4.1.5. gfporder
        6. 4.4.1.6. gfpflags
        7. 4.4.1.7. slabp_cache
        8. 4.4.1.8. ctor
        9. 4.4.1.9. dtor
        10. 4.4.1.10. name
        11. 4.4.1.11. next
      2. 4.4.2. General Purpose Cache Descriptor
        1. 4.4.2.1. cs_size
        2. 4.4.2.2. cs_cachep
        3. 4.4.2.3. cs_dmacachep
      3. 4.4.3. Slab Descriptor
        1. 4.4.3.1. list
        2. 4.4.3.2. s_mem
        3. 4.4.3.3. inuse
        4. 4.4.3.4. free
    5. 4.5. Slab Allocator's Lifecycle
      1. 4.5.1. Global Variables of the Slab Allocator
      2. 4.5.2. Creating a Cache
        1. 4.5.2.1. kmem_cache_init()
          1. Lines 661–663
          2. Lines 669–670
          3. Line 690
          4. Line 691
          5. Line 692
          6. Line 693
          7. Lines 695–698
          8. Line 708
          9. Lines 714–718
          10. Lines 726–730
          11. Lines 732–733
        2. 4.5.2.2. kmem_cache_create()
          1. name
          2. size
          3. offset
          4. flags
          5. ctor and dtor
          6. Lines 1079–1084
          7. Lines 1144–1174
          8. Lines 1200–1217
          9. Lines 1243–1244
          10. Lines 1247–1276
      3. 4.5.3. Slab Creation and cache_grow()
        1. 4.5.3.1. cache_grow()
          1. Lines 1572–1573
          2. Lines 1582–1585
          3. Lines 1597–1598
          4. Lines 1601–1602
          5. Lines 1605–1613
          6. Line 1615
          7. Lines 1616–1619
          8. Lines 1622–1624
          9. Lines 1625–1626
          10. Lines 1627–1628
          11. Lines 1629–1632
      4. 4.5.4. Slab Destruction: Returning Memory and kmem_cache_destroy()
        1. 4.5.4.1. kmem_cache_destroy()
          1. Lines 1425–1426
          2. Lines 1429–1434
          3. Lines 1436–1442
          4. Line 1450
    6. 4.6. Memory Request Path
      1. 4.6.1. kmalloc()
        1. 4.6.1.1. size
        2. 4.6.1.2. flags
          1. Lines 2102–2104
          2. Lines 2112–2113
      2. 4.6.2. kmem_cache_alloc()
        1. 4.6.2.1. cachep
        2. 4.6.2.2. flags
    7. 4.7. Linux Process Memory Structures
      1. 4.7.1. mm_struct
        1. 4.7.1.1. mmap
        2. 4.7.1.2. mm_rb
        3. 4.7.1.3. mmap_cache
        4. 4.7.1.4. pgd
        5. 4.7.1.5. mm_users
        6. 4.7.1.6. mm_count
        7. 4.7.1.7. map_count
        8. 4.7.1.8. mm_list
        9. 4.7.1.9. start_code and end_code
        10. 4.7.1.10. start_data and end_data
        11. 4.7.1.11. start_brk and brk
        12. 4.7.1.12. start_stack
        13. 4.7.1.13. arg_start and arg_end
        14. 4.7.1.14. env_start and env_end
      2. 4.7.2. vm_area_struct
        1. 4.7.2.1. vm_mm
        2. 4.7.2.2. vm_start and vm_end
        3. 4.7.2.3. vm_next
        4. 4.7.2.4. vm_flags
        5. 4.7.2.5. vm_rb
        6. 4.7.2.6. vm_ops
    8. 4.8. Process Image Layout and Linear Address Space
    9. 4.9. Page Tables
    10. 4.10. Page Fault
      1. 4.10.1. x86 Page Fault Exception
      2. 4.10.2. Page Fault Handler
        1. Line 223
        2. Line 232
        3. Lines 246–248
        4. Line 253
        5. Line 257
        6. Lines 262–263
        7. Line 265
        8. Lines 267–269
        9. Lines 270–271
        10. Lines 272–273
        11. Lines 274–284
        12. Lines 473–509
        13. Lines 294–304
        14. Lines 305–309
        15. Lines 318–329
        16. Line 348
        17. Lines 351–353
        18. Lines 354–366
        19. Line 390
        20. Line 432
      3. 4.10.3. PowerPC Page Fault Exception
    11. Summary
    12. Project: Process Memory Map
    13. Exercises
  11. 5. Input/Output
    1. 5.1. How Hardware Does It: Busses, Bridges, Ports, and Interfaces
    2. 5.2. Devices
      1. 5.2.1. Block Device Overview
        1. 5.2.1.1. Generic Block Device Layer
      2. 5.2.2. Request Queues and Scheduling I/O
        1. 5.2.2.1. No-Op I/O Scheduler
        2. 5.2.2.2. Deadline I/O Scheduler
        3. 5.2.2.3. Anticipatory I/O Scheduling
        4. 5.2.2.4. Request Queue
          1. Line 275
          2. Line 276
          3. Line 277
          4. Line 282
          5. Lines 283–293
          6. Lines 294–303
          7. Lines 304–311
          8. Lines 312–317
          9. Lines 318–321
          10. Lines 323–360
          11. Line 1402
          12. Line 1406
          13. Line 1414
          14. Lines 1417–1424
          15. Line 1426
          16. Line 1428
          17. Line 1429
          18. Line 1431
          19. Line 1432
          20. Line 1434
          21. Lines 1435–1439
      3. 5.2.3. Example: “Generic” Block Driver
        1. Line 82
        2. Line 83
        3. Line 85
        4. Line 87
        5. Line 88
        6. Line 89
        7. Line 90
        8. Line 92
        9. Line 196
        10. Line 198
        11. Line 199
      4. 5.2.4. Device Operations
        1. Line 2599
        2. Line 2601
        3. Line 2602
        4. Line 2603
        5. Line 2604
      5. 5.2.5. Character Device Overview
      6. 5.2.6. A Note on Network Devices
      7. 5.2.7. Clock Devices
      8. 5.2.8. Terminal Devices
      9. 5.2.9. Direct Memory Access (DMA)
    3. Summary
    4. Project: Building a Parallel Port Driver
      1. Parallel Port Hardware
      2. Parallel Port Software
        1. 1. Setting Up the File Operations (fops)
        2. 2. Setting Up the Module Initialization Routine
        3. 3. Setting Up the Module Cleanup Routine
        4. 4. Inserting the Module
        5. 5. Application Code
          1. Line 4
          2. Line 12
          3. Line 18
          4. Line 20
          5. Line 21
          6. Line 22
          7. Lines 24–27
          8. Lines 28–33
          9. Line 38
    5. Exercises
  12. 6. Filesystems
    1. 6.1. General Filesystem Concepts
      1. 6.1.1. File and Filenames
      2. 6.1.2. File Types
      3. 6.1.3. Additional File Attributes
      4. 6.1.4. Directories and Pathnames
      5. 6.1.5. File Operations
      6. 6.1.6. File Descriptors
      7. 6.1.7. Disk Blocks, Partitions, and Implementation
      8. 6.1.8. Performance
    2. 6.2. Linux Virtual Filesystem
      1. 6.2.1. VFS Data Structures
        1. 6.2.1.1. superblock Structure
          1. Line 667
          2. Line 672
          3. Line 673
          4. Line 674
          5. Line 675
          6. Line 681
          7. Line 690
          8. Line 693
          9. Line 696
          10. Line 702
        2. 6.2.1.2. superblock Operations
        3. 6.2.1.3. inode Structure
          1. Line 369
          2. Line 370
          3. Line 371
          4. Line 372
          5. Line 373
          6. Line 392
          7. Line 407
        4. 6.2.1.4. dentry Structure
          1. Line 85
          2. Lines 85–88
          3. Line 91
          4. Line 92
          5. Line 100
        5. 6.2.1.5. file Structure
          1. Line 507
          2. Line 508
          3. Line 509
          4. Line 510
          5. Line 511
          6. Line 512
          7. Line 514
          8. Line 516
          9. Line 517
          10. Line 527
      2. 6.2.2. Global and Local List References
    3. 6.3. Structures Associated with VFS
      1. 6.3.1. fs_struct Structure
        1. 6.3.1.1. count
        2. 6.3.1.2. umask
        3. 6.3.1.3. root, pwd, and altroot
        4. 6.3.1.4. rootmnt, pwdmnt, and altrootmnt
      2. 6.3.2. files_struct Structure
        1. Line 23
        2. Line 25
        3. Line 26
        4. Line 27
        5. Line 28
        6. Lines 30–32
        7. 6.3.2.1. close_on_exec
        8. 6.3.2.2. open_fds
        9. 6.3.2.3. close_on_exec
        10. 6.3.2.4. open_fds_init
        11. 6.3.2.5. fd_array
    4. 6.4. Page Cache
      1. 6.4.1. address_space Structure
      2. 6.4.2. buffer_head Structure
    5. 6.5. VFS System Calls and the Filesystem Layer
      1. 6.5.1. open ()
        1. Lines 932–934
        2. Line 935
        3. Line 938
        4. Line 940
        5. Lines 745–749
        6. Line 751
        7. Line 753
        8. Line 852
        9. Lines 855–856
        10. Lines 866–869
        11. Line 870
        12. Lines 872–877
        13. Line 944
        14. Line 947
        15. Line 949
        16. Line 952
      2. 6.5.2. close ()
        1. Line 1023
        2. Lines 1025–1030
        3. Lines 1031–1032
        4. Line 1033
        5. Lines 890–891
        6. Lines 1034–1035
        7. Lines 991–993
        8. Lines 995–997
        9. Lines 1000–1001
        10. Line 1008
      3. 6.5.3. read()
        1. Line 272
        2. Lines 273–282
        3. Line 200
        4. Line 202
        5. Lines 205–208
        6. Lines 210–214
        7. Lines 215–217
        8. 6.5.3.1. Moving from the Generic to the Specific
          1. Lines 924–925
          2. Line 927
          3. Lines 928 and 931
          4. Line 932
          5. Lines 933–935
          6. Lines 835–842
          7. Lines 845–862
          8. Lines 863–886
          9. Lines 889–890
          10. Lines 891–898
          11. Line 838
          12. Line 839
          13. Line 840
          14. Line 841
          15. Lines 899
          16. Lines 900–909
        9. 6.5.3.2. Tracing the Page Cache
          1. Lines 1420–1430
          2. Line 652
          3. Lines 658–660
          4. Lines 662–681
          5. Lines 682–689
          6. Lines 690–723
          7. Lines 724–740
          8. Lines 741–743
          9. Lines 746–750
          10. Lines 751–758
          11. Lines 698–772
          12. Lines 773–775
          13. Lines 776–777
          14. Lines 779–781
          15. Line 786
          16. Lines 787–788
          17. Line 789
          18. Lines 360–361
          19. Lines 363–364
          20. Lines 365–367
          21. Line 90
          22. Lines 92–94
          23. Lines 95–96
          24. Lines 2433–2443
          25. Lines 2445–2452
          26. Line 2454
      4. 6.5.4. write()
        1. Lines 44–45
        2. Line 632
        3. 6.5.4.1. Flushing Dirty Pages
    6. Summary
    7. Exercises
  13. 7. Scheduling and Kernel Synchronization
    1. 7.1. Linux Scheduler
      1. 7.1.1. Choosing the Next Task
        1. Lines 2213–2218
        2. Lines 2224–2225
        3. Line 2227
        4. Lines 2233–2241
        5. Line 2243
        6. Lines 2244–2252
        7. Lines 2255–2264
        8. Lines 2266–2268
        9. Lines 2270–2273
        10. Lines 2275–2285
        11. Line 2286
        12. Line 2288
        13. Line 2290
        14. Lines 2292–2298
        15. Lines 2300–2304
        16. Lines 2306–2308
        17. Lines 2314–2318
      2. 7.1.2. Context Switch
        1. Line 39
        2. Line 42
        3. Line 47
        4. 7.1.2.1. Following the x86 Trail of switch_to()
          1. Line 12
          2. Lines 15–16
          3. Lines 17 and 30
          4. Lines 17–18
          5. Line 19
          6. Line 20
          7. Line 21
          8. Line 22
          9. Line 23
          10. Lines 24–25
          11. Lines 26–29
          12. Line 29
        5. 7.1.2.2. Following the PPC context_switch()
          1. Line 157
          2. Line 158
          3. Line 159
          4. Lines 1437–1440
          5. Lines 1461–1465
        6. 7.1.2.3. Following the PPC Trail of switch_to()
          1. Line 205
          2. Lines 247–248
          3. Line 249
          4. Line 250
          5. Tracing the PPC Code for _switch()
          6. Lines 438–460
          7. Line 461
          8. Lines 463–465
          9. Line 466
          10. Line 468
          11. Line 469
          12. Lines 478–486
      3. 7.1.3. Yielding the CPU
        1. Lines 1981–1986
        2. Line 1988
        3. Lines 1990–1991
        4. Lines 1994–2000
        5. Lines 2002–2011
        6. Lines 2012–2016
        7. Lines 2019–2022
        8. Line 2023
        9. Lines 2031–2046
        10. Lines 2047–2061
        11. Lines 2079–2089
        12. Lines 2090–2094
        13. 7.1.3.1. Dynamic Priority Calculation
          1. Lines 386–389
          2. Lines 391–404
          3. Lines 405–410
          4. Lines 411–418
          5. Lines 419–432
          6. Lines 434–450
          7. Line 452
        14. 7.1.3.2. Deactivation
          1. Line 509
          2. Lines 510–511
          3. Line 512–513
          4. Line 305
          5. Lines 306–308
    2. 7.2. Preemption
      1. 7.2.1. Explicit Kernel Preemption
      2. 7.2.2. Implicit User Preemption
        1. Lines 988–996
        2. Lines 1003–1006
      3. 7.2.3. Implicit Kernel Preemption
        1. Lines 46–50
        2. Lines 40–44
        3. Line 2336–2337
        4. Line 2340–2347
    3. 7.3. Spinlocks and Semaphores
    4. 7.4. System Clock: Of Time and Timers
      1. 7.4.1. Real-Time Clock: What Time Is It?
      2. 7.4.2. Reading the PPC Real-Time Clock
      3. 7.4.3. Reading the x86 Real-Time Clock
    5. Summary
    6. Exercises
  14. 8. Booting the Kernel
    1. 8.1. BIOS and Open Firmware
    2. 8.2. Boot Loaders
      1. 8.2.1. GRUB
        1. 8.2.1.1. Multiboot Specification
      2. 8.2.2. LILO
      3. 8.2.3. PowerPC and Yaboot
    3. 8.3. Architecture-Dependent Memory Initialization
      1. 8.3.1. PowerPC Hardware Memory Management
        1. 8.3.1.1. Real Addressing Mode
        2. 8.3.1.2. Address Translation
          1. Segmented Address Translation Direct Store Segment T
          2. Block Address Translation
          3. Translation Lookaside Buffers
          4. Storage Access Mode Control
        3. 8.3.1.3. How Linux Uses PPC Address Translation
          1. Line 40
          2. Line 54
          3. Line 64
          4. Line 68
          5. Line 73
          6. Line 89
          7. Line 131
          8. Line 150
          9. Line 170
          10. Lines 173–176
          11. Lines 181–182
          12. Lines 188–198
          13. Line 210
          14. Lines 224–232
          15. Line 1337
          16. Line 1364
          17. Line 1365
          18. Line 1385
          19. Line 1395
          20. Lines 1412–1419
      2. 8.3.2. x86 Intel-Based Hardware Memory Management
        1. Lines 307–345
        2. Lines 595–628
        3. Lines 723–739
        4. Lines 790–797
        5. Lines 981–1006
        6. Lines 830–831
        7. Lines 834–839
        8. Line 852
        9. 8.3.2.1. Protected Mode
          1. Line 57
          2. Line 63
          3. Lines 64–68
          4. Lines 91–111
          5. Lines 113–157
          6. Lines 162–164
          7. Lines 165–168
          8. Line 170
          9. Lines 177–178
          10. Lines 180–185
          11. Line 191
          12. Lines 197–214
          13. Lines 215–303
      3. 8.3.3. PowerPC and x86 Code Convergence
    4. 8.4. Initial RAM Disk
    5. 8.5. The Beginning: start_kernel()
      1. 8.5.1. The Call to lock_kernel()
        1. Line 405
        2. Lines 44–48
        3. Lines 10–15
        4. Lines 59–63
      2. 8.5.2. The Call to page_address_init()
        1. Line 406
        2. Line 597
        3. Lines 598–599
        4. Lines 600–603
        5. Line 604
      3. 8.5.3. The Call to printk(linux_banner)
        1. Line 407
      4. 8.5.4. The Call to setup_arch
        1. Line 408
        2. Line 1087
        3. Line 1088
        4. Line 1089
        5. Lines 1103–1116
        6. Lines 1118–1122
        7. Lines 1124–1127
        8. Line 1129
        9. Lines 1133–1141
        10. Line 1143
        11. Line 1145
        12. Lines 1153–1155
        13. Lines 1157–1167
        14. Line 1170
        15. Lines 1172–1174
        16. Lines 1175–1176
        17. Line 1181
        18. Lines 1183–1186
        19. Line 1188
        20. Lines 1190–1197
      5. 8.5.5. The Call to setup_per_cpu_areas()
        1. Line 409
        2. Lines 329–332
        3. Lines 334–341
        4. Lines 343–346
      6. 8.5.6. The Call to smp_prepare_boot_cpu()
        1. Line 415
      7. 8.5.7. The Call to sched_init()
        1. Line 422
        2. Lines 3919–3926
        3. Lines 3938–3947
        4. Lines 3952–3956
        5. Lines 3961–3962
      8. 8.5.8. The Call to build_all_zonelists()
        1. Line 424
      9. 8.5.9. The Call to page_alloc_init
        1. Line 425
        2. Line 1809
        3. Line 1788
        4. Lines 1794–1802
      10. 8.5.10. The Call to parse_args()
        1. Line 427
        2. Lines 116–125
        3. Lines 126–153
        4. Lines 46–54
        5. Lines 55–61
        6. Lines 62–66
      11. 8.5.11. The Call to trap_init()
        1. Line 431
      12. 8.5.12. The Call to rcu_init()
        1. Line 432
      13. 8.5.13. The Call to init_IRQ()
        1. Line 433
        2. Lines 422–432
        3. Line 437
        4. Line 443
        5. Lines 449–450
        6. Line 704
        7. Line 707
      14. 8.5.14. The Call to softirq_init()
        1. Line 436
        2. Lines 319–320
      15. 8.5.15. The Call to time_init()
        1. Line 437
        2. Lines 379–387
        3. Lines 388–391
        4. Line 393
      16. 8.5.16. The Call to console_init()
        1. Line 444
        2. Line 2352
        3. Line 2359
        4. Line 2366
      17. 8.5.17. The Call to profile_init()
        1. Line 447
        2. Lines 34–35
        3. Lines 38–39
        4. Lines 41–42
      18. 8.5.18. The Call to local_irq_enable()
        1. Line 448
        2. Lines 446–447
      19. 8.5.19. initrd Configuration
        1. Lines 449–456
      20. 8.5.20. The Call to mem_init()
        1. Line 457
        2. Line 459
        3. Line 469
        4. Line 477
        5. Lines 480–486
        6. Line 488
        7. Lines 490–506
        8. Lines 521–523
        9. Lines 399–410
        10. Lines 412–419
        11. Lines 421–432
        12. Lines 433–450
        13. Lines 452–467
        14. Lines 469–480
        15. Lines 482–492
      21. 8.5.21. The Call to late_time_init()
        1. Lines 459–460
      22. 8.5.22. The Call to calibrate_delay()
        1. Line 461
        2. Line 186
        3. Lines 189–200
        4. Line 204
        5. Lines 206–214
        6. Lines 217–219
      23. 8.5.23. The Call to pgtable_cache_init()
        1. Line 463
        2. Lines 532–542
        3. Lines 544–551
      24. 8.5.24. The Call to buffer_init()
        1. Line 472
        2. Line 3036
        3. Line 3039
        4. Line 3044
      25. 8.5.25. The Call to security_scaffolding_startup()
        1. Line 474
      26. 8.5.26. The Call to vfs_caches_init()
        1. Line 475
        2. Line 1623
        3. Lines 1625–1629
        4. Lines 1631–1635
        5. Line 1637
        6. Line 1638
        7. Line 1639
        8. Line 299
        9. Lines 301–302
        10. Line 1640
        11. Lines 1139–1144
        12. Lines 1161–1173
        13. Lines 1179–1185
        14. Lines 218–222
        15. Lines 237–240
        16. Lines 1116–1123
        17. Line 1125
        18. Lines 1134–1135
        19. Lines 293–298
        20. Line 301
        21. Lines 304–308
      27. 8.5.27. The Call to radix_tree_init()
        1. Line 476
      28. 8.5.28. The Call to signals_init()
        1. Line 477
        2. Lines 2567–2571
      29. 8.5.29. The Call to page_writeback_init()
        1. Line 479
        2. Lines 495–507
        3. Line 508
        4. Line 509
        5. Line 510
        6. Lines 416–417
      30. 8.5.30. The Call to proc_root_init()
        1. Lines 480–482
        2. Line 42
        3. Line 45
        4. Line 48
        5. Lines 54–78
      31. 8.5.31. The Call to init_idle()
        1. Line 490
        2. Line 2645
        3. Line 2648–2649
        4. Line 2651
        5. Lines 2652–2656
        6. Lines 2657–2659
      32. 8.5.32. The Call to rest_init()
        1. Line 493
        2. Line 388
        3. Line 390
        4. Line 391
        5. Line 392
    6. 8.6. The init Thread (or Process 1)
      1. Line 612
      2. Line 629
      3. Line 553
      4. Lines 555–557
      5. Line 560
      6. Line 562
      7. Line 563
      8. Lines 635–638
      9. Line 387
      10. Lines 391–396
      11. Line 398
      12. Lines 400–401
      13. Line 406
      14. Lines 355–358
      15. Lines 364–375
      16. Line 377
      17. Line 645
      18. Lines 649–650
      19. Lines 662–668
      20. Line 670
    7. Summary
    8. Exercises
  15. 9. Building the Linux Kernel
    1. 9.1. Toolchain
      1. 9.1.1. Compilers
      2. 9.1.2. Cross Compilers
      3. 9.1.3. Linker
      4. 9.1.4. ELF Object Files
        1. 9.1.4.1. ELF Header
          1. Line 237
          2. Line 238
          3. Line 239
          4. Line 240
          5. Line 241
          6. Line 242
          7. Line 243
          8. Line 244
          9. Line 245
          10. Line 246
          11. Line 247
          12. Line 248
          13. Line 249
          14. Line 250
        2. 9.1.4.2. Section Header Table
          1. Line 333
          2. Line 334
          3. Line 335
          4. Line 336
          5. Line 337
          6. Line 338
          7. Line 339
          8. Line 340
          9. Line 341
          10. Line 342
        3. 9.1.4.3. Non-Executable ELF File Sections
        4. 9.1.4.4. Program Header Table
          1. Line 277
          2. Line 278
          3. Line 279
          4. Line 280
          5. Line 281
          6. Line 282
          7. Line 283
          8. Line 284
    2. 9.2. Kernel Source Build
      1. 9.2.1. Source Explained
        1. 9.2.1.1. Architecture-Independent Code
          1. fs/
          2. init/
          3. kernel/
          4. mm/
        2. 9.2.1.2. Architecture-Dependent Code
        3. 9.2.1.3. Miscellaneous Files and Directories
      2. 9.2.2. Building the Kernel Image
        1. 9.2.2.1. Kernel Configuration Tool
        2. 9.2.2.2. Sub-Makefiles
        3. 9.2.2.3. Linux Kernel Makefiles
    3. Summary
    4. Exercises
  16. 10. Adding Your Code to the Kernel
    1. 10.1. Traversing the Source
      1. 10.1.1. Getting Familiar with the Filesystem
        1. Lines 655–681
      2. 10.1.2. Filps and Fops
        1. Lines 1824–1829
        2. Lines 1831–1835
      3. 10.1.3. User Memory and Kernel Memory
        1. Lines 1454–1455
        2. Lines 1460–1461
      4. 10.1.4. Wait Queues
        1. Line 1591
        2. Lines 1608–1611
        3. Lines 1618–1626
        4. Lines 1631–1633
        5. Lines 1635–1636
        6. Lines 1638–1639
        7. Line 2209
        8. Line 2233
        9. Line 2234
        10. Lines 2235–2241
        11. Lines 2494–2497
        12. Lines 2499–2502
        13. Lines 2504–2513
      5. 10.1.5. Work Queues and Interrupts
      6. 10.1.6. System Calls
      7. 10.1.7. Other Types of Drivers
        1. Line 83
        2. Lines 84–85
        3. Line 86
        4. Line 87
        5. Line 88
        6. Line 89
        7. Line 90
        8. Line 91
        9. Line 576
        10. Line 495
        11. Line 557
      8. 10.1.8. Device Model and sysfs
        1. Line 103
        2. Line 104
        3. Lines 105–115
        4. Line 135
        5. Line 136
        6. Line 137
    2. 10.2. Writing the Code
      1. 10.2.1. Device Basics
      2. 10.2.2. Symbol Exporting
      3. 10.2.3. IOCTL
      4. 10.2.4. Polling and Interrupts
        1. Line 8
        2. Lines 9–12
        3. Line 27
      5. 10.2.5. Work Queues and Tasklets
      6. 10.2.6. Adding Code for a System Call
    3. 10.3. Building and Debugging
      1. 10.3.1. Debugging Device Drivers
    4. Summary
    5. Exercises
  17. Bibliography