1 linux内存管理
地址类型
物理地址
出现在cpu地址总线上的寻址物理内存的地址信号,是地址变换的最终结果
线性地址(虚拟地址)
在32位cpu架构下,可以表示4g的地址空间,用16进制表示就是
0x00000000到0xffffffff
逻辑地址
程序代码编译后,出现在汇编程序中的地址
地址转换
cpu将一个逻辑地址转换为物理地址:
利用段式内存管理单元,将逻辑地址转换成线性地址
再利用页式内存管理单元,将线性地址转换成物理地址
段式管理
(16位cpu)
有20位的地址线,1m的内存空间,由于寄存器只有16位,只能访问65536
个存储单元,64k
因此cpu采用了内存分段的管理模式,cpu内部加入了段寄存器,把1M的
空间分为若干个逻辑段,要求如下:
逻辑段的起始地址必须是16的倍数(最后四个二进制位必须为0)
逻辑段的最大容量最大为64k
物理地址的形成方式:
段地址是16的倍数,形式为xxxx0h,即前16位是变化的,可以只保存前
16位二进制位来保存整个段基地址,所以使用时需要用段寄存器左移补
4个0来得到实际的段地址
确定内存单元在存储器中的具体位置: 段地址+偏移量
逻辑地址=段基地址+段内偏移量
物理地址=段寄存器值*16+逻辑地址
16位cpu有四个段寄存器,程序可同时访问四个不同含义的段
cs+ip 用于代码段的访问
cs 存放程序的段基址 用这两个寄存器就可以得到一个内存物理地址
ip 指向下条要执行的指令在cs段的偏移量
ss+sp 用于堆栈段的访问 直接访问栈顶单元的内存地址
ss 指向堆栈段的基地址
sp 指向栈顶
ds+bx 用于数据段的访问
ds 值左移四位得到数据段的起始地址
bx 偏移量
es+bx 用于附加段的访问
es 值左移四位得到附加段起始地址
bx 偏移量
(32位cpu)
有两种不同的工作方式:
实模式 与16位cpu一致
保护模式 段基地址长达32位 段寄存器存放的是一个地址
(段选择器), 选择器从内存中得到一个32位的段地址
页式管理
线性地址分为固定长度的组,称为页
linux中所有段的基地址均为0,所以线性地址=逻辑地址
linux页式管理
linux2.3.29内核采用了四级页管理架构
页全局目录
页上级目录
页中间目录
页表
2 linux进程地址空间
linux采用虚拟内存管理技术,每个进程都有独立的进程地址空间,约3G
linux将4G的虚拟地址空间划分为
用户空间 从0到0xbfffffff 随进程切换发生变化
内核空间 从3G到4G
用户进程只能访问用户空间,可以通过系统调用访问内核空间
查看线性地址
px aux
cat /proc/<pid>/maps
内核内存分配
应用程序中 malloc
linux内核中 kmalloc
函数原型:
#include<linux/slab.h>
void *kmalloc(size_t size,int flags)
size 要分配的内存大小
flags 分配标志,控制kmalloc的行为
GFP_AUTOMIC 在进程上下文之外的代码(包括中断处理)中分配内存,不睡眠
GFP_KERNEL 进程上下文中的分配,可能睡眠(16M-896M)
__GFP_DMA 分配能够DMA的内存区(物理地址在16m以下的页帧)
__GFP_HIGHMEM 分配的内存位于高端内存(896以上)
按页分配
get_zeroed_page(unsigned int flags)//返回指向新页面的指针,页面清零
__get_free_page(unsigned int flags)//同上,但不清零
__get_free_pages(unsigned int flags,unsigned int order)
//分配若干个连续的页面,返回指向该内存区域的指什,不清零
释放内存
void free_page(unsigned long addr)
void free_pages(unsigned long addr,unsigned long order)
3 linux内核地址空间
内核空间是由内核负责映射,不会随进程改变发生变化
物理内存为896M以上的为高端内 存
内核空间分布:
(3G开始)
直接映射区(direct memory region) 896M
8M
动态映射区(vmalloc region)
8k
KMAP区4M
固定映射区4M
4k
(4G结束)
-----------------------------------------
直接映射区 从3G开始,最大896M的线性地址区间
线性地址=3G+物理地址
动态映射区 地址由内核函数vmalloc来进行划分,线线空间连续,物理空间不
一定
永久内存映射区(PKMap region)对于896m以上的高端内存
访问方法:
1 alloc_page(__GFP_HIGHMEM)分配高端内存页
2 kmap函数将分配到的高端内存映射到该区域
固定映射区(fixing mapping region)
4 linux内核链表
链表的数据结构: 数据域和指针域
定义如下:
sturct list_head{
struct list_head *next,*prev;
};
内核链表为双向循环链表
链表的操作主要有:
/*初始化链表头*/
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
/*插入节点*/
/**
* 节点前插入
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head
*head)
{
__list_add(new, head, head->next);
}
/**
*节点尾插入
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct
list_head *head)
{
__list_add(new, head->prev, head);
}
/*删除节点*/
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the
entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/*提取数据结构*/
/**
* list_entry - get the struct for this entry
* @ptr:the &struct list_head pointer.
* @type:the type of the struct this is embedded in.
* @member:the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/* 遍历 */
/**
* list_for_each-iterate over a list
* @pos:the &struct list_head to use as a loop cursor.
* @head:the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
5 linux内核定时器
度量时间差
时钟中断 由系统的定时硬件以周期性的时间间隔产生,这个间隔由内核跟据hz来
确定,hz与体系结构无关,可配置(50-1200),x86平台默认为1000
时钟中断发生后,全局变量jiffies(unsigned long)会加1,驱动程序常
利用其来计算不同事件的时间间隔
内核定时器 (双向链表)
用于控制某个函数(定时器处理函数)在未来的某个特定时间执行(只执行一次)
struct timer_list{
struct list_head entry //内核使用
unsigned long expires //超时的jiffies的值
void (*function)(unsigned long) 超时处理函数
unsigned long data //超时处理函数参数
struct tvec_base *base //内核使用
};
/*初始化定时器队列*/
void init_timer(struct timer_list *timer);
/*启动定时器*/
void add_timer(struct timer_list *timer);
/*定时器超时前将其删除*/
void del_timer(struct timer_list *timer);
示例代码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <asm/uaccass.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Retacn Yue");
MODULE_DESCRIPTION("timer module");
MODULE_ALIAS("timer module");
sturct timer_list timer;
void timer_function(int para){
prink("timer expired and para is %d\n",para);
}
int timer_init(){
/*初始化定时器*/
init_timer(&timer);
timer.data=5; /*超时处理函数参数*/
timer.expires=jiffies+(20*HZ); /*超时jiffies的值*/
timer.function=timer_function; /*超时处理函数*/
/*启动定时器*/
add_timer(&timer);
return 0;
}
void timer_exit(){
del_timer(&timer);
}
module_init(timer_init);
module_exit(timer_exit);
- 浏览: 263360 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (303)
- c (31)
- c++ (16)
- java (18)
- c# (1)
- python (3)
- java web (6)
- oracle (7)
- sqlserver (2)
- mysql (2)
- android (24)
- android系统 (15)
- android多媒体部分 (15)
- android游戏 (12)
- linux (26)
- javaScript (1)
- ajax (1)
- node JS (2)
- html (5)
- apache (3)
- jboss (1)
- weblogic (0)
- 通信协议 (10)
- 云计算 (1)
- 分布式 (5)
- ejb (1)
- webservice (5)
- 设计模式 (16)
- JNI (6)
- swing (13)
- 版本控制 (1)
- UML (1)
- xml (4)
- spring (5)
- hibernate (5)
- struts1 (3)
- struts2 (4)
- ibatis (0)
- tomcat (2)
- 心得体会 (1)
- css (1)
- 嵌入式 (41)
- arm体系结构 (10)
发表评论
-
u-boot Makefile 文件分析
2013-06-01 21:44 2430Makefile文件分析 # #(C)Copyri ... -
uboot start.S文件分析
2013-06-03 22:18 1326U-boot第一个开始文件arch\arm\cpu\arm1 ... -
u-boot mkconfig文件分析
2013-05-31 21:29 1140Mkconfig文件分析 #!/bin/ ... -
链接地址学习笔记
2013-05-05 12:40 1287链接地址 启动过程 示例代码如下: ... -
DDR学习笔记
2013-05-11 14:19 1041DDR 15条地址线32k 128M*2(20)=2(2 ... -
nand flash学习笔记一
2013-05-13 21:05 962Nandflash 原理图上有data0-data7 ... -
openJTAG学习笔记一
2013-05-22 21:45 2184安装软件 光盘Windows\install目录下的 01.O ... -
linux进程管理学习笔记
2013-03-28 20:57 1368linux 进程管理 1 linux进程控制 进程的四个要素: ... -
字符设备驱动程序学习笔记一
2013-04-01 21:55 890linux 驱动程序 字符设备驱动程序 网络接口驱动程序 块设 ... -
字符设备驱动程序学习笔记二
2013-04-04 10:29 755字符驱动程序 1 设备号 字符设备通过字符设备文件来存取 ls ... -
字符设备驱动程序学习笔记三
2013-04-04 14:03 790memdev.h文件示例代码如下: #ifndef _MEM ... -
字符设备驱动程序学习笔记四
2013-04-05 11:12 590竟争与互斥 程序调试 1 ... -
GPIO学习笔记
2013-04-14 19:50 814用汇编点亮一个led 1看原理图GPK4=0,led亮G ... -
系统时钟学习笔记
2013-05-04 21:59 83812m晶振----->pll------>cpu ... -
UART学习笔记
2013-05-04 22:00 1168串口(UART) DIV_VAL=(PCLK/(bpsx1 ... -
嵌入式linux系统学习笔记
2013-03-06 21:39 974嵌入式linux内核制作 1 清除原有配置文件与中间文件 x8 ... -
原理图学习笔记一
2013-02-17 22:24 425画个草图也挺过瘾 -
进程间通信学习笔记一(管道通信)
2013-02-01 20:08 1419进程间通信(ipc) 应用场景: 数据传输 资源共享 通知事件 ... -
进程间通信学习笔记二(信号通信)
2013-02-16 21:39 795信号通信 用户按某些键时,产生信号 硬件异常产生信号 进程用k ... -
进程间通信学习笔记三(共享内存通信)
2013-02-16 21:40 609共享内存通信 被多个进程共享的一部分物理内存,是进程间共享数据 ...
相关推荐
我不可能完全理解LINUX内存管理的精髓,肯定有很多地方理解错误。希望大 家能够指正,以便提高,谢谢。 学习方法: 可能您第一次阅读的时候很多地方都不理解,不用担心。那您可能需要阅读一些 文件系统的知识。 或者...
《深入理解LINUX内存管理》学习笔记a.PDF
Linux内存管理笔记详细介绍了Linux操作系统内核中内存管理机制的关键知识点,下面将依次对这些知识点进行详细说明: 存储器的层次结构:计算机系统采用分层的存储子系统以在存储容量、访问速度、成本效益之间取得...
《深入理解LINUX内存管理》学习笔记c.PDF
《深入理解LINUX内存管理》学习笔记b.PDF
在《深入理解Linux内存管理》的学习笔记中,我们将会探讨以下几个关键概念: 1. **内存区域(Memory Regions)**:Linux将内存划分为不同的区域,如保留区(Reserved)、初始化数据区(Initialized Data)、未初始...
最后,"**深入理解LINUX内存管理学习笔记**"这份文档将带你深入了解Linux内核的内存管理机制,包括物理内存、虚拟内存、页面分配和回收、交换机制等。理解这些概念有助于优化你的程序性能,特别是在处理大量数据或高...
Linux内存在操作系统中扮演着至关重要的角色,它...提供的“内存管理.ppt”可能包含更详细的讲解和实例,而“www.pudn.com.txt”可能是相关资料链接或笔记,进一步深入学习这些内容,将有助于掌握Linux内存管理的精髓。
在Linux操作系统的学习中,掌握命令行的使用是至关重要的。...总的来说,Linux学习笔记是一个全面了解和掌握Linux系统操作的基础教程,涵盖了从基本命令到高级管理的诸多方面,对提升Linux技能有很大帮助。
本系列涵盖了"深入理解Linux内存管理"、"Linux虚拟内存"以及相关的读书笔记,为那些希望深入了解Linux内存机制的读者提供了宝贵的资料。下面将详细阐述这些主题的主要知识点。 首先,我们来探讨"深入理解Linux内存...
Linux内核提供了进程管理、内存管理、文件系统、网络协议栈等核心功能,同时支持多种硬件平台,包括我们接下来要讨论的ARM架构。 ARM(Advanced RISC Machines)是一种微处理器架构,以其低功耗和高性能在嵌入式...
Linux 嵌入式学习笔记主要涵盖了Linux操作系统的基础知识以及C语言编程的相关内容。下面将对这些知识点进行详细的解析。 1. Linux基础操作: - 登录:在Linux系统中,用户通过`用户名:密码`的方式登录系统。 - ...
韩顺平 Linux 学习笔记 本学习笔记涵盖了 Linux 的基础知识、Samba 服务的搭建、Web 项目的开发和发布等内容。学习笔记分为多个阶段,从基础的 Linux 平台开发到高级的 Unix 环境编程,并涉及到 Linux 应用系统开发...
Linux 学习笔记分享 (Linux 入门绝佳) Linux 是一个开源的操作系统,它的目录架构是非常重要的概念。在 Linux 中,目录架构是按照 FHS(Filesystem Hierarchy Standard)标准来组织的。下面是 Linux 中一些重要的...
这份“Linux0.11 内核学习笔记”详细解读了这个早期内核的结构、工作原理以及相关的编程技术。下面,我们将深入探讨其中的关键知识点。 一、内核架构 Linux 0.11内核采用单内核设计,所有的系统服务都集中在一个可...
Linux驱动学习笔记主要涵盖的是与Linux操作系统内核交互的程序设计,这在系统开发和设备管理中至关重要。Linux驱动程序是连接硬件设备和操作系统之间的桥梁,使得操作系统能够控制和利用硬件资源。以下是对这些文件...