Linux内核学习之四--进程、进程调度、系统调用、proc文件系统和内核异常分析

一、Linux进程控制(内核角度)
1》定义
程序:程序是存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体。
进程:是一个执行中的程序,它是动态的实体。

2》进程四要素
a)有一段程序供其执行。
b)有进程专用的内核空间堆栈。
c)在内核中有一个task_struct数据结构。PCB:process control block,即task_struct
d)有独立的用户空间堆栈。
  有共享的--用户线程   完全没有用户空间--内核线程

3》进程描述
Linux中进程和线程都用struct task_struct结构表示
a)pid_t pid:进程号
volatile long state:进程状态
*TASK_RUNNING:就绪和执行都是该状态
*TASK_INTERRUPTIBLE:可中断的阻塞,即可以被信号唤醒
*TASK_UNINTERRUPTIBLE 不可以被信号唤醒 但是可以通过函数强制唤醒
TASK_STOPPED:暂时中止,收到SIGSTOP SIGTSTP即为该状态,其它进程通过signal或中断唤醒。
TASK_KILLABLE:阻塞的一种,类似于TASK_UNINTERRUPTIBLE,但是可以被SIGKILL唤醒
TASK_TRACED:正处于被调试的进程 gdb 单步停下来时即该状态
TASK_DEAD:进程退出时(调用do_exit),state字段被设置为该状态

b)int exit_state 进程退出时的状态
EXIT_ZOMBILE僵死进程,表示进程的执行被终止,但是父进程还没有发布waitpid()系统调用来收集有关死亡

的进程信息。【父进程 通知 内核 回收资源】
EXIT_DEAD僵死撤销状态

c)struct mm_struct *mm进程用户空间描述指针,内核线程该项为空
unsigned int policy 该进程的调度策略
d)int prio等等

task_struct位置:
1》2.4
两个连续物理页面的底部1KB,内核空间堆栈7KB,大的数组会导致栈溢出
2》2.6
thread_info structure包含一个task指针,指向task_struct结构

当前运行的进程
current指针指向当前正在运行的进程的task_struct

进程创建:
用户空间   内 核 空 间
fork()----sys_fork()-----do_fork()
vfork()---sys_vfork()----do_fork()
          sys_clone()----do_fork()
          kernel_thread--do_fork()
          copy_process---do_fork()

销毁
exit()---sys_exit--------do_exit()
         fatal signals---do_exit()


二、Linux进程调度
(较复杂 中等了解)
从就绪的进程中选出最适合的一个来执行
知识点:调度策略  调度时机  调度步骤
1》调度策略:最合适即为策略
SCHED_NORMAL(SCHED_OTHER)
SCHED_FIFO
SCHED_RR
SCHED_BATCH:
SCHED_IDLE

可以划分为两大类:
CFS调度类:在kernel/sched_fair.c中实现,用于SCHED_NORMAL SCHED_NORMAL SCHED_BATCH
           CFS:Complete Fire Scheduler 完全公平调度类
实时调度类 在kernel/sched_rt.c中实现 用于SCHED_RR和SCHED_FIFO

一个进程只能遵循一个调度策略,应用程序创建时默认SCHED_NORMAL,不过是可以修改的

调度类:struct sched_class,其中包含一个重要的函数指针pick_next_task,选择下一个要运行的进程

2》调度时机
a)主动式 直接调用schedule(),需要等待资源而暂时停止运行时,会把状态置为挂起,主动请求调度 让出cpu
主动放弃cpu例子:
current->state = TASK_INTERRUPTIBLE;
schedule();

b)被动式(抢占)
用户抢占 2.4 2.6支持
内核抢占 2.6支持

用户抢占发生在:
*从系统调用返回用户空间
*从中断处理程序返回用户空间

内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule()被调用,此时就会发生用户

抢占

某些特例下不允许内核抢占:
中断处理 中断上下文处理 自选所 读写锁 正在执行调度

内核使用了preempt_count 内核抢占计数器 不能被抢占时加1,从以上状态退出时减1

内核抢占发生在:
*中断处理程序完成 返回内核空间之前
*当内核代码再一次具有可抢占性的时候 如解锁及时能软中断

调度标志:need_resched

2》调度步骤
 a.清理当前运行中的进程
 b.选择下一个要运行的进程 pick_next_task 重要环节
 c.设置新进程的运行环境
 d.进程上下文切换

分析pick_next_task


三、Linux系统调用
read write close open 等等
系统调用:Linux内核中设置了一组用于实现各种系统功能的子程序。

系统调用和普通函数的区别:
系统调用:实现在内核空间,运行于内核态
普通函数:由函数库或用户自己提供,运行于用户态

Linux库函数对系统调用进行了一定的封装,这些库函数于系统调用关系密切

系统调用个数:
arch/arm/include/asm/unistd.h

系统调用工作原理
使用系统调用时,进行现用适当的值填充寄存器,然后调用一个特殊的指令,
这个指令会让用户程序跳转到一个事先定义好的内核中的一个位置:
x86 0x80
ARM SWI

ENTYR(vector_swi)<arch/arm/kernel/enty-common.S>
数字和sys_call_table对比 找出相应的函数

事先系统调用的三个步骤:
1>添加新的内核函数
2>更新unistd.h
3>根据系统调用表 更新 call.S

四、Proc文件系统
Proc文件系统是一种在用户态检查内核状态的机制。proc文件系统提供了一条途径。
/proc/目录下面有诸多文件

例如 内核中断发生了多少次
a)每个文件都规定了严格的权限
b)文本编辑程序查看
c)不仅有文件 也可以有子目录
d)可以自己编写程序添加一个/proc/下的文件
e)文件的内容都是动态创建的,并不存在于磁盘上

数据结构
struct proc_dir_entry
read
write

a)使用create_proc_entry函数创建proc文件
b)proc_mkdir创建proc目录下的目录
c)使用remove_proc_entry删除文件或目录

读写回调函数:
read_proc
write_proc

proc文件 不去读它的时候 里面没有内容,只有在去读的时候,才会有东西
显示什么 在read函数中控制


五、内核异常分析
Oops信息
1》查看错误原因
2》调用栈(对照反汇编代码)
3》寄存器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值