关于自己写操作系统进程的实现
2016-06-29 21:21
369 查看
1.首先进程有进程表和相关数据结构:
2.在初始化第一个进程的时候,一般设置较少,如下:
哈哈,其实就是一个操作而以,什么也没干,就是打印一个A,然后。。。。。。。
3.关键进程设置完后,什么时候进入进程,
在上面kernel_main()函数后面,有一个restart()函数,内容如下:
typedef struct s_stackframe { u32 gs; /* \ */ u32 fs; /* | */ u32 es; /* | */ u32 ds; /* | */ u32 edi; /* | */ u32 esi; /* | pushed by save() */ u32 ebp; /* | */ u32 kernel_esp; /* <- 'popad' will ignore it */ u32 ebx; /* | */ u32 edx; /* | */ u32 ecx; /* | */ u32 eax; /* / */ u32 retaddr; /* return addr for kernel.asm::save() */ u32 eip; /* \ */ u32 cs; /* | */ u32 eflags; /* | pushed by CPU during interrupt */ u32 esp; /* | */ u32 ss; /* / */ }STACK_FRAME; typedef struct s_proc { STACK_FRAME regs; /* process registers saved in stack frame */ u16 ldt_sel; /* gdt selector giving ldt base and limit */ DESCRIPTOR ldts[LDT_SIZE]; /* local descriptors for code and data */ u32 pid; /* process id passed in from MM */ char p_name[16]; /* name of the process */ }PROCESS;可以看出PROCESS结构体,将上面的图解释了一下,相当于我们根据上图来填PROCESS,
2.在初始化第一个进程的时候,一般设置较少,如下:
PUBLIC int kernel_main() { disp_str("-----\"kernel_main\" begins-----\n"); PROCESS* p_proc = proc_table; p_proc->ldt_sel = SELECTOR_LDT_FIRST; memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS>>3], sizeof(DESCRIPTOR)); p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; // change the DPL memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS>>3], sizeof(DESCRIPTOR)); p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; // change the DPL p_proc->regs.cs = (0 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.ds = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.es = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.fs = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.ss = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK; p_proc->regs.eip= (u32)TestA; p_proc->regs.esp= (u32) task_stack + STACK_SIZE_TOTAL; p_proc->regs.eflags = 0x1202; // IF=1, IOPL=1, bit 2 is always 1. p_proc_ready = proc_table; restart(); while(1){} }
</pre><pre name="code" class="cpp">其中,eip即为我们的进程函数,函数名为TestA,在于渊的书中原函数如下:
</pre><pre name="code" class="cpp">void TestA() { int i = 0; while(1){ disp_str("A"); disp_int(i++); disp_str("."); delay(1); } }
哈哈,其实就是一个操作而以,什么也没干,就是打印一个A,然后。。。。。。。
3.关键进程设置完后,什么时候进入进程,
在上面kernel_main()函数后面,有一个restart()函数,内容如下:
restart: mov esp, [p_proc_ready] lldt [esp + P_LDT_SEL] lea eax, [esp + P_STACKTOP] mov dword [tss + TSS3_S_SP0], eax pop gs pop fs pop es pop ds popad add esp, 4 iretd,最后一个iretd执行以后,eflags会改变成pProc->regs.eflags的值,我们已经事先设置了IF位,所以进程开始运行了。
相关文章推荐
- Thread的interrupt、isInterrupted、interrupted源码探索
- 分分钟让你搞懂VR和AR这么高大上的名词
- JDBC编程案例
- 图算法
- ActionBar
- [Android Pro] Android studio jni中调用Log输出调试信息
- AndroidStudio-Git-本地项目添加Git并初次上传到远程Git
- Android.mk文件配置多个LOCAL_SRC_FILES
- SQLite数据库
- file遍历(递归)
- Android 热修复总结
- LeetCode ——258.Add Digits
- openstack on centos 7.1(Object Storage)
- NFS安装
- 数据库三范式讲解
- File的sd卡
- DirectXMath
- 【MediaElement】WPF视频播放器【1】
- UVC支持的摄像头列表
- java中的不为空判断