JOS LAB3 小问题(二)

在lab3/lib/syscall.c里面有这样一段汇编:

                          

这段汇编代码主要是将系统调用号存放在AX,参数a1,a2,a3,a4,a5分别放在DX,CX,BX,DI,SI当中。下面我们看一段代码:

 

trap_dispatch(struct Trapframe *tf)
{
	// Handle processor exceptions.
	// LAB 3: Your code here.
	print_trapframe(tf);	
        switch(tf->tf_trapno)
	{
		case T_DIVIDE:print_trapframe(tf);break;
		case T_DEBUG:print_trapframe(tf);break;
		case T_NMI:print_trapframe(tf);break;
		case T_BRKPT:monitor(tf);return;
		case T_OFLOW:print_trapframe(tf);break;
		case T_BOUND:
		case T_ILLOP:
		case T_DEVICE:
		case T_DBLFLT:
		case T_TSS:
		case T_SEGNP:
		case T_STACK:
		case T_GPFLT:print_trapframe(tf);break;
		case T_PGFLT:page_fault_handler(tf); return;
		case T_FPERR:
		case T_ALIGN:
		case T_MCHK:
		case T_SIMDERR:print_trapframe(tf);break;
		case T_SYSCALL:
			       cprintf("enter syscall\n");
			       tf->tf_regs.reg_eax=syscall(tf->tf_regs.reg_eax,
					               tf->tf_regs.reg_ebx,
						       tf->tf_regs.reg_ecx,
						       tf->tf_regs.reg_edx,
						       tf->tf_regs.reg_edi,
						       tf->tf_regs.reg_esi);
			       return;

		default:break;
		

	}

	// Unexpected trap: The user process or the kernel has a bug.
        

	print_trapframe(tf);
	if (tf->tf_cs == GD_KT)
		panic("unhandled trap in kernel");
	else {
		env_destroy(curenv);
		return;
	}
}

我们主要看case T_SYSCALL那一段:syscall()函数里面的参数分别为:tf->tf_regs.reg_eax,tf->tf_regs.reg_ebx,tf->tf_regs.reg_ecx,tf->tf_regs.reg_edx,tf->tf_regs.reg_edi,tf->tf_regs.reg_esi。这与我们前面那段汇编代码所要做的事情是不一致的,显然会出现错误的。我们可以看看:

 

这里并没没有输出hello,world!这就是因为我们前面所说的不一致而引起的,我们要将代码稍微改一下:将trap_distrap()函数里面case T_SYSCALL那里syscall()函数里面的参数tf->tf_regs.reg_ebx和tf->tf_regs.reg_edx对换一下。这里就输出了hello,world。

             asm volatile("int %1\n"

                   : “=a”  (ret)

                   :   “i”    (T_SYSCALL),
                       “a”   (num),
                       “d”   (a1),
                       “c”   (a2),
                       “b”   (a3), 
                       “D”   (a4),
                       “S”   (a5),
                   :   “cc”  ,“memory”);

JOS LAB3 (一) 小问题

 

      在这个实验的PART A部分,我遇到了一个小小的问题,就是在env_run()当中,cr3的值变为零了。

 

代码如下:

 

void  env_run(struct Env *e)
{

 

       if(curenv != e){
              curenv=e;

      }
      curenv->env_runs++;
      cprintf("env_run cr3:%d\n", curenv->env_cr3);

      lcr3(e->env_cr3);               
      env_pop_tf(&curenv->env_tf);
}

 

 

 

实际上这里是没有问题的,那么问题在哪里呢?我们找到env初始化的地方去。

 

代码如下:

void env_init(void)

{

 

 

       int i;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       LIST_INIT(&env_free_list);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      

       for(i=0;i>NENV-1;i++)

       {

                envs[i].env_status=ENV_FREE;

                envs[i].env_id=0;

                LIST_INSERT_HEAD(&env_free_list,&envs[i],env_link);

      }

}

然后就是env的分配:


int   env_alloc(struct Env **newenv_store, envid_t parent_id)
{
       int32_t  generation;
       int r;
       struct Env *e;

       if (!(e = LIST_FIRST(&env_free_list)))

                  return -E_NO_FREE_ENV;

       if ((r = env_setup_vm(e)) < 0)
                  return r;

       generation = (e->env_id + (1 << ENVGENSHIFT)) & ~(NENV - 1);

if (generation <= 0) // Don't create a negative env_id.
  generation = 1 << ENVGENSHIFT;
 e->env_id = generation | (e - envs);
 
 e->env_parent_id = parent_id;
 e->env_status = ENV_RUNNABLE;
 e->env_runs = 0;

 memset(&e->env_tf, 0, sizeof(e->env_tf)

 e->env_tf.tf_ds = GD_UD | 3;
 e->env_tf.tf_es = GD_UD | 3;
 e->env_tf.tf_ss = GD_UD | 3;
 e->env_tf.tf_esp = USTACKTOP;
 e->env_tf.tf_cs = GD_UT | 3;

 LIST_REMOVE(e, env_link);
 *newenv_store = e;

 cprintf("[%08x] new env %08x\n", curenv ? curenv->env_id : 0, e->env_id);
 return 0;
}

这里我们知道新分配的env是插入到头结点后面的。所以我们分配的是env[NENV-1]的地址空间。但是实际上我们在env_run 中运行的是env[0],所以在env_run()函数中cr3变为零了。因此我们将初始化函数程序做如下修改:

 

void env_init(void)

{

 

 

       int i;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

LIST_INIT(&env_free_list);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      

 

       for(i=NENV-1;i>=0;i--)

       {

                envs[i].env_status=ENV_FREE;

                envs[i].env_id=0;

                LIST_INSERT_HEAD(&env_free_list,&envs[i],env_link);

      }

}





Host by is-Programmer.com | Power by Chito 1.3.3 beta
Butterfly Theme | Design: HRS Hersteller of mobile Hundeschule.