分类: LINUX
2017-03-04 13:10:39
1、mystartkernel()程序中,任务控制块的初始化中
*(task[i].thread.sp) = task[i].thread.sp;
task[i].thread.sp -= 1;
编译错误,修改为
*((unsigned long *)task[i].thread.sp) = task[i].thread.sp - sizeof(unsigned long);
// task[i].thread.sp -= 1; (去掉,即使需要这一步,也应该改为task[i].thread.sp -= 4; )
(程序中,地址都是当做unsigned long类型处理的)
2、程序中将堆栈设成unsigned long类型,为什么不把堆栈设成字符型的呢?
待验证(拖到最后了,时间来不及,所以还按原程序讨论)
创建的进程控制块链表
3、启动进程0之前,任务0的堆栈
并且此时task[0].thread.ip指向myprocess()程序的入口
启动进程0
asm volatile(
"movl %1,%%esp\n\t" /* set task[pid].thread.sp to esp */
"pushl %1\n\t" /* push ebp */
"pushl %0\n\t" /* push task[pid].thread.ip */
"ret\n\t" /* pop task[pid].thread.ip to eip */
"popl %%ebp\n\t"
:
: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp) /* input c or d mean %ecx/%edx*/
);
启动进程0之后,任务0的堆栈
并且此时eip指向my_process程序的入口地址
4、两进程切换之前的堆栈(以2到3的切换为例)
两进程切换
asm volatile(
"pushl %%ebp\n\t" /* save ebp */
"movl %%esp,%0\n\t" /* save esp */
"movl %2,%%esp\n\t" /* restore esp */
"movl $1f,%1\n\t" /* save eip */
"pushl %3\n\t"
"ret\n\t" /* restore eip */
"1:\t" /* next process start here */
"popl %%ebp\n\t"
: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
: "m" (next->thread.sp),"m" (next->thread.ip)
);
两进程切换之后的堆栈
5、试验结果:
注:
郭昌明 + 《Linux内核分析》 MOOC课程