📄 main.c
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/kernel/main.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06700 /* This file contains the main program of MINIX. The routine main()
06701 * initializes the system and starts the ball rolling by setting up the proc
06702 * table, interrupt vectors, and scheduling each task to run to initialize
06703 * itself.
06704 *
06705 * The entries into this file are:
06706 * main: MINIX main program
06707 * panic: abort MINIX due to a fatal error
06708 */
06709
06710 #include "kernel.h"
06711 #include <signal.h>
06712 #include <unistd.h>
06713 #include <minix/callnr.h>
06714 #include <minix/com.h>
06715 #include "proc.h"
06716
06717
06718 /*===========================================================================*
06719 * main *
06720 *===========================================================================*/
06721 PUBLIC void main()
06722 {
06723 /* Start the ball rolling. */
06724
06725 register struct proc *rp;
06726 register int t;
06727 int sizeindex;
06728 phys_clicks text_base;
06729 vir_clicks text_clicks;
06730 vir_clicks data_clicks;
06731 phys_bytes phys_b;
06732 reg_t ktsb; /* kernel task stack base */
06733 struct memory *memp;
06734 struct tasktab *ttp;
06735
06736 /* Initialize the interrupt controller. */
06737 intr_init(1);
06738
06739 /* Interpret memory sizes. */
06740 mem_init();
06741
06742 /* Clear the process table.
06743 * Set up mappings for proc_addr() and proc_number() macros.
06744 */
06745 for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
06746 rp->p_flags = P_SLOT_FREE;
06747 rp->p_nr = t; /* proc number from ptr */
06748 (pproc_addr + NR_TASKS)[t] = rp; /* proc ptr from number */
06749 }
06750
06751 /* Set up proc table entries for tasks and servers. The stacks of the
06752 * kernel tasks are initialized to an array in data space. The stacks
06753 * of the servers have been added to the data segment by the monitor, so
06754 * the stack pointer is set to the end of the data segment. All the
06755 * processes are in low memory on the 8086. On the 386 only the kernel
06756 * is in low memory, the rest if loaded in extended memory.
06757 */
06758
06759 /* Task stacks. */
06760 ktsb = (reg_t) t_stack;
06761
06762 for (t = -NR_TASKS; t <= LOW_USER; ++t) {
06763 rp = proc_addr(t); /* t's process slot */
06764 ttp = &tasktab[t + NR_TASKS]; /* t's task attributes */
06765 strcpy(rp->p_name, ttp->name);
06766 if (t < 0) {
06767 if (ttp->stksize > 0) {
06768 rp->p_stguard = (reg_t *) ktsb;
06769 *rp->p_stguard = STACK_GUARD;
06770 }
06771 ktsb += ttp->stksize;
06772 rp->p_reg.sp = ktsb;
06773 text_base = code_base >> CLICK_SHIFT;
06774 /* tasks are all in the kernel */
06775 sizeindex = 0; /* and use the full kernel sizes */
06776 memp = &mem[0]; /* remove from this memory chunk */
06777 } else {
06778 sizeindex = 2 * t + 2; /* MM, FS, INIT have their own sizes */
06779 }
06780 rp->p_reg.pc = (reg_t) ttp->initial_pc;
06781 rp->p_reg.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;
06782
06783 text_clicks = sizes[sizeindex];
06784 data_clicks = sizes[sizeindex + 1];
06785 rp->p_map[T].mem_phys = text_base;
06786 rp->p_map[T].mem_len = text_clicks;
06787 rp->p_map[D].mem_phys = text_base + text_clicks;
06788 rp->p_map[D].mem_len = data_clicks;
06789 rp->p_map[S].mem_phys = text_base + text_clicks + data_clicks;
06790 rp->p_map[S].mem_vir = data_clicks; /* empty - stack is in data */
06791 text_base += text_clicks + data_clicks; /* ready for next, if server */
06792 memp->size -= (text_base - memp->base);
06793 memp->base = text_base; /* memory no longer free */
06794
06795 if (t >= 0) {
06796 /* Initialize the server stack pointer. Take it down one word
06797 * to give crtso.s something to use as "argc".
06798 */
06799 rp->p_reg.sp = (rp->p_map[S].mem_vir +
06800 rp->p_map[S].mem_len) << CLICK_SHIFT;
06801 rp->p_reg.sp -= sizeof(reg_t);
06802 }
06803
06804 #if _WORD_SIZE == 4
06805 /* Servers are loaded in extended memory if in 386 mode. */
06806 if (t < 0) {
06807 memp = &mem[1];
06808 text_base = 0x100000 >> CLICK_SHIFT;
06809 }
06810 #endif
06811 if (!isidlehardware(t)) lock_ready(rp); /* IDLE, HARDWARE neveready */
06812 rp->p_flags = 0;
06813
06814 alloc_segments(rp);
06815 }
06816
06817 proc[NR_TASKS+INIT_PROC_NR].p_pid = 1;/* INIT of course has pid 1 */
06818 bill_ptr = proc_addr(IDLE); /* it has to point somewhere */
06819 lock_pick_proc();
06820
06821 /* Now go to the assembly code to start running the current process. */
06822 restart();
06823 }
06826 /*===========================================================================*
06827 * panic *
06828 *===========================================================================*/
06829 PUBLIC void panic(s,n)
06830 _CONST char *s;
06831 int n;
06832 {
06833 /* The system has run aground of a fatal error. Terminate execution.
06834 * If the panic originated in MM or FS, the string will be empty and the
06835 * file system already syncked. If the panic originates in the kernel, we are
06836 * kind of stuck.
06837 */
06838
06839 if (*s != 0) {
06840 printf("\nKernel panic: %s",s);
06841 if (n != NO_NUM) printf(" %d", n);
06842 printf("\n");
06843 }
06844 wreboot(RBT_PANIC);
06845 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -