minix3内核代码注释----分析系统调用

490阅读 0评论2014-03-07 慕冬亮
分类:

内核任务sys_task会调用initialize()来初始化系统调用表。
 

PRIVATE void initialize(void)
{
  register struct priv *sp;
  int i;

  /* 初始化所有的irq_hooks为NONE 未被使用 */
  for (i=0; i<NR_IRQ_HOOKS; i++) {
      irq_hooks[i].proc_nr_e = NONE;
  }

  /* 初始化所有的特权结构体中的alarm timer */
  for (sp=BEG_PRIV_ADDR; sp < END_PRIV_ADDR; sp++) {
    tmr_inittimer(&(sp->s_alarm_timer));
  }

  /* 初始化所有的system calls为unused
   */

  for (i=0; i<NR_SYS_CALLS; i++) {
      call_vec[i] = do_unused;
  }

  /* 进程管理相关的系统调用. */
  map(SYS_FORK, do_fork);         /*a process forked a new process */
  map(SYS_EXEC, do_exec);        /* update process after execute*/
  map(SYS_EXIT, do_exit);        /* clean up after process exit */
  map(SYS_NICE, do_nice);        /* set scheduling priority*/
  map(SYS_PRIVCTL, do_privctl);        /* system privileges control*/
  map(SYS_TRACE, do_trace);        /* request a trace operation*/

  /* 信号处理. */
  map(SYS_KILL, do_kill);         /* cause a process to be signaled */
  map(SYS_GETKSIG, do_getksig);        /* PM checks for pending signals */
  map(SYS_ENDKSIG, do_endksig);        /* PM finished processing signal */
  map(SYS_SIGSEND, do_sigsend);        /* start POSIX-style signal */
  map(SYS_SIGRETURN, do_sigreturn);    /* return from POSIX-style signal */

  /* I/O设备. */
  map(SYS_IRQCTL, do_irqctl);         /* interrupt control operations */
  map(SYS_DEVIO, do_devio);         /* inb, inw, inl, outb, outw, outl */
  map(SYS_SDEVIO, do_sdevio);        /* phys_insb, _insw, _outsb, _outsw */
  map(SYS_VDEVIO, do_vdevio);         /* vector with devio requests */
  map(SYS_INT86, do_int86);         /* real-mode BIOS calls */

  /* 内存管理. */
  map(SYS_NEWMAP, do_newmap);        /* set up a process memory map */
  map(SYS_SEGCTL, do_segctl);        /* add segment and get selector */
  map(SYS_MEMSET, do_memset);        /* write char to memory area */
  map(SYS_VM_SETBUF, do_vm_setbuf);     /* PM passes buffer for page tables */
  map(SYS_VM_MAP, do_vm_map);         /* Map/unmap physical (device) memory */

  /* 内存间拷贝. */
  map(SYS_UMAP, do_umap);        /* map virtual to physical address */
  map(SYS_VIRCOPY, do_vircopy);     /* use pure virtual addressing */
  map(SYS_PHYSCOPY, do_physcopy);     /* use physical addressing */
  map(SYS_VIRVCOPY, do_virvcopy);    /* vector with copy requests */
  map(SYS_PHYSVCOPY, do_physvcopy);    /* vector with copy requests */

  /* 时钟功能. */
  map(SYS_TIMES, do_times);        /* get uptime and process times */
  map(SYS_SETALARM, do_setalarm);    /* schedule a synchronous alarm */

  /*系统控制. */
  map(SYS_ABORT, do_abort);        /* abort MINIX */
  map(SYS_GETINFO, do_getinfo);     /* request system information */
  map(SYS_IOPENABLE, do_iopenable);     /* Enable I/O */
}

map代码如下

#define map(call_nr, handler) \
    {extern int dummy[NR_SYS_CALLS>(unsigned)(call_nr-KERNEL_CALL) ? 1:-1];} \
    call_vec[(call_nr-KERNEL_CALL)] = (handler) 

dummy数组的用处是防止NR_SYS_CALLS<(unsigned)(call_nr-KERNEL_CALL),若其情况发生则编译器报错 因为数组大小不能为-1

call_vec[(call_nr-KERNEL_CALL)] = (handler) //将对应的系统调用handler写到table中。

完成了系统调用的初始化,那么上层的driver或servers等是如何使用系统调用的呢?

内核外的进程是通过IPC通知内核中的sys_task来调用系统调用的,message结构体中包括了消息源,消息类型和消息数据。消息类型决定了调用哪个系统调用。消息源说明了系统调用的调用者。在确认系统调用调用者和系统调用号的合法性后,还需要检查此进程的系统调用屏蔽位图,看对应的系统调用是否被允许,最后完成系统调用并根据结果返回消息。

上一篇:minix3内核代码注释----ipc分析
下一篇:如何写一个简易文件系统(1):注册文件系统