Chinaunix首页 | 论坛 | 博客
  • 博客访问: 37750
  • 博文数量: 6
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 75
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-10 00:12
文章存档

2011年(6)

我的朋友

分类: LINUX

2011-05-04 10:33:01



  1. /* This file contains the main program of MINIX as well as its shutdown code.
  2.  * The routine main() initializes the system and starts the ball rolling by
  3.  * setting up the process table, interrupt vectors, and scheduling each task
  4.  * to run to initialize itself.
  5.  * The routine shutdown() does the opposite and brings down MINIX.
  6.  *
  7.  * The entries into this file are:
  8.  * main:         MINIX main program
  9.  * prepare_shutdown:    prepare to take MINIX down
  10.  *
  11.  * Changes:
  12.  * Nov 24, 2004 simplified main() with system image (Jorrit N. Herder)
  13.  * Aug 20, 2004 new prepare_shutdown() and shutdown() (Jorrit N. Herder)
  14.  */
  15.  /*
  16.  main()函数通过设置进程表,中断向量,调度每个任务去运行从而初始化了系统并且启动了ball rolling
  17. shutdown()函数则相反 它使minix关机
  18.  */
  19. #include "kernel.h"
  20. #include <signal.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <a.out.h>//minix3中可执行文件的格式
  24. #include <minix/callnr.h>
  25. #include <minix/com.h>
  26. #include "proc.h"

  27. /* Prototype declarations for PRIVATE functions. */
  28. FORWARD _PROTOTYPE( void announce, (void));    
  29. FORWARD _PROTOTYPE( void shutdown, (timer_t *tp));

  30. /*===========================================================================*
  31.  *                main *
  32.  *===========================================================================*/
  33. PUBLIC void main()
  34. {
  35. /* Start the ball rolling. */
  36.   struct boot_image *ip;    /* boot image pointer *//* boot image指针 */
  37.   register struct proc *rp;    /* process pointer *//* 进程描述符指针 */
  38.   register struct priv *sp;    /* privilege structure pointer *//* 优先级结构体指针 */
  39.   register int i, s;
  40.   int hdrindex;            /* index to array of a.out headers *//* 标准执行文件头的索引 */
  41.   phys_clicks text_base;/*物理代码地址*/
  42.   vir_clicks text_clicks, data_clicks;/* 虚拟代码和数据地址*/
  43.   reg_t ktsb;            /* kernel task stack base *//* 内核任务堆栈基地址 */
  44.   struct exec e_hdr;        /* for a copy of an a.out header *//* 可执行文件头的一个拷贝*/

  45.   /* Initialize the interrupt controller. *//* 初始化中断控制器. */
  46.   intr_init(1);/* 参数1代表中断向量将被内核重写 0代表使用bios设置的中断向量 */

  47.   /* Clear the process table. Anounce each slot as empty and set up mappings
  48.    * for proc_addr() and proc_nr() macros. Do the same for the table with
  49.    * privilege structures for the system processes.
  50.    */
  51.    /* 清空进程表。将每个槽声明为空并且设置proc_addr() 和proc_nr() 宏的映射表. 设置优先级表 */
  52.   for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
  53.       rp->p_rts_flags = SLOT_FREE;        /* initialize free slot */
  54.     rp->p_nr = i;                /* proc number from ptr */
  55.         (pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */
  56.   }
  57.   /*初始化优先级结构体 总共有32个 因为系统进程数为32*/
  58.   for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
  59.     sp->s_proc_nr = NONE;            /* initialize as free */
  60.     sp->s_id = i;                /* priv structure index */
  61.     ppriv_addr[i] = sp;            /* priv ptr from number */
  62.   }

  63.   /* Set up proc table entries for processes in boot image. The stacks of the
  64.    * kernel tasks are initialized to an array in data space. The stacks
  65.    * of the servers have been added to the data segment by the monitor, so
  66.    * the stack pointer is set to the end of the data segment. All the
  67.    * processes are in low memory on the 8086. On the 386 only the kernel
  68.    * is in low memory, the rest is loaded in extended memory.
  69.    */

  70.   /* Task stacks. */
  71.   ktsb = (reg_t) t_stack;

  72.   /*初始化包含在启动映像中的进程 包括4个任务 8个进程 这八个进程ms已被移出boot image*/
  73.   for (i=0; i < NR_BOOT_PROCS; ++i) {
  74.     ip = &image[i];                /* process' attributes */
  75.     rp = proc_addr(ip->proc_nr);        /* get process pointer */
  76.     rp->p_max_priority = ip->priority;    /* max scheduling priority */
  77.     rp->p_priority = ip->priority;        /* current priority */
  78.     rp->p_quantum_size = ip->quantum;    /* quantum size in ticks */
  79.     rp->p_ticks_left = ip->quantum;        /* current credit */
  80.     strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
  81.     (void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
  82.     priv(rp)->s_flags = ip->flags;            /* process flags */
  83.     priv(rp)->s_trap_mask = ip->trap_mask;        /* allowed traps */
  84.     priv(rp)->s_call_mask = ip->call_mask;        /* kernel call mask */
  85.     priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to;    /* restrict targets */
  86.     if (iskerneln(proc_nr(rp))) {        /* part of the kernel? */
  87.         if (ip->stksize > 0) {        /* HARDWARE stack size is 0 */
  88.             rp->p_priv->s_stack_guard = (reg_t *) ktsb;
  89.             *rp->p_priv->s_stack_guard = STACK_GUARD;
  90.         }
  91.         ktsb += ip->stksize;    /* point to high end of stack */
  92.         rp->p_reg.sp = ktsb;    /* this task's initial stack ptr */
  93.         text_base = kinfo.code_base >> CLICK_SHIFT;
  94.                     /* processes that are in the kernel */
  95.         hdrindex = 0;        /* all use the first a.out header */
  96.     } else {
  97.         hdrindex = 1 + i-NR_TASKS;    /* servers, drivers, INIT */
  98.     }

  99.     /* The bootstrap loader created an array of the a.out headers at
  100.      * absolute address 'aout'. Get one element to e_hdr.
  101.      */
  102.     phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
  103.                         (phys_bytes) A_MINHDR);
  104.     /* Convert addresses to clicks and build process memory map */
  105.     text_base = e_hdr.a_syms >> CLICK_SHIFT;
  106.     text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
  107.     if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0;     /* common I&D */
  108.     data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
  109.     rp->p_memmap[T].mem_phys = text_base;
  110.     rp->p_memmap[T].mem_len = text_clicks;
  111.     rp->p_memmap[D].mem_phys = text_base + text_clicks;
  112.     rp->p_memmap[D].mem_len = data_clicks;
  113.     rp->p_memmap[S].mem_phys = text_base + text_clicks + data_clicks;
  114.     rp->p_memmap[S].mem_vir = data_clicks;    /* empty - stack is in data */

  115.     /* Set initial register values. The processor status word for tasks
  116.      * is different from that of other processes because tasks can
  117.      * access I/O; this is not allowed to less-privileged processes
  118.      */
  119.     rp->p_reg.pc = (reg_t) ip->initial_pc;
  120.     rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;

  121.     /* Initialize the server stack pointer. Take it down one word
  122.      * to give crtso.s something to use as "argc".
  123.      */
  124.     if (isusern(proc_nr(rp))) {        /* user-space process? */
  125.         rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
  126.                 rp->p_memmap[S].mem_len) << CLICK_SHIFT;
  127.         rp->p_reg.sp -= sizeof(reg_t);
  128.     }
  129.     
  130.     /* Set ready. The HARDWARE task is never ready. */
  131.     if (rp->p_nr != HARDWARE) {
  132.         rp->p_rts_flags = 0;        /* runnable if no flags */
  133.         lock_enqueue(rp);        /* add to scheduling queues */
  134.     } else {
  135.         rp->p_rts_flags = NO_MAP;    /* prevent from running */
  136.     }

  137.     /* Code and data segments must be allocated in protected mode. */
  138.     alloc_segments(rp);
  139.   }

  140. #if ENABLE_BOOTDEV
  141.   /* Expect an image of the boot device to be loaded into memory as well.
  142.    * The boot device is the last module that is loaded into memory, and,
  143.    * for example, can contain the root FS (useful for embedded systems).
  144.    */
  145.   hdrindex ++;
  146.   phys_copy(aout + hdrindex * A_MINHDR,vir2phys(&e_hdr),(phys_bytes) A_MINHDR);
  147.   if (e_hdr.a_flags & A_IMG) {
  148.       kinfo.bootdev_base = e_hdr.a_syms;
  149.       kinfo.bootdev_size = e_hdr.a_data;
  150.   }
  151. #endif

  152.   /* MINIX is now ready. All boot image processes are on the ready queue.
  153.    * Return to the assembly code to start running the current process.
  154.    */
  155.   bill_ptr = proc_addr(IDLE);        /* it has to point somewhere */
  156.   announce();                /* print MINIX startup banner */
  157.   restart();
  158. }
  159. /* restart 是一段汇编程序 */
  160. /*
  161. _restart:

  162. ! 重新启动就绪的进程.

  163.  cmp (_next_ptr), 0 ! 看是否有就绪的next进程
  164.  jz 0f
  165.  mov eax, (_next_ptr)
  166.  mov (_proc_ptr), eax ! 将next进程设为当前进程
  167.  mov (_next_ptr), 0 ! 将next指针设为0
  168. 0: mov esp, (_proc_ptr) ! will assume P_STACKBASE == 0
  169.  lldt P_LDT_SEL(esp) ! enable process' segment descriptors
  170.  lea eax, P_STACKTOP(esp) ! arrange for next interrupt
  171.  mov (_tss+TSS3_S_SP0), eax ! to save state in process table
  172. restart1:
  173.  decb (_k_reenter)
  174.     o16 pop gs
  175.     o16 pop fs
  176.     o16 pop es
  177.     o16 pop ds
  178.  popad
  179.  add esp, 4 ! skip return adr
  180.  iretd ! 恢复寄存器
  181. */
  182. /*===========================================================================*
  183.  *                announce                 *
  184.  *===========================================================================*/
  185. PRIVATE void announce(void)
  186. {
  187.   /* Display the MINIX startup banner. */
  188.   kprintf("\nMINIX %s.%s. "
  189.       "Copyright 2006, Vrije Universiteit, Amsterdam, The Netherlands\n",
  190.       OS_RELEASE, OS_VERSION);
  191. #if (CHIP == INTEL)
  192.   /* Real mode, or 16/32-bit protected mode? */
  193.   kprintf("Executing in %s mode.\n\n",
  194.       machine.protected ? "32-bit protected" : "real");
  195. #endif
  196. }

  197. /*===========================================================================*
  198.  *                prepare_shutdown             *
  199.  *===========================================================================*/
  200. PUBLIC void prepare_shutdown(how)
  201. int how;
  202. {
  203. /* This function prepares to shutdown MINIX. */
  204.   static timer_t shutdown_timer;
  205.   register struct proc *rp;
  206.   message m;

  207.   /* Send a signal to all system processes that are still alive to inform
  208.    * them that the MINIX kernel is shutting down. A proper shutdown sequence
  209.    * should be implemented by a user-space server. This mechanism is useful
  210.    * as a backup in case of system panics, so that system processes can still
  211.    * run their shutdown code, e.g, to synchronize the FS or to let the TTY
  212.    * switch to the first console.
  213.    */
  214.   kprintf("Sending SIGKSTOP to system processes ...\n");
  215.   for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
  216.       if (!isemptyp(rp) && (priv(rp)->s_flags & SYS_PROC) && !iskernelp(rp))
  217.           send_sig(proc_nr(rp), SIGKSTOP);
  218.   }

  219.   /* Continue after 1 second, to give processes a chance to get scheduled to
  220.    * do shutdown work. Set a watchog timer to call shutdown(). The timer
  221.    * argument passes the shutdown status.
  222.    */
  223.   kprintf("MINIX will now be shut down ...\n");
  224.   tmr_arg(&shutdown_timer)->ta_int = how;
  225.   shutdown(&shutdown_timer);
  226. }
  227. /*===========================================================================*
  228.  *                shutdown                  *
  229.  *===========================================================================*/
  230. PRIVATE void shutdown(tp)
  231. timer_t *tp;
  232. {
  233. /* This function is called from prepare_shutdown or stop_sequence to bring
  234.  * down MINIX. How to shutdown is in the argument: RBT_HALT (return to the
  235.  * monitor), RBT_MONITOR (execute given code), RBT_RESET (hard reset).
  236.  */
  237.   int how = tmr_arg(tp)->ta_int;
  238.   u16_t magic;

  239.   /* Now mask all interrupts, including the clock, and stop the clock. */
  240.   outb(INT_CTLMASK, ~0);
  241.   clock_stop();

  242.   if (mon_return && how != RBT_RESET) {
  243.     /* Reinitialize the interrupt controllers to the BIOS defaults. */
  244.     intr_init(0);
  245.     outb(INT_CTLMASK, 0);
  246.     outb(INT2_CTLMASK, 0);

  247.     /* Return to the boot monitor. Set the program if not already done. */
  248.     if (how != RBT_MONITOR) phys_copy(vir2phys(""), kinfo.params_base, 1);
  249.     level0(monitor);
  250.   }

  251.   /* Reset the system by jumping to the reset address (real mode), or by
  252.    * forcing a processor shutdown (protected mode). First stop the BIOS
  253.    * memory test by setting a soft reset flag.
  254.    */
  255.   magic = STOP_MEM_CHECK;
  256.   phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE);
  257.   level0(reset);
  258. }
阅读(1603) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:minix3系统 boot 过程

给主人留下些什么吧!~~