读薄《Linux 内核设计与实现》(5) - 定时器、时间管理和内存管理
2016-10-23 14:00
471 查看
这篇文章是《读薄「Linux 内核设计与实现」》系列文章的第 V 篇,本文主要讲了以下问题:Linux 内核中的时间概念和时间表示,硬件时钟和定时器以及时间中断和内存管理的相关知识。
硬件为内核提供了一个系统定时器用以计算流逝的时间,它以某种频率自行触发时间中断,该频率可以通过编程预定,称作节拍率
时间的作用:
更新系统时间
更新实际时间
定期均衡运行队列(SMP)
时间片
定期统计处理器时间
系统定时器:提供了一种周期性触发中断机制
实时时钟:用来持久存放系统时间的设备
应答或重新设置系统时钟
周期性使用墙上时间更新实时时钟
调用体系结构无关的时钟例程:
更新资源消耗的统计值
执行到期的动态定时器
执行
更新墙上时间并存到 xtime 变量中
计算平均负载值
内核不支持便捷的内存分配方式
处理内存分配错误难度大
内核分配机制不能太复杂
物理页的大小取决于体系结构
page 结构体(定义于
Linux 必需处理 2 种由于硬件存在缺陷而引起的内存寻址问题:
一些硬件只能用某些特定的内存地址来执行DMA(Direct Memory Access)
一些体系结构的内存的物理寻址范围比虚拟内存大得多,导致一些内存不能总是映射到内核空间
Linux 主要使用了 4 种区:
ZONE_DMA: 该区页面用来执行 DMA
ZONE_DMA32: 用于 32 位设备执行 DMA
ZONE_NORMAL:该区页面都能正常映射
ZONE_HIGHEM:该区包含“高端内存”,这里的页不能永久映射到内核空间
page_address(struct page* page)
__get_free_pages()
alloc_page()
__get_free_page()
free_pages()
free_page()
本文的版权归作者 罗远航 所有,采用 Attribution-NonCommercial 3.0 License。任何人可以进行转载、分享,但不可在未经允许的情况下用于商业用途;转载请注明出处。感谢配合!
0x00 内核中的时间概念
内核需要管理相对时间和绝对时间硬件为内核提供了一个系统定时器用以计算流逝的时间,它以某种频率自行触发时间中断,该频率可以通过编程预定,称作节拍率
时间的作用:
更新系统时间
更新实际时间
定期均衡运行队列(SMP)
时间片
定期统计处理器时间
0x01 Linux 中的时间表示
I 节拍率(Hz)
在II jiffies
全局变量 jiffies 用来记录自系统启动以来产生的节拍的总数,定义于unsigned long timeout = jiffies + HZ / 2; /*0.5秒后超时*/ if(time_before(jiffies, timeout)){ /*没有超时,很好*/ }else{ /*超时,发生错误*/ }
0x02 硬件时钟和定时器
体系结构中提供了两种设备进行计时:系统定时器:提供了一种周期性触发中断机制
实时时钟:用来持久存放系统时间的设备
0x03 Linux 下的时钟中断
I 时钟中断处理程序做的工作
获得xtime_lock锁,对 jiffies_64 和 xtime 进行保护
应答或重新设置系统时钟
周期性使用墙上时间更新实时时钟
调用体系结构无关的时钟例程:
do_timer()
II do_timer()
jiffies + 1更新资源消耗的统计值
执行到期的动态定时器
执行
scheduler_tick()
更新墙上时间并存到 xtime 变量中
计算平均负载值
III 从用户空间获取时间
gettimeofday(): 对应系统调用sys_gettimeofday()
0x04 Linux 内存页
I 内核分配内存特点
内核使用的内存空间有限内核不支持便捷的内存分配方式
处理内存分配错误难度大
内核分配机制不能太复杂
II 页
内核以物理页为单位分配内存物理页的大小取决于体系结构
page 结构体(定义于
struct page{ unsigned long flags; //存放页的状态 atomic_t _count; //存放页的引用计数 atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual; //页的虚拟地址 }
0x05 Linux 内存区
由于硬件的限制,内核并不能对所有的页一样看待,内核需要对页进行分类,分不同区域Linux 必需处理 2 种由于硬件存在缺陷而引起的内存寻址问题:
一些硬件只能用某些特定的内存地址来执行DMA(Direct Memory Access)
一些体系结构的内存的物理寻址范围比虚拟内存大得多,导致一些内存不能总是映射到内核空间
Linux 主要使用了 4 种区:
ZONE_DMA: 该区页面用来执行 DMA
ZONE_DMA32: 用于 32 位设备执行 DMA
ZONE_NORMAL:该区页面都能正常映射
ZONE_HIGHEM:该区包含“高端内存”,这里的页不能永久映射到内核空间
0x06 内存管理提供的服务
I 获得页
alloc_pages()page_address(struct page* page)
__get_free_pages()
alloc_page()
__get_free_page()
II 获得填充为 0 的页
get_zeroed_page()III 释放页
__free_pages()free_pages()
free_page()
IV kmalloc()
用于获得以字节为单位的一块连续内存空间:void *kmalloc (size_t size, gfp_t flags)
V kfree()
该函数用于释放 kmalloc() 分配出的内存块:void kfree(const void *ptr)
VI vmalloc()
类似 kmalloc(), 但分配的内存空间不连续,释放使用 vfree()VII slab 层
即 slab 分配器,它扮演了通用数据结构缓存层的角色,是一种缓存机制本文的版权归作者 罗远航 所有,采用 Attribution-NonCommercial 3.0 License。任何人可以进行转载、分享,但不可在未经允许的情况下用于商业用途;转载请注明出处。感谢配合!
相关文章推荐
- LINUX内核设计思想之定时器和时间管理
- Linux内核设计与实现(三) linux进程管理 之 概述
- linux时间管理 之 内核定时器
- linux 内核学习之—定时器和时间管理
- Linux内核设计与实现-进程管理与进程调度
- Linux内核学习笔记八——定时器和时间管理
- 读薄「Linux 内核设计与实现」(2) - 进程管理和调度
- 每日阅读1之内核设计与实现(第三版)4.5——linux调度实现之时间记账
- Linux 内核设计与实现(第二版)1-3章(读书)
- Linux内核设计与实现——7 中断与中断处理(2)
- Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现
- [Linux内核设计与实现]Linux进程管理
- Linux Kernel Development——定时器和时间管理
- Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现
- 【转】深入剖析linux内核的定时器实现机制-动态刷新维护
- 《Linux 内核设计与实现》(LKD)第三版译者序
- linux内核设计与实现思想 – C风格的面向对象
- 一个资源管理系统的设计--解析linux的cgroup实现
- Linux基础系列-定时器与时间管理
- Linux内核设计与实现 之二 从内核出发