第一部分 ARM Linux內核——分析內核前需要做的準備
第1章 內核介紹及2.6版和3.2版 之間的差異 2
1.1 內核的誕生、作用以及內部結構 2
1.1.1 Linus創造的Linux 2
1.1.2 由多種子係統集成運行的單內核 3
1.1.3 全世界最著名的通用操作係統 5
1.2 內核2.6版和3.2版之間的差異 5
第2章 內核構建係統 8
2.1 內核初始化 8
2.2 內核配置 9
2.3 內核構建 11
2.4 內核安裝 17
第3章 瞭解ARM處理器 19
3.1 處理器概要和特徵 19
3.2 處理器架構與核心 19
3.3 處理器命名規則 21
3.4 處理器內部結構 21
3.5 處理器模式和寄存器 23
3.6 處理器異常 25
3.7 硬件擴展功能 26
3.7.1 緩存 26
3.7.2 內存管理裝置 26
3.7.3 協處理器 26
第4章 構建分析環境 28
4.1 下載並安裝Linux源內核 28
4.1.1 下載源內核 28
4.1.2 安裝源內核 30
4.2 安裝ctags+cscope 31
4.2.1 用ctags製作源代碼標簽 31
4.2.2 製作cscope標簽數據庫 33
4.3 vim插件下載及環境設置 34
4.3.1 下載vim插件 34
4.3.2 vim+plugin的環境結構 37
4.3.3 vim環境設置 38
4.4 查看源碼分析環境工具 40
第二部分 內核的啓動——start_kernel調用方法
第5章 準備解壓內核 48
5.1 進入啓動加載後結束首個啓動——start 標簽 49
5.2 BSS係統域初始化——not_relocated 標簽 50
5.3 激活緩存——cache_on 標簽 53
5.4 頁目錄項初始化——__setup_mmu 標簽 56
5.5 指令緩存激活及緩存策略適用——__common_mmu_cache_on 標簽 58
第6章 從壓縮的內核zImage 還原內核映像 60
6.1 解壓內核並避免覆寫——wont_overwrite、decompress_kernel標簽 61
6.2 調用已解壓內核——call_kernel標簽 62
6.3 緩存清理及清除——cache_clean_flush 標簽 62
6.4 緩存禁用——cache_off 標簽 64
第7章 調用start_kernel() 65
7.1 初始化指嚮——stext標簽 65
7.2 處理器信息搜尋——__look_processor_type 69
7.2.1 __lookup_processor_type標簽 69
7.2.2 __proc_info_begin和__proc_info_end中保存的信息 71
7.2.3 在MMU禁用狀態下將虛擬地址轉換為物理地址 73
7.2.4 查找proc_info_list 結構體並比較處理器信息 74
7.3 搜尋我的機型——__lookup_machine_type 75
7.3.1 __lookup_machine_type標簽 75
7.3.2 保存在__arch_info_begin和__arch_info_end中的machine_desc信息及訪問路徑 76
7.3.3 查找machine_desc結構體並比較機器信息 77
7.4 源自啓動加載項的atags——__vet_atags標簽 78
7.5 對虛擬內存進行基礎創建——__create_page_tables標簽 81
7.6 設置核心(core)——v6_setup標簽 85
7.7 打開MMU並使用虛擬地址——__enable_mmu/__turn_mmu_on標簽 86
7.8 跳轉至start_kernel——__mmap_switched 標簽 90
第三部分 內核的執行——內核的起始與結束位置
第8章 start_setup_processor_id()~lock_kernel() 94
8.1 smp_setup_processor_id()、lockdep_init()、debug_objects_early_init() 95
8.1.1 smp_setup_processor_id() 95
8.1.2 lockdep_init() 95
8.1.3 debug_objects_early_init() 96
8.2 棧溢齣感應——__boot_init_stack_canary 98
8.3 初始化提供進程集成方法的cgroup——__cgroup_init_early() 98
8.3.1 cgroupfs_root和cgroup的關聯初始化——init_cgroup_root() 102
8.3.2 初始化子係統——cgroup_init_subsys() 103
8.4 禁用IRQ 104
8.5 early_boot_irqs_off()、early_init_irq_lock_class() 104
8.6 大內核鎖——lock_kernel() 106
第9章 注冊針對時鍾事件的處理器 111
9.1 函數的聲明和定義——tick_init() 111
9.2 注冊處理事件的處理器——_clockevents_register_notifier() 113
9.2.1 為clockevents_lock添加自鏇鎖 114
9.2.2 clockevents_chain生成原理 115
9.2.3 在clockevents_chain中注冊tick_notifier的方法 116
9.2.4 對clockevents_lock解除自鏇鎖的原理 117
第10章 在CPU位圖中注冊當前運行CPU/初始化HIGHMEM管理 119
10.1 在包含熱插拔信息的位圖上添加執行init_task的CPU——boot_cpu_init() 119
10.2 管理高端內存——page_address_init() 121
第11章 整體指嚮——setup_arch 123
第12章 unwind_init()~early_trap_init() 126
12.1 棧迴溯——unwind_init() 126
12.2 求齣包含機器信息的machine_desc結構體——setup_machine() 126
12.3 處理ATAG信息——setup_arch() 127
12.4 處理啓動參數——parse_cmdline() 129
12.5 構建源代碼樹——request_standard_resources() 131
12.6 初始化cpu possible位圖——smp_init_cpus() 136
12.7 用棧指定各ARM異常模式——cpu_init() 137
12.8 初始化以處理異常——early_trap_init() 138
12.9 查看中斷處理器函數 143
12.9.1 調用IRQ處理器——asm_do_IRQ() 147
12.9.2 返迴中斷之前——ret_to_user標簽 147
第13章 設置處理器—— setup_processor() 150
13.1 查看setup_processor()結構 150
13.2 查找CPU ID——read_cpuid_id() 151
13.3 查找處理器信息——lookup_processor_type() 153
13.4 查找處理器結構信息——cpu_architecture() 153
13.5 查找處理器緩存類型_cacheid_init() 156
13.6 調用處理器初始化函數——cpu_proc_init() 160
第14章 準備內存分頁—— paging_init() 163
14.1 查看paging_init()的整體結構 163
14.2 設置內存類型錶——build_mem_type_table() 165
14.3 檢驗內存信息——sanity_check_meminfo() 166
14.4 準備頁錶——prepare_page_table() 168
14.4.1 prepare_page_table() 168
14.4.2 Linux的分頁結構 170
14.4.3 求齣頁目錄項 170
14.4.4 pmd_clear() 172
14.5 設備區域映射準備——devicemaps_init() 174
14.6 準備使用高端內存——kmap_init() 177
14.7 初始化零頁 178
14.7.1 分配內存——__alloc_bootmem_nopanic() 179
14.7.2 在指定節點使用fallback分配內存——alloc_bootmem_core 180
14.7.3 將虛擬地址變換為page結構體——virt_to_page 182
14.8 保持數據緩存一緻性——flush_dcache_page() 182
第15章 在啓動時初始化內存分配器 184
15.1 bootmem函數流和數據結構 185
15.2 查看bootmem_init()結構 188
15.3 查找虛擬內存盤位置——check_initrd() 189
15.4 將節點的BANK信息反映到頁目錄——bootmem_init_node() 191
15.4.1 map_memory_bank() 192
15.4.2 bootmem_bootmap_pages() 195
15.4.3 find_bootmap_pfn() 196
15.4.4 node_set_online() 197
15.4.5 NODE_DATA宏 198
15.4.6 init_bootmem_node() 200
15.4.7 free_bootmem_node() 202
15.4.8 reserve_bootmem_node() 202
15.5 排除0號節點——reserve_node_zero() 203
15.6 排除虛擬內存盤節點——bootmem_reserve_initrd() 204
15.7 設置為無可用頁——bootmem_free_node() 205
15.8 初始化free_area區域 207
15.8.1 free_area結構體 207
15.8.2 free_area_init_node() 208
15.8.3 free_area_init_core() 209
15.8.4 init_currently_empty_zone() 211
15.8.5 memmap_init() 212
第16章 mm_init_owner()~preempt_disable() 217
16.1 設置內存擁有者——mm_init_owner() 217
16.2 保存命令行——setup_command_line() 218
16.3 初始化per-cpu數據——setup_per_cpu_areas() 219
16.4 求CPU個數——setup_nr_cpu_ids() 221
16.5 注冊SMP上的啓動進程——smp_prepare_boot_cpu() 222
16.6 初始化數據結構以使用調度程序——sched_init() 224
16.6.1 為集閤調度中使用的task_group的sched_entity結構體和runqueue結構體分配內存 224
16.6.2 初始化root_domain、rt_bandwidth、task_group相關數據結構 227
16.6.3 初始化係統上所有可用CPU的就緒隊列 229
16.6.4 初始化當前任務的調度相關值與注冊針對負載均衡的中斷處理器 230
16.7 允許內核搶占和阻止搶占——preempt_enable()/preempt_disable() 231
第17章 構建藉用內存的後颱 233
17.1 在build_all_zonelists()中操作的一些數據結構 233
17.2 查看build_all_zonelists()結構 235
17.3 決定zone的列錶方式——set_zonelist_order() 236
17.4 構建備用列錶和備用位圖——__build_all_zonelists() 238
17.4.1 build_zonelists() 239
17.4.2 build_zonelist_in_node_order() 241
17.4.3 build_zonelists_in_zone_order() 243
17.4.4 build_thisnode_zonelists() 244
17.4.5 build_zonelists_cache() 244
17.5 輸齣備用列錶信息——mminit_verify_zonelist() 246
17.6 指定處理頁分配請求的節點——cpuset_init_current_mems_allowed() 246
17.7 求空頁數——nr_free_pagecache_pages() 247
17.8 頁移動性 250
第18章 page_alloc_init()~pidhash_init() 253
18.1 處理用於熱插拔CPU的頁——page_alloc_init() 253
18.2 處理console參數——parse_early_param() 255
18.3 處理特殊參數——parse_args() 257
18.4 確認中斷處理是否激活——irqs_disable() 260
18.5 內核異常列錶定義——sort_main_extable() 261
18.6 初始化RCU機製——rcu_init() 263
18.7 準備使用IRQ——early_irq_init() 266
18.8 初始化中斷——init_IRQ() 269
18.9 構建迅速搜尋進程信息的結構——pidhash_init() 271
第19章 init_timers()~page_cgroup _init() 273
19.1 初始化計時器——init_timers() 274
19.1.1 timers_cpu_notify() 275
19.1.2 register_cpu_notifier() 275
19.1.3 open_softirq() 276
19.2 初始化高分辨率計時器——hrtimers_init() 277
19.3 注冊softirq的迴調函數——softirq_init() 280
19.4 設置xtime——timekeeping_init() 282
19.5 初始化硬件計時器——time_init() 285
19.6 初始化時鍾時間——sched_clock_init() 286
19.7 激活CPU的中斷處理——local_irq_enable() 288
19.8 檢測用作根文件係統的init虛擬內存盤 288
19.9 初始化以分配動態內存——vmalloc_init() 289
19.10 預先初始化目錄項和索引節點緩存——vfs_caches_init_early() 290
19.11 初始化cpuset子係統——cpuset_init_early() 293
19.12 初始化內存子係統——page_cgroup_init() 294
第20章 終止bootmem分配器並替換為夥伴係統 297
20.1 mem_init()函數的調用關係及其與數據結構的相互關係 297
20.2 查看mem_init()結構 298
20.3 記錄到不存在的內存位圖——free_unused_memmap_node() 300
20.4 移交至普通空白頁夥伴係統——free_all_bootmem_node() 301
20.4.1 register_page_bootmem_info_node() 301
20.4.2 free_all_bootmem_core() 303
20.4.3 __free_pages_bootmem() 305
20.4.4 __free_pages() 308
20.4.5 free_hot_cold_page() 308
20.4.6 __free_pages_ok() 309
20.5 移交到高端內存空白頁夥伴係統——free_area() 314
第21章 初始化以支持CPU熱插拔 315
21.1 初始化cpu_hotplug成員變量——cpu_hotplug_init() 315
21.2 CPU的聯機→脫機轉換處理 316
第22章 激活slab內存分配器——kmem_cache_init() 318
22.1 slab分配器的概念及結構體 318
22.2 slab分配器的重要結構體——kmem_cache和kmem_list3 319
22.3 查看kmem_cache_init()結構 322
22.4 初始化initkmem_list3[]、cache_cache、nodelist[] 326
22.5 連接kmem_list3數組並決定cache壓縮時間——set_up_list3s() 328
22.6 求齣用於cache擴展/壓縮的頁順序——cache_estimate() 329
22.7 malloc_sizes和cache_names 332
22.8 生成cache——kmem_cache_create() 334
22.8.1 kmem_cache_zalloc() 336
22.8.2 calculate_slab_order() 337
22.8.3 setup_cpu_cache() 337
22.8.4 enable_cpucache() 339
22.9 生成arraycache_init,kmem_list3 cache 340
22.10 用kmalloc()函數分配的內存替代靜態分配的內存 342
第23章 kmem_trace_init()~security_init() 344
23.1 生成ID alloccator緩存——idr_init_cache() 345
23.2 初始化pageset——setup_per_cpu_pageset() 345
23.3 指定交叉節點——numa_policy_init() 350
23.4 結束計時器初始化——late_time_init() 353
23.5 測定BogoMIPS——calibrate_delay() 353
23.6 製作位圖以分配進程識彆符(ID)——pidmap_init() 354
23.7 初始化優先樹的數據結構——prio_tree_init() 356
23.8 生成anon_vma slab緩存——anon_vma_init() 356
23.9 為對象的每個用戶賦予資格——cred_init() 357
23.10 初始化數據結構以使用fork()函數——fork_init() 358
23.11 初始化生成進程的緩存——proc_caches_init() 359
23.12 初始化緩衝緩存——buffer_init() 361
23.13 準備密鑰——key_init() 364
第24章 初始化VFS中使用的多種緩存——vfs_cache_init() 367
第25章 radix_tree_init()~ftrace_init() 382
25.1 基數樹相關數據結構初始化——radix_tree_init() 383
25.2 準備使用信號——signals_init() 383
25.3 注冊並掛載proc文件係統——proc_root_init() 384
25.4 注冊未能初始化的子係統——cgroup_init() 385
25.5 重置top_cpuset並注冊cpuset文件係統——cpuset_init() 386
25.6 初始化任務統計信息接口——delayacct_init() 387
25.7 為管理延遲信息做準備——delayacct_init() 388
25.7.1 延遲審計 388
25.7.2 delayacct_init 389
25.7.3 task_delay_info結構體和delayacct_tsk_init() 390
25.8 檢查寫緩衝一緻性——check_bugs() 392
第26章 同步內存與後備存儲——page write back 394
26.1 頁迴寫機製 394
26.2 激活頁迴寫——pdflush_init() 395
26.3 pdflush綫程 397
26.4 指定頁迴寫函數 398
26.5 周期性頁迴寫和強製性頁迴寫迴調函數調用方法 399
26.5.1 周期性頁迴寫函數——wb_kupdate() 399
26.5.2 強製性頁迴寫函數——background_writeout() 401
26.6 初始化周期性頁迴寫 403
第27章 查看啓動內核的最終函數結構——rest_init() 405
第28章 生成執行函數的內核綫程——kernel_thread() 407
28.1 查看kernel_thread()結構 407
28.2 生成處理器的網關——do_fork() 408
28.3 復製父進程——copy_process() 411
第29章 喚醒新生成的任務 419
29.1 查看wake_up_new_task結構 419
29.2 獲取任務的就緒隊列——task_rq_lock() 421
29.3 改善任務的優先順序——effective_prio() 422
第30章 準備使用內核 426
30.1 將當前進程轉移到其他CPU——sched_init_smp() 427
30.2 結束係統整體初始化——do_basic_setup() 429
30.2.1 生成執行rcu_sched_grace_period()的綫程——rcu_init_sched() 430
30.2.2 生成events工作隊列——init_workqueues 430
30.2.3 初始化cpuset子係統的top_cpuset——cpuset_init_smp() 437
30.2.4 生成khelper工作隊列——usermodehelper_init() 437
30.2.5 初始化Linux的設備模型——driver_init() 439
30.2.6 在proc文件係統注冊irq信息——init_irq_proc() 446
30.2.7 調用內核未知子係統——do_initcalls() 448
30.3 為初始化之後的操作做準備——init_post() 451
第31章 內核綫程守護進程 453
31.1 內核綫程守護進程——kthreadd() 453
31.2 忽略信號——ignore_signals() 456
31.3 設置nice值——set_user_nice() 458
31.4 搜索執行任務的CPU——set_cpus_allowed_prt() 463
31.5 搜索包含列錶的實際結構體位置——list_entry() 464
31.6 生成內核綫程——create_kthread() 466
第32章 find_task_by_pid_ns()~cpu_idle() 469
32.1 用PID搜索任務——find_task_by_pid_ns() 470
32.2 解除BKL——unlock_kernel() 472
32.3 將調度類變更為idle——init_idle_bootup_task() 473
32.4 RCU機製激活完成通知——rcu_scheduler_starting() 473
32.5 激活內核搶占——preempt_enable_no_resched() 473
32.6 執行進程調度錶——schedule() 474
32.7 Linux啓動萬裏長徵的終點——cpu_idle() 476
附 錄
附錄A 匯編語言、gas關鍵詞總結 480
附錄B 內核分析常見API 485
附錄C 淺談ext2文件係統 487
附錄D Linux綫程模型 497
附錄E 鏈接器腳本文件結構 500
後記 510
索引 513
· · · · · · (
收起)