内核子系统及链表

内存管理子系统

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),当一个虚拟内存首次被建立联系时,①发现对应的物理内存被占用,则进行缺页异常,重新找一块空闲的内存进行联系。②当发现物理内存已满时候,将相应的物理内存页写入磁盘(硬盘),将物理内存进行覆盖写入。

 

进程管理子系统

  1. 进程的定义:有独立的4G空间的运行程序
  2. 三种状态:就绪,阻塞,运行,只有就绪态能切换到运行,阻塞得先到就绪
  3. 被管理的方式: task_struct 数据结构(进程控制块),每一个进程对应一个这样的结构体,里面存储了进程的所有信息。比如进程ID啥的
  4. 进程调度分为:调度策略,调度时机,调度步骤

调度策略: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:遍历链表

 

 

内核调用

  1. 在一个内核文件中实现函数功能sys_pk。只要是内核C文件就可以。
  2. 在对应的arch/arm/kernel/calls.S对应位置的最后加上CALL(sys_pk)和arch/arm/include/asm/unistd.h文件对应位置的最后加上#define __NR_pk  (__NR_SYSCALL_BASE+num(上一个数字加1))将函数的对应的的swi软中断的R7寄存器的函数编码注册好。这个函数编码到时候在应用层作为参数传入,就能找到对用的内核函数。重新编译烧写内核。
  3. 在应用层调用统一的内核函数接口,同时传入内核函数对应的函数编码。应用层就能找到对应的内核函数实现系统调用。应用层示例:

void pk()

{

    __asm__ (

    "ldr r7,=363 \n" //363为内核函数注册时的编号

    "swi \n"

    :

    :

    :"memory");

}

void main()

{

    pk(); //此处调用pk和调用read等系统函数是一样的流程

}

猜你喜欢

转载自blog.csdn.net/qq_43706825/article/details/103717078