内存管理子系统
1.作用:将虚拟内存映射到物理内存
2.方法:每一个进程都有2^x大小的虚拟内存(x为机器字长位)以下x=32
ar3+页目录(10位)+页表(10位)+页偏移指针(12位)映射到物理 内存
3.虚拟内存分布:0-3G为用户空间,3-4G为内核空间,直接映射:3-3G+896M, 直接映射对应的物理内存,物理地址就是3G后面的地址。vmalloc区:既可 以访问低端直接映射区,也可以访问高端映射区。永久映射区:只可以访问 高端物理地址。固定映射区:寄存器地址。
4.内存申请:用户空间应用:malloc,vmalloc申请一段内存时,分配的是虚拟地址,为与物理地址建立联系,只有当去访问这个虚拟地址,系统才会通过缺页异常的方式与物理内存建立实在的联系。
内核程序:Kmalloc,申请空间时,与物理空间直接建立联系。预先分配的,在一开始就有分配一个物理内存池,使用函数的时候,将内存池中的内存拿出来建立联系。
5.虚拟内存,物理内存,磁盘的关系:虚拟内存先被应用分配,当被访问时才与物理内存建立联系,每一个进程都有4G的虚拟内存,但是他们访问的是同一个物理内存(DRAM),当一个虚拟内存首次被建立联系时,①发现对应的物理内存被占用,则进行缺页异常,重新找一块空闲的内存进行联系。②当发现物理内存已满时候,将相应的物理内存页写入磁盘(硬盘),将物理内存进行覆盖写入。
进程管理子系统
- 进程的定义:有独立的4G空间的运行程序
- 三种状态:就绪,阻塞,运行,只有就绪态能切换到运行,阻塞得先到就绪
- 被管理的方式: task_struct 数据结构(进程控制块),每一个进程对应一个这样的结构体,里面存储了进程的所有信息。比如进程ID啥的
- 进程调度分为:调度策略,调度时机,调度步骤
调度策略:SCHED_NORMAL(SCHED_OTHER): 普通的分时进程

SCHED_FIFO : 先入先出的实时进程
SCHED_RR : 时间片轮转的实时进程
SCHED_RR : 时间片轮转的实时进程
SCHED_BATCH: 批处理进程
SCHED_IDLE: 只在系统空闲时才能够被调度执行
调度时机:即函数schedule()什么时候被调度
调度步骤:即内核函数schedule()做了什么
1). 清理当前运行中的进程
2). 选择下一 个要运行的进程
3). 设置新进程的运行环境
4). 进程上下文切换
内核链表
1.内核链表只对指针域进行插入删除和查找操作。如果需要访问节点的内容,需要将节点的指针域转换成节点的地址,然后再访问其成员变量。
内核中用来管理内核链表的节点域。
struct list_head
{ struct list_head *next, *prev; };
INIT_LIST_HEAD:创建链表
list_add :在链表头插入节点
list_add_tail :在链表尾插入节点
list_del: : 删除节点
list_entry :取出节点
list_for_each:遍历链表
内核调用
- 在一个内核文件中实现函数功能sys_pk。只要是内核C文件就可以。
- 在对应的arch/arm/kernel/calls.S对应位置的最后加上CALL(sys_pk)和arch/arm/include/asm/unistd.h文件对应位置的最后加上#define __NR_pk (__NR_SYSCALL_BASE+num(上一个数字加1))将函数的对应的的swi软中断的R7寄存器的函数编码注册好。这个函数编码到时候在应用层作为参数传入,就能找到对用的内核函数。重新编译烧写内核。
- 在应用层调用统一的内核函数接口,同时传入内核函数对应的函数编码。应用层就能找到对应的内核函数实现系统调用。应用层示例:
void pk()
{
__asm__ (
"ldr r7,=363 \n" //363为内核函数注册时的编号
"swi \n"
:
:
:"memory");
}
void main()
{
pk(); //此处调用pk和调用read等系统函数是一样的流程
}