第六章 进程 总结
来源:互联网 发布:网络交易管理办法解读 编辑:程序博客网 时间:2024/05/16 08:19
一、各个程序的作用
f程序,进程主体
g加入系统调用
h加入时间
i进程调度
三、下面分析f程序
1.关键结构体
[1]任务结构体
堆栈大小,任务名,任务函数
typedef void (*t_pf_task) ();
typedef struct s_task{
t_pf_task initial_eip; //TestA,TestB,TestC
int stacksize; //0x8000,0x8000,0x8000
char name[32]; //"TestA","TestB","TestC"
}TASK;
[2]每个进程的结构体
每个进程有TSS,ldt选择子,2个LDT,pid和pidname
typedef struct s_proc{
STACK_FRAME regs;
t_16 ldt_sel;
DESCRIPTOR ldts[LDT_SIZE]; //LDT_SIZE=2,DESCRIPTOR是8字节的描述符
t_32 pid;
char p_name[16];
}PROCESS;
typedef structs_stackframe { /* proc_ptrpoints here ↑ Low */
t_32 gs; /*┓ │ */+0
t_32 fs; /*┃ │ */+4
t_32 es; /*┃ │ */+8
t_32 ds; /*┃ │ */+12
t_32 edi; /*┃ │ */+16
t_32 esi; /*┣ pushed by save() │ */+20
t_32 ebp; /* ┃ │ */+24
t_32 kernel_esp; /* <-'popad' will ignore it │ */+28
t_32 ebx; /* ┃ ↑栈从高地址往低地址增长*/+32
t_32 edx; /* ┃ │ */+36
t_32 ecx; /* ┃ │ */+40
t_32 eax; /* ┛ │ */+44
t_32 retaddr; /*return address for assembly code save() │ */+48
t_32 eip; /* ┓ │ */+52
t_32 cs; /* ┃ │ */+56
t_32 eflags; /* ┣ these are pushed by CPU during interrupt │ */+60
t_32 esp; /* ┃ │ */+64
t_32 ss; /* ┛ ┷High */+68
}STACK_FRAME;
/* 存储段描述符/系统段描述符 */
typedef structs_descriptor /* 共 8 个字节 */
{
t_16 limit_low; /*Limit */
t_16 base_low; /*Base */
t_8 base_mid; /*Base */
t_8 attr1; /*P(1) DPL(2) DT(1) TYPE(4) */
t_8 limit_high_attr2; /*G(1) D(1) 0(1) AVL(1) LimitHigh(4) */
t_8 base_high; /*Base */
}DESCRIPTOR;
三个进程PROCESS结构内容如下
TestA
save:
TestB
TestC
0x0004b5c0-0x4b624 共101个字节
STACK_FRAME regs;
+0 gs
0x19
0x19
+4 fs
0xd
0xd
+8 es
0xd
0xd
+12 ds
0xd
0xd
+16 edi
0x0
0xb4a
+20 esi
0x0后来设置成
0x31543
+24 ebp
0x0
0x4a89c
+28 kernel_esp
0x0
0x4b5f0
+32 ebx
0x0
0x0
+36 edx
0x0
0x0
+40 ecx
0x0
0x0
+44 eax
0x0
0x4a894
+48 retaddr
0x0
restart或者restart_reenter
+52 eip
0x000309e7 TestA函数
0x31438
+56 cs
0x5
0x5
+60 eflags
0x1202
0x1203
+64 esp
0x4a8c0
+68 ss
0xd
+72 t_16 ldt_sel
0x28
DESCRIPTOR ldts[LDT_SIZE];
+74 第一个LDT
0x00cfb800 0x0000ffff
+82 第二个LDT
0x00cfb200 0x0000ffff
+90 t_32 pid;
0x00000000
+94 char p_name[16];
00 00 54 65 73 74 41也就是TestA
3.TSS
typedef struct s_tss {
t_32 backlink;
t_32 esp0; /*stack pointer to use during interrupt */
t_32 ss0; /* " segment " " " " */
t_32 esp1;
x
t_32 cr3;
t_32 eip;
t_32 flags;
t_32 eax;
t_32 ecx;
t_32 edx;
t_32 ebx;
t_32 esp;
t_32 ebp;
t_32 esi;
t_32 edi;
t_32 es;
t_32 cs;
t_32 ss;
t_32 ds;
t_32 fs;
t_32 gs;
t_32 ldt;
t_16 trap;
t_16 iobase; /*I/O位图基址大于或等于TSS段界限,就表示没有I/O许可位图 */
/*t_8 iomap[2];*/
}TSS;
4.添加一个任务的步骤总结
下面我在f程序的基础上,增加一个进程D
(1)在添加一个进程体
Kernel\main.c
void TestD()
{
int i = 0x3000;
while(1){
disp_str("D");
disp_int(i++);
disp_str(".");
delay(1);
}
}
(2)在task_table中添加一项进程
Kernel\global.c
PUBLIC TASK task_table[NR_TASKS] = {{TestA,STACK_SIZE_TESTA, "TestA"},
{TestB,STACK_SIZE_TESTB, "TestB"},
{TestC,STACK_SIZE_TESTC, "TestC"},
{TestD,STACK_SIZE_TESTD, "TestD"}};
(3)让NR_TASKS加1
Include\proc.h
#define NR_TASKS 4
(4)定义任务堆栈和修改STACK_SIZE_TOTAL
Include\proc.h
#define STACK_SIZE_TESTA 0x8000
#define STACK_SIZE_TESTB 0x8000
#define STACK_SIZE_TESTC 0x8000
#define STACK_SIZE_TESTD 0x8000
#define STACK_SIZE_TOTAL (STACK_SIZE_TESTA+ \
STACK_SIZE_TESTB+ \
STACK_SIZE_TESTC+ \
STACK_SIZE_TESTD)
(5)添加新任务执行体函数声明
Include\proto.h
void TestD();
四、分析g加入系统调用
在f程序上增加的代码
1.在kernel/syscall.asm
get_ticks:
mov eax, _NR_get_ticks ; _NR_get_ticks
int INT_VECTOR_SYS_CALL ; INT_VECTOR_SYS_CALL equ 0x90
ret
2.在 kernel/protect.c中
//init_idt_desc_3102C(0x90, 0x8E,sys_call_307C6, 3);
init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate, sys_call, PRIVILEGE_USER);
3.当调用get_tichs就会调用sys_call函数,
Kernel/kernel.asm中
sys_call:
call save
sti ;开中断
call [sys_call_table + eax * 4] ;call off_32098[eax*4] ,,off_32098存放的是sys_get_ticks函数
mov [esi + EAXREG - P_STACKBASE], eax ;mov [esi+2Ch], eax
cli ;关中断
ret
4.上面实际调用了call [sys_call_table],也就是调用sys_call_table[0]
在kernel/global.c中有
PUBLIC t_sys_call sys_call_table[NR_SYS_CALL] ={sys_get_ticks};
实际调用函数sys_get_ticks
5.在kernel/proc.c中
PUBLIC int sys_get_ticks()
{
returnticks;
}
所以get_ticks最终调用的是sys_get_ticks函数
6.使用kernel/ main.c
void TestA()
{
while(1){
disp_str("A");
disp_int(get_ticks());
disp_str(".");
delay(1);
}
}
五、分析h加入时间
1.设置8253将时钟中断间隔改成10ms
Kernel\main.c
out_byte(TIMER_MODE,RATE_GENERATOR);
out_byte(TIMER0,(t_8) (TIMER_FREQ/HZ) );
out_byte(TIMER0,(t_8) ((TIMER_FREQ/HZ) >> 8));
2. 延迟函数
Kernel\ clock.c
PUBLIC void milli_delay(int milli_sec)
{
intt = get_ticks();
while(((get_ticks()- t) * 1000 / HZ) < milli_sec) {}
}
3.使用
void TestA()
{
while(1){
disp_str("A");
disp_int(get_ticks());
disp_str(".");
milli_delay(1000); //延迟了1s
}
}
4.注意
由于多进程切换和打印那些#字符导致不准确,去掉之后就好多了,还有bochs也不准确,换virtual pc就准确了,virtual pc更加像真机
5.为了测试我们改成一个进程
Kernel\global.c
PUBLIC TASK task_table[NR_TASKS] = {{TestA,STACK_SIZE_TESTA, "TestA"}};
Include\proc.h
#define NR_TASKS 1
#define STACK_SIZE_TESTA 0x8000
#define STACK_SIZE_TOTAL (STACK_SIZE_TESTA)
显示结果,果然每次打印相隔1s,数值每次差别是100
六、分析i程序进程调度
根据延长的时间长短实现进程调度
在进程表中加入一个变量,
1.为进程表添加新的成员
Include/proc.h
Typedef struct s_proc{
……
Int ticks;从某个值开始递减
Int priority;prority=ticks永久不变
2.初始化
Kernel/main.c
proc_table[0].ticks =proc_table[0].priority = 15;
proc_table[1].ticks =proc_table[1].priority = 5;
proc_table[2].ticks =proc_table[2].priority = 3;
3进程调度函数
Kernel/proc.c
PUBLIC void schedule()
{
PROCESS* p;
int greatest_ticks = 0;
while(!greatest_ticks) {
for(p=proc_table; p<proc_table+NR_TASKS; p++) {
if(p->ticks > greatest_ticks) {
greatest_ticks= p->ticks;
p_proc_ready= p;
}
}
if(!greatest_ticks) {
for (p=proc_table;p<proc_table+NR_TASKS; p++) {
p->ticks= p->priority;
}
}
}
}
4修改时钟中断处理函数
Kernel/clock.c
PUBLIC void clock_handler(int irq)
{
p_proc_read->ticks--;//新加入
schedule();//新加入
}
- 第六章 进程 总结
- 第六章、可执行文件的装载与进程 (总结)
- 第六章 进程控制
- 第六章-----进程通信
- 【操作系统】第六章 进程同步
- 《第六章 复用类》 总结
- 第六章 过程总结
- 第六章数组总结
- 第六章总结
- 第六章总结
- 第六章知识点总结
- Java总结第六章
- 第六章 13_总结
- 第六章(笔记总结)
- 数据结构第六章知识总结
- 软件工程第六章知识点总结
- 第六章 常用类总结
- c++ primer 第六章总结
- 给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)
- 数据结构(四)双向链表的基本操作
- 输入框去除边框及其属性
- 加入微信支付和微信分享的打包混淆问题
- Spring多视图配置
- 第六章 进程 总结
- MongoDB 模糊查询的三种实现方式-morphia实现
- 安卓 listview 怎样实现新加数据显示在上面?
- 【Intellij Idea】关于idea下使用lombok
- WebService的简介、原理和使用方法
- RxJava的使用与深入学习
- HTML5样式的使用
- 不良资产处置对于银行风险影响是什么?
- Android中的多线程断点下载