小苏子
小苏子PDF在线图书

ARM Linux内核源码剖析 内容简介

ARM Linux内核源码剖析 内容简介

ARM Linux内核源码剖析 目录

ARM Linux内核源码剖析 精彩文摘

《图灵程序设计丛书:ARM Linux内核源码剖析》是多位作者在3年Liunx内核分析经验和庞大资料基础上写成的,收录了其他同类书未曾讲解的内容并进行逐行分析,一扫当前市场中其他理论书带给读者的郁闷。书中详细的代码分析与大量插图能够使读者对Linux内核及ARM获得正确认识,自然而然习得如何有效分析定期发布的Linux内核。《图灵程序设计丛书:ARM Linux内核源码剖析》适合想从Linux内核启动开始透彻分析全部启动过程的读者,因Linux代码量庞大而束手无策的人、想要了解Linux实际运行过程的人、渴求OS实操理论的人,本书必将成为他们不可或缺的参考书。第一部分 ARM Linux内核——分析内核前需要做的准备第1章 内核介绍及2.6版和3.2版之间的差异1.1 内核的诞生、作用以及内部结构1.1.1 Linus创造的Linux1.1.2 由多种子系统集成运行的单内核1.1.3 全世界最著名的通用操作系统1.2 内核2.6版和3.2版之间的差异第2章 内核构建系统2.1 内核初始化2.2 内核配置2.3 内核构建2.4 内核安装第3章 了解ARM处理器3.1 处理器概要和特征3.2 处理器架构与核心3.3 处理器命名规则3.4 处理器内部结构3.5 处理器模式和寄存器3.6 处理器异常3.7 硬件扩展功能3.7.1 缓存3.7.2 内存管理装置3.7.3 协处理器第4章 构建分析环境4.1 下载并安装Linux源内核4.1.1 下载源内核4.1.2 安装源内核4.2 安装ctags+cscope4.2.1 用ctags制作源代码标签4.2.2 制作cscope标签数据库4.3 vim插件下载及环境设置4.3.1 下载vim插件4.3.2 vim+plugin的环境结构4.3.3 vim环境设置4.4 查看源码分析环境工具第二部分 内核的启动——start_kernel调用方法第5章 准备解压内核5.1 进入启动加载后结束首个启动——start标签5.2 BSS系统域初始化——not_relocated标签5.3 激活缓存——cache_on标签5.4 页目录项初始化——__setup_mmu标签5.5 指令缓存激活及缓存策略适用——__common_mmu_cache_on标签第6章 从压缩的内核zImage还原内核映像6.1 解压内核并避免覆写——wont_overwrite、decompress_kernel标签6.2 调用已解压内核——call_kernel标签6.3 缓存清理及清除——cache_clean_flush标签6.4 缓存禁用——cache_off标签第7章 调用start_kernel7.1 初始化指向——stext标签7.2 处理器信息搜寻——__look_processor_type7.2.1 __lookup_processor_type标签7.2.2 __proc_info_begin和__proc_info_end中保存的信息7.2.3 在MMU禁用状态下将虚拟地址转换为物理地址7.2.4 查找proc_info_list结构体并比较处理器信息7.3 搜寻我的机型——__lookup_machine_type7.3.1 __lookup_machine_type标签7.3.2 保存在__arch_info_begin和__arch_info_end中的machine_desc信息及访问路径7.3.3 查找machine_desc结构体并比较机器信息7.4 源自启动加载项的atags——__vet_atags标签7.5 对虚拟内存进行基础创建——__create_page_tables标签7.6 设置核心(core)——v6_setup标签7.7 打开MMU并使用虚拟地址——__enable_mmu/__turn_mmu_on标签7.8 跳转至start_kernel——__mmap_switched 标签第三部分 内核的执行——内核的起始与结束位置第8章 start_setup_processor_id~lock_kernel8.1 smp_setup_processor_id、lockdep_init、debug_objects_early_init8.1.1 smp_setup_processor_id8.1.2 lockdep_init8.1.3 debug_objects_early_init8.2 栈溢出感应——__boot_init_stack_canary8.3 初始化提供进程集成方法的cgroup——__cgroup_init_early8.3.1 cgroupfs_root和cgroup的关联初始化——init_cgroup_root8.3.2 初始化子系统——cgroup_init_subsys8.4 禁用IRQ8.5 early_boot_irqs_off、early_init_irq_lock_class8.6 大内核锁——lock_kernel第9章 注册针对时钟事件的处理器9.1 函数的声明和定义——tick_init9.2 注册处理事件的处理器——_clockevents_register_notifier9.2.1 为clockevents_lock添加自旋锁9.2.2 clockevents_chain生成原理9.2.3 在clockevents_chain中注册tick_notifier的方法9.2.4 对clockevents_lock解除自旋锁的原理第10章 在CPU位图中注册当前运行CPU/初始化HIGHMEM管理10.1 在包含热插拔信息的位图上添加执行init_task的CPU——boot_cpu_init10.2 管理高端内存——page_address_init第11章 整体指向——setup_arch第12章 unwind_init~early_trap_init12.1 栈回溯——unwind_init12.2 求出包含机器信息的machine_desc结构体——setup_machine12.3 处理ATAG信息——setup_arch12.4 处理启动参数——parse_cmdline12.5 构建源代码树——request_standard_resources12.6 初始化cpu possible位图——smp_init_cpus12.7 用栈指定各ARM异常模式——cpu_init12.8 初始化以处理异常——early_trap_init12.9 查看中断处理器函数12.9.1 调用IRQ处理器——asm_do_IRQ12.9.2 返回中断之前——ret_to_user标签第13章 设置处理器—— setup_processor13.1 查看setup_processor结构13.2 查找CPU ID——read_cpuid_id13.3 查找处理器信息——lookup_processor_type13.4 查找处理器结构信息——cpu_architecture13.5 查找处理器缓存类型_cacheid_init13.6 调用处理器初始化函数——cpu_proc_init第14章 准备内存分页—— paging_init14.1 查看paging_init的整体结构14.2 设置内存类型表——build_mem_type_table14.3 检验内存信息——sanity_check_meminfo14.4 准备页表——prepare_page_table14.4.1 prepare_page_table14.4.2 Linux的分页结构14.4.3 求出页目录项14.4.4 pmd_clear14.5 设备区域映射准备——devicemaps_init14.6 准备使用高端内存——kmap_init14.7 初始化零页14.7.1 分配内存——__alloc_bootmem_nopanic14.7.2 在指定节点使用fallback分配内存——alloc_bootmem_core14.7.3 将虚拟地址变换为page结构体——virt_to_page14.8 保持数据缓存一致性——flush_dcache_page第15章 在启动时初始化内存分配器15.1 bootmem函数流和数据结构15.2 查看bootmem_init结构15.3 查找虚拟内存盘位置——check_initrd15.4 将节点的BANK信息反映到页目录——bootmem_init_node15.4.1 map_memory_bank15.4.2 bootmem_bootmap_pages15.4.3 find_bootmap_pfn15.4.4 node_set_online15.4.5 NODE_DATA宏15.4.6 init_bootmem_node15.4.7 free_bootmem_node15.4.8 reserve_bootmem_node15.5 排除0号节点——reserve_node_zero15.6 排除虚拟内存盘节点——bootmem_reserve_initrd15.7 设置为无可用页——bootmem_free_node15.8 初始化free_area区域15.8.1 free_area结构体15.8.2 free_area_init_node15.8.3 free_area_init_core15.8.4 init_currently_empty_zone15.8.5 memmap_init第16章 mm_init_owner~preempt_disable16.1 设置内存拥有者——mm_init_owner16.2 保存命令行——setup_command_line16.3 初始化per-cpu数据——setup_per_cpu_areas16.4 求CPU个数——setup_nr_cpu_ids16.5 注册SMP上的启动进程——smp_prepare_boot_cpu16.6 初始化数据结构以使用调度程序——sched_init16.6.1 为集合调度中使用的task_group的sched_entity结构体和runqueue结构体分配内存16.6.2 初始化root_domain、rt_bandwidth、task_group相关数据结构16.6.3 初始化系统上所有可用CPU的就绪队列16.6.4 初始化当前任务的调度相关值与注册针对负载均衡的中断处理器16.7 允许内核抢占和阻止抢占——preempt_enable/preempt_disable第17章 构建借用内存的后台17.1 在build_all_zonelists中操作的一些数据结构17.2 查看build_all_zonelists结构17.3 决定zone的列表方式——set_zonelist_order17.4 构建备用列表和备用位图——__build_all_zonelists17.4.1 build_zonelists17.4.2 build_zonelist_in_node_order17.4.3 build_zonelists_in_zone_order17.4.4 build_thisnode_zonelists17.4.5 build_zonelists_cache17.5 输出备用列表信息——mminit_verify_zonelist17.6 指定处理页分配请求的节点——cpuset_init_current_mems_allowed17.7 求空页数——nr_free_pagecache_pages17.8 页移动性第18章 page_alloc_init~pidhash_init18.1 处理用于热插拔CPU的页——page_alloc_init18.2 处理console参数——parse_early_param18.3 处理特殊参数——parse_args18.4 确认中断处理是否激活——irqs_disable18.5 内核异常列表定义——sort_main_extable18.6 初始化RCU机制——rcu_init18.7 准备使用IRQ——early_irq_init18.8 初始化中断——init_IRQ18.9 构建迅速搜寻进程信息的结构——pidhash_init第19章 init_timers~page_cgroup _init19.1 初始化计时器——init_timers19.1.1 timers_cpu_notify19.1.2 register_cpu_notifier19.1.3 open_softirq19.2 初始化高分辨率计时器——hrtimers_init19.3 注册softirq的回调函数——softirq_init19.4 设置xtime——timekeeping_init19.5 初始化硬件计时器——time_init19.6 初始化时钟时间——sched_clock_init19.7 激活CPU的中断处理——local_irq_enable19.8 检测用作根文件系统的init虚拟内存盘19.9 初始化以分配动态内存——vmalloc_init19.10 预先初始化目录项和索引节点缓存——vfs_caches_init_early19.11 初始化cpuset子系统——cpuset_init_early19.12 初始化内存子系统——page_cgroup_init第20章 终止bootmem分配器并替换为伙伴系统20.1 mem_init函数的调用关系及其与数据结构的相互关系20.2 查看mem_init结构20.3 记录到不存在的内存位图——free_unused_memmap_node20.4 移交至普通空白页伙伴系统——free_all_bootmem_node20.4.1 register_page_bootmem_info_node20.4.2 free_all_bootmem_core20.4.3 __free_pages_bootmem20.4.4 __free_pages20.4.5 free_hot_cold_page20.4.6 __free_pages_ok20.5 移交到高端内存空白页伙伴系统——free_area第21章 初始化以支持CPU热插拔21.1 初始化cpu_hotplug成员变量——cpu_hotplug_init21.2 CPU的联机→脱机转换处理第22章 激活slab内存分配器——kmem_cache_init22.1 slab分配器的概念及结构体22.2 slab分配器的重要结构体——kmem_cache和kmem_list322.3 查看kmem_cache_init结构22.4 初始化initkmem_list3〔〕、cache_cache、nodelist〔〕22.5 连接kmem_list3数组并决定cache压缩时间——set_up_list3s22.6 求出用于cache扩展/压缩的页顺序——cache_estimate22.7 malloc_sizes和cache_names22.8 生成cache——kmem_cache_create22.8.1 kmem_cache_zalloc22.8.2 calculate_slab_order22.8.3 setup_cpu_cache22.8.4 enable_cpucache22.9 生成arraycache_init,kmem_list3 cache22.10 用kmalloc函数分配的内存替代静态分配的内存第23章 kmem_trace_init~security_init23.1 生成ID alloccator缓存——idr_init_cache23.2 初始化pageset——setup_per_cpu_pageset23.3 指定交叉节点——numa_policy_init23.4 结束计时器初始化——late_time_init23.5 测定BogoMIPS——calibrate_delay23.6 制作位图以分配进程识别符(ID)——pidmap_init23.7 初始化优先树的数据结构——prio_tree_init23.8 生成anon_vma slab缓存——anon_vma_init23.9 为对象的每个用户赋予资格——cred_init23.10 初始化数据结构以使用fork函数——fork_init23.11 初始化生成进程的缓存——proc_caches_init23.12 初始化缓冲缓存——buffer_init23.13 准备密钥——key_init第24章 初始化VFS中使用的多种缓存——vfs_cache_init第25章 radix_tree_init~ftrace_init25.1 基数树相关数据结构初始化——radix_tree_init25.2 准备使用信号——signals_init25.3 注册并挂载proc文件系统——proc_root_init25.4 注册未能初始化的子系统——cgroup_init25.5 重置top_cpuset并注册cpuset文件系统——cpuset_init25.6 初始化任务统计信息接口——delayacct_init25.7 为管理延迟信息做准备——delayacct_init25.7.1 延迟审计25.7.2 delayacct_init25.7.3 task_delay_info结构体和delayacct_tsk_init25.8 检查写缓冲一致性——check_bugs第26章 同步内存与后备存储——page write back26.1 页回写机制26.2 激活页回写——pdflush_init26.3 pdflush线程26.4 指定页回写函数26.5 周期性页回写和强制性页回写回调函数调用方法26.5.1 周期性页回写函数——wb_kupdate26.5.2 强制性页回写函数——background_writeout26.6 初始化周期性页回写第27章 查看启动内核的最终函数结构——rest_init第28章 生成执行函数的内核线程——kernel_thread28.1 查看kernel_thread结构28.2 生成处理器的网关——do_fork28.3 复制父进程——copy_process第29章 唤醒新生成的任务29.1 查看wake_up_new_task结构29.2 获取任务的就绪队列——task_rq_lock29.3 改善任务的优先顺序——effective_prio第30章 准备使用内核30.1 将当前进程转移到其他CPU——sched_init_smp30.2 结束系统整体初始化——do_basic_setup30.2.1 生成执行rcu_sched_grace_period的线程——rcu_init_sched30.2.2 生成events工作队列——init_workqueues30.2.3 初始化cpuset子系统的top_cpuset——cpuset_init_smp30.2.4 生成khelper工作队列——usermodehelper_init30.2.5 初始化Linux的设备模型——driver_init30.2.6 在proc文件系统注册irq信息——init_irq_proc30.2.7 调用内核未知子系统——do_initcalls30.3 为初始化之后的操作做准备——init_post第31章 内核线程守护进程31.1 内核线程守护进程——kthreadd31.2 忽略信号——ignore_signals31.3 设置nice值——set_user_nice31.4 搜索执行任务的CPU——set_cpus_allowed_prt31.5 搜索包含列表的实际结构体位置——list_entry31.6 生成内核线程——create_kthread第32章 find_task_by_pid_ns~cpu_idle32.1 用PID搜索任务——find_task_by_pid_ns32.2 解除BKL——unlock_kernel32.3 将调度类变更为idle——init_idle_bootup_task32.4 RCU机制激活完成通知——rcu_scheduler_starting32.5 激活内核抢占——preempt_enable_no_resched32.6 执行进程调度表——schedule32.7 Linux启动万里长征的终点——cpu_idle附录附录A 汇编语言、gas关键词总结附录B 内核分析常见API附录C 浅谈ext2文件系统附录D Linux线程模型附录E 链接器脚本文件结构后记索引本书对启动Linux内核过程中调用的代码进行分析,并着重讲解Linux是怎样运行的,以及Linux运行时哪些部分需要初始化等内容。 本章在分析之前,先讲解两个内容:第一,Linux是由林纳斯发起的当前最成功的操作系统之一;第二,Linux内核是由多个子系统构成的一个单内核。最后,了解本书中分析的内核版本和内核3.2版之间的差异。在这一过程中大家会发现,内核从2.4版升级到2.6版的过程中,结构上并没有发生太大变化。所以本书并没有把重点放在内核3.2版上,但对其的讲解有助于分析最新版的内核。1.1 内核的诞生、作用以及内部结构1.1.1 Linus创造的LinuxLinux 是由赫尔辛基大学的研究生林纳斯•托瓦兹(Linus Torvalds)在1991年发布的操作系统。林纳斯在大学期间对MINIX的许可授权政策感到不满,从而打算开发Linux。虽然开发初期是以MINIX为基础的,但进展到一定程度后,他在运行Linux内核的Linux系统上进行了开发。之后,与MINIX相关的组件全部被GNU应用程序取代 。由于从GNU阵营中得到了许多支持和无数内核黑客的贡献,Linux成为全世界应用最广、最为成功的开放源操作系统。1.1.2 由多种子系统集成运行的单内核Linux内核由许多子系统构成。图1-1表示各子系统之间的关系,请通过该图了解各子系统的作用。图1-1 Linux子系统结构结构依赖代码无论为何种结构类型,Linux均提供相同服务。但在其底层,每个结构都有需要另行控制的部分。这些部分是指用于CPU、MMU以及机载(on board)状态的低级(low-level)驱动程序,而且这些代码均位于arch目录下。设备驱动程序我们使用的电脑中,有很多周边设备(LCD、按钮、蓝牙、Wi-Fi等)通过多种方式(J2C、SCSI、EIDE)进行通信。设备驱动程序是指为这些高层设备制订的代码,位于drivers目录下。Linux内核中有一半以上是设备驱动程序代码,Linux通常最先封装最新设备。进程管理执行进程前必须先分配CPU资源。同时执行多个进程时,根据制定的政策公平分配资源,并且要管理进程的生成及状态转移的过程。进程管理就是执行这些任务的子系统,位于kernel目录下。内存管理与CPU同样重要的系统资源是内存。内存管理子系统负责内存分配、释放及共享,其相关代码位于mm目录下。虚拟文件系统虚拟文件系统在Linux中是个很有意思的部分。该系统将多种文件系统抽象化,从而提供共通的接口。因此,我们能够在Linux中使用相同的文件操作访问多个文件系统或设备。网络子系统网络子系统就像TCP/IP通信协议和套接字(SOCKET)接口那样,对网络装置提供抽象化概念,可通过一致的方法使用多种网络装置。系统调用接口提供接口,以在用户空间级调用已在内核中实现的特定功能。根据结构的不同,其实现方法可能有所不同。其相关代码位于linux/kernel或linux/arch目录下。补充知识点 内核结构的区分:单内核(宏内核)与微内核单内核与微内核是具有代表性的内核结构。其特征如下。单内核——所有内核服务均在内核地址空间中存在并运行。直接调出内核服务。微内核——内核服务中一部分位于用户空间。利用消息传送方式调用内核服务。内核结构的区分标准是,所有内核服务是否集成在内核地址空间运行。由于2.6版Linux内核具有支持模块的模块化内核(Modular kernel)的特性,偶尔会让人产生误解。但模块也是在内核地址空间中运行的,因此可将Linux内核视作单内核(请参考图1-2)。

赞(0)
未经允许不得转载:小苏子图书 » ARM Linux内核源码剖析 内容简介