Beispiel #1
0
/*=======================================================
                 init_prot()
 ========================================================*/
PUBLIC void init_prot()
{
	init_8259A();

	//初始化异常  (中断门  没有陷阱门)
	init_idt_desc( INT_VECTOR_DIVIDE, DA_386IGate, divide_error, PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_DEBUG,  DA_386IGate, single_step_exception,  PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_NMI,     DA_386IGate, nmi,  PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_BREAKPOINT, DA_386IGate,  breakpoint_exception, PRIVILEGE_USER);
    init_idt_desc( INT_VECTOR_OVERFLOW,  DA_386IGate , overflow,   PRIVILEGE_USER);
    init_idt_desc( INT_VECTOR_BOUNDS,    DA_386IGate,  bounds_check,  PRIVILEGE_KRNL);
	init_idt_desc( INT_VECTOR_INVAL_OP,  DA_386IGate,  inval_opcode,  PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_COPROC_NOT, DA_386IGate,  copr_not_available,   PRIVILEGE_KRNL);
	init_idt_desc( INT_VECTOR_DOUBLE_FAULT,  DA_386IGate,  double_fault,   PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_COPROC_SEG,    DA_386IGate,  copr_seg_overrun,  PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_INVAL_TSS, DA_386IGate,  inval_tss,    PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_SEG_NOT,   DA_386IGate,  segment_not_present,  PRIVILEGE_KRNL);
	init_idt_desc( INT_VECTOR_STACK_FAULT,   DA_386IGate,   stack_exception,    PRIVILEGE_KRNL);
	init_idt_desc( INT_VECTOR_PROTECTION,    DA_386IGate,   general_protection,   PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_PAGE_FAULT,    DA_386IGate,  page_fault,   PRIVILEGE_KRNL);
    init_idt_desc( INT_VECTOR_COPROC_ERR,    DA_386IGate,  copr_error,  PRIVILEGE_KRNL);
  
	 /*初始化中断*/
	 init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate , hint00 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate , hint01 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate , hint02 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate , hint03 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate , hint04 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate , hint05 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate , hint06 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate , hint07 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate , hint08 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate , hint09 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate , hint10 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate , hint11 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate , hint12 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate , hint13 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate , hint14 , PRIVILEGE_KRNL);
	 init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate , hint15 , PRIVILEGE_KRNL);


	 /* 填充 GDT 中的 TSS */
	 memset(&tss,0,sizeof(tss));
     tss.ss0 = SELECTOR_KERNEL_DS;
	 init_descriptor(&gdt[INDEX_TSS],
			 vir2phys(seg2phys(SELECTOR_KERNEL_DS),&tss),
			 sizeof(tss) - 1, DA_386TSS);

	 tss.iobase = sizeof(tss); /*没有I/O许可位图*/

	 /*填充 GDT 中进程的 LDT的描述符 */
	 init_descriptor(&gdt[INDEX_LDT_FIRST],
			 vir2phys(seg2phys(SELECTOR_KERNEL_DS),proc_table[0].ldts),
			 LDT_SIZE * sizeof(DESCRIPTOR) - 1, DA_LDT);
}
Beispiel #2
0
phys_bytes pg_load()
{
	phys_bytes phpagedir = vir2phys(pagedir);
	refresh_tlb();
        write_ttbr0(phpagedir);
	return phpagedir;
}
Beispiel #3
0
PUBLIC void arch_get_aout_headers(const int i, struct exec *h)
{
    /* The bootstrap loader created an array of the a.out headers at
     * absolute address 'aout'. Get one element to h.
     */
    phys_copy(aout + i * A_MINHDR, vir2phys(h), (phys_bytes) A_MINHDR);
}
Beispiel #4
0
PRIVATE void cons_setc(const int pos, const int c)
{
    char ch;

    ch= c;
    phys_copy(vir2phys((vir_bytes)&ch), COLOR_BASE+(20*80+pos)*2, 1);
}
Beispiel #5
0
PUBLIC int arch_set_params(char *params, int size)
{
	if(size > params_size)
		return E2BIG;
	phys_copy(vir2phys(params), seg2phys(mon_ds) + params_offset, size);
	return OK;
}
Beispiel #6
0
PUBLIC int arch_get_params(char *params, int maxsize)
{
	phys_copy(seg2phys(mon_ds) + params_offset, vir2phys(params),
		MIN(maxsize, params_size));
	params[maxsize-1] = '\0';
	return OK;
}
Beispiel #7
0
static u32_t phys_get32(phys_bytes addr)
{
	const u32_t v;
	int r;

	if(!vm_running) {
		phys_copy(addr, vir2phys(&v), sizeof(v));
		return v;
	}

	if((r=lin_lin_copy(NULL, addr, 
		proc_addr(SYSTEM), vir2phys(&v), sizeof(v))) != OK) {
		panic("lin_lin_copy for phys_get32 failed: %d",  r);
	}

	return v;
}
Beispiel #8
0
/*
**  Name:	void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from user area to board (Prog. I/O, 16bits).
*/
static void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
  u8_t two_bytes[2];
  phys_bytes phys_user, phys_2bytes = vir2phys(two_bytes);
  vir_bytes ecount = (pktsize + 1) & NOT(0x0001);
  int bytes, ix = 0, odd_byte = 0;
  iovec_dat_t *iovp = &dep->de_write_iovec;

  outb_reg0(dep, DP_ISR, ISR_RDC);
  dp_read_setup(dep, ecount, pageno * DP_PAGESIZE);

  do {
	bytes = iovp->iod_iovec[ix].iov_size;
	if (bytes > pktsize) bytes = pktsize;

	phys_user = numap(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);
	if (!phys_user) panic(UmapErrMsg);

	if (odd_byte) {
		phys_copy(phys_user, phys_2bytes + 1, (phys_bytes) 1);
		out_word(dep->de_data_port, *(u16_t *)two_bytes);
		pktsize--;
		bytes--;
		phys_user++;
		odd_byte = 0;
		if (!bytes) continue;
	}
	ecount = bytes & NOT(0x0001);
	if (ecount != 0) {
		phys_outsw(dep->de_data_port, phys_user, ecount);
		pktsize -= ecount;
		bytes -= ecount;
		phys_user += ecount;
	}
	if (bytes) {
		phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);
		pktsize--;
		bytes--;
		phys_user++;
		odd_byte = 1;
	}
	if (++ix >= IOVEC_NR) {	/* Next buffer of I/O vector */
		dp_next_iovec(iovp);
		ix = 0;
	}

  }  while (bytes > 0);

  if (odd_byte) out_word(dep->de_data_port, *(u16_t *) two_bytes);
  for (ix = 0; ix < 100; ix++) {
	if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
  }
  if (ix == 100) {
	panic(RdmaErrMsg);
  }
  return;
}
Beispiel #9
0
/*
**  Name:	void dp_pio16_nic2user(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from board to user area (Prog. I/O, 16bits).
*/
static void dp_pio16_nic2user(dpeth_t * dep, int nic_addr, int count)
{
  phys_bytes phys_user;
  vir_bytes ecount;
  int bytes, i;
  u8_t two_bytes[2];
  phys_bytes phys_2bytes;
  int odd_byte;

  ecount = (count + 1) & ~1;
  phys_2bytes = vir2phys(two_bytes);
  odd_byte = 0;

  dp_read_setup(dep, ecount, nic_addr);

  i = 0;
  while (count > 0) {
	if (i >= IOVEC_NR) {
		dp_next_iovec(iovp);
		i = 0;
		continue;
	}
	bytes = iovp->iod_iovec[i].iov_size;
	if (bytes > count) bytes = count;

	phys_user = numap(iovp->iod_proc_nr,
			  iovp->iod_iovec[i].iov_addr, bytes);
	if (!phys_user) panic(UmapErrMsg);
	if (odd_byte) {
		phys_copy(phys_2bytes + 1, phys_user, (phys_bytes) 1);
		count--;
		bytes--;
		phys_user++;
		odd_byte = 0;
		if (!bytes) continue;
	}
	ecount = bytes & ~1;
	if (ecount != 0) {
		phys_insw(dep->de_data_port, phys_user, ecount);
		count -= ecount;
		bytes -= ecount;
		phys_user += ecount;
	}
	if (bytes) {
		*(u16_t *) two_bytes = in_word(dep->de_data_port);
		phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);
		count--;
		bytes--;
		phys_user++;
		odd_byte = 1;
	}
  }
  return;
}
Beispiel #10
0
u32_t *alloc_pagetable(phys_bytes *ph)
{
	u32_t *ret;
#define PG_PAGETABLES 24
	static u32_t pagetables[PG_PAGETABLES][256]  __aligned(1024);
	static int pt_inuse = 0;
	if(pt_inuse >= PG_PAGETABLES) panic("no more pagetables");
	assert(sizeof(pagetables[pt_inuse]) == 1024);
	ret = pagetables[pt_inuse++];
	*ph = vir2phys(ret);
	return ret;
}
Beispiel #11
0
/*===========================================================================*
 *				QueueMess				     * 
 *===========================================================================*/
PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
{
	int k;
	phys_bytes addr;
	NOREC_ENTER(queuemess);
	/* Queue a message from the src process (in memory) to the dst
	 * process (using dst process table entry). Do actual copy to
	 * kernel here; it's an error if the copy fails into kernel.
	 */
	vmassert(!(dst->p_misc_flags & MF_DELIVERMSG));	
	vmassert(dst->p_delivermsg_lin);
	vmassert(isokendpt(ep, &k));

#if 0
	if(INMEMORY(dst)) {
		PHYS_COPY_CATCH(msg_lin, dst->p_delivermsg_lin,
			sizeof(message), addr);
		if(!addr) {
			PHYS_COPY_CATCH(vir2phys(&ep), dst->p_delivermsg_lin,
				sizeof(ep), addr);
			if(!addr) {
				NOREC_RETURN(queuemess, OK);
			}
		}
	}
#endif

	PHYS_COPY_CATCH(msg_lin, vir2phys(&dst->p_delivermsg), sizeof(message), addr);
	if(addr) {
		NOREC_RETURN(queuemess, EFAULT);
	}

	dst->p_delivermsg.m_source = ep;
	dst->p_misc_flags |= MF_DELIVERMSG;

	NOREC_RETURN(queuemess, OK);
}
Beispiel #12
0
/*===========================================================================*
 *				main                                         *
 *===========================================================================*/
PUBLIC void main()
{
/* Start the ball rolling. */
  struct boot_image *ip;	/* boot image pointer */
  register struct proc *rp;	/* process pointer */
  register struct priv *sp;	/* privilege structure pointer */
  register int i, s;
  int hdrindex;			/* index to array of a.out headers */
  phys_clicks text_base;
  vir_clicks text_clicks, data_clicks;
  reg_t ktsb;			/* kernel task stack base */
  struct exec e_hdr;		/* for a copy of an a.out header */

  /* Initialize the interrupt controller. */
  intr_init(1);

  /* Clear the process table. Anounce each slot as empty and set up mappings 
   * for proc_addr() and proc_nr() macros. Do the same for the table with 
   * privilege structures for the system processes. 
   */
  for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
  	rp->p_rts_flags = SLOT_FREE;		/* initialize free slot */
	rp->p_nr = i;				/* proc number from ptr */
        (pproc_addr + NR_TASKS)[i] = rp;        /* proc ptr from number */
  }
  for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
	sp->s_proc_nr = NONE;			/* initialize as free */
	sp->s_id = i;				/* priv structure index */
	ppriv_addr[i] = sp;			/* priv ptr from number */
  }

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

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

  for (i=0; i < NR_BOOT_PROCS; ++i) {
	ip = &image[i];				/* process' attributes */
	rp = proc_addr(ip->proc_nr);		/* get process pointer */
	rp->p_max_priority = ip->priority;	/* max scheduling priority */
	rp->p_priority = ip->priority;		/* current priority */
	rp->p_quantum_size = ip->quantum;	/* quantum size in ticks */
	rp->p_ticks_left = ip->quantum;		/* current credit */
	strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
	(void) get_priv(rp, (ip->flags & SYS_PROC));    /* assign structure */
	priv(rp)->s_flags = ip->flags;			/* process flags */
	priv(rp)->s_trap_mask = ip->trap_mask;		/* allowed traps */
	priv(rp)->s_call_mask = ip->call_mask;		/* kernel call mask */
	priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to;	/* restrict targets */
	if (iskerneln(proc_nr(rp))) {		/* part of the kernel? */ 
		if (ip->stksize > 0) {		/* HARDWARE stack size is 0 */
			rp->p_priv->s_stack_guard = (reg_t *) ktsb;
			*rp->p_priv->s_stack_guard = STACK_GUARD;
		}
		ktsb += ip->stksize;	/* point to high end of stack */
		rp->p_reg.sp = ktsb;	/* this task's initial stack ptr */
		text_base = kinfo.code_base >> CLICK_SHIFT;
					/* processes that are in the kernel */
		hdrindex = 0;		/* all use the first a.out header */
	} else {
		hdrindex = 1 + i-NR_TASKS;	/* servers, drivers, INIT */
	}

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

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

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

	/* Code and data segments must be allocated in protected mode. */
	alloc_segments(rp);
  }
Beispiel #13
0
PUBLIC __dead void arch_shutdown(int how)
{
	u16_t magic;
	vm_stop();

	/* Mask all interrupts, including the clock. */
	outb( INT_CTLMASK, ~0);

	if(minix_panicing) {
		unsigned char unused_ch;
		/* We're panicing? Then retrieve and decode currently
		 * loaded segment selectors.
		 */
		printseg("cs: ", 1, get_cpulocal_var(proc_ptr), read_cs());
		printseg("ds: ", 0, get_cpulocal_var(proc_ptr), read_ds());
		if(read_ds() != read_ss()) {
			printseg("ss: ", 0, NULL, read_ss());
		}

		/* Printing is done synchronously over serial. */
		if (do_serial_debug)
			reset();

		/* Print accumulated diagnostics buffer and reset. */
		mb_cls();
		mb_print("Minix panic. System diagnostics buffer:\n\n");
		mb_print(kmess_buf);
		mb_print("\nSystem has panicked, press any key to reboot");
		while (!mb_read_char(&unused_ch))
			;
		reset();
	}

#if USE_BOOTPARAM
	if (how == RBT_DEFAULT) {
		how = mon_return ? RBT_HALT : RBT_RESET;
	}

	if(how != RBT_RESET) {
		/* return to boot monitor */

		outb( INT_CTLMASK, 0);            
		outb( INT2_CTLMASK, 0);
        
		/* Return to the boot monitor. Set
		 * the program if not already done.
		 */
		if (how != RBT_MONITOR)
			arch_set_params("", 1);

		if (mon_return)
			arch_monitor();

		/* monitor command with no monitor: reset or poweroff 
		 * depending on the parameters
		 */
		if (how == RBT_MONITOR) {
			how = RBT_RESET;
		}
	}

	switch (how) {
		case RBT_REBOOT:
		case RBT_RESET:
			/* Reset the system by forcing a processor shutdown. 
			 * First stop the BIOS memory test by setting a soft
			 * reset flag.
			 */
			magic = STOP_MEM_CHECK;
			phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR,
       		 	SOFT_RESET_FLAG_SIZE);
			reset();
			NOT_REACHABLE;

		case RBT_HALT:
			/* Poweroff without boot monitor */
			arch_bios_poweroff();
			NOT_REACHABLE;

		case RBT_PANIC:
			/* Allow user to read panic message */
			for (; ; ) halt_cpu();
			NOT_REACHABLE;

		default:	
			/* Not possible! trigger panic */
			assert(how != RBT_MONITOR);
			assert(how != RBT_DEFAULT);
			assert(how < RBT_INVALID);
			panic("unexpected value for how: %d", how);
			NOT_REACHABLE;
	}
#else /* !USE_BOOTPARAM */
	/* Poweroff without boot monitor */
	arch_bios_poweroff();
#endif

	NOT_REACHABLE;
}
Beispiel #14
0
phys_bytes pg_load()
{
	phys_bytes phpagedir = vir2phys(pagedir);
        write_cr3(phpagedir);
	return phpagedir;
}
Beispiel #15
0
PUBLIC __dead void arch_shutdown(int how)
{
    static char mybuffer[sizeof(params_buffer)];
    u16_t magic;
    vm_stop();

    /* Mask all interrupts, including the clock. */
    outb( INT_CTLMASK, ~0);

    if(minix_panicing) {
        /* We're panicing? Then retrieve and decode currently
         * loaded segment selectors.
         */
        printseg("cs: ", 1, proc_ptr, read_cs());
        printseg("ds: ", 0, proc_ptr, read_ds());
        if(read_ds() != read_ss()) {
            printseg("ss: ", 0, NULL, read_ss());
        }
    }

    if (how == RBT_DEFAULT) {
        how = mon_return ? RBT_HALT : RBT_RESET;
    }

    if(how != RBT_RESET) {
        /* return to boot monitor */

        outb( INT_CTLMASK, 0);
        outb( INT2_CTLMASK, 0);

        /* Return to the boot monitor. Set
         * the program if not already done.
         */
        if (how != RBT_MONITOR)
            arch_set_params("", 1);
        if(minix_panicing) {
            int source, dest;
            const char *lead = "echo \\n*** kernel messages:\\n";
            const int leadlen = strlen(lead);
            strcpy(mybuffer, lead);

#define DECSOURCE source = (source - 1 + _KMESS_BUF_SIZE) % _KMESS_BUF_SIZE

            dest = sizeof(mybuffer)-1;
            mybuffer[dest--] = '\0';

            source = kmess.km_next;
            DECSOURCE;

            while(dest >= leadlen) {
                const char c = kmess.km_buf[source];
                if(c == '\n') {
                    mybuffer[dest--] = 'n';
                    mybuffer[dest] = '\\';
                } else if(isprint(c) &&
                          c != '\'' && c != '"' &&
                          c != '\\' && c != ';') {
                    mybuffer[dest] = c;
                } else	mybuffer[dest] = ' ';

                DECSOURCE;
                dest--;
            }

            arch_set_params(mybuffer, strlen(mybuffer)+1);
        }
        if (mon_return)
            arch_monitor();

        /* monitor command with no monitor: reset or poweroff
         * depending on the parameters
         */
        if (how == RBT_MONITOR) {
            mybuffer[0] = '\0';
            arch_get_params(mybuffer, sizeof(mybuffer));
            if (strstr(mybuffer, "boot") ||
                    strstr(mybuffer, "menu") ||
                    strstr(mybuffer, "reset"))
                how = RBT_RESET;
            else
                how = RBT_HALT;
        }
    }

    switch (how) {
    case RBT_REBOOT:
    case RBT_RESET:
        /* Reset the system by forcing a processor shutdown.
         * First stop the BIOS memory test by setting a soft
         * reset flag.
         */
        magic = STOP_MEM_CHECK;
        phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR,
                  SOFT_RESET_FLAG_SIZE);
        reset();
        NOT_REACHABLE;

    case RBT_HALT:
        /* Poweroff without boot monitor */
        arch_bios_poweroff();
        NOT_REACHABLE;

    case RBT_PANIC:
        /* Allow user to read panic message */
        for (; ; ) halt_cpu();
        NOT_REACHABLE;

    default:
        /* Not possible! trigger panic */
        assert(how != RBT_MONITOR);
        assert(how != RBT_DEFAULT);
        assert(how < RBT_INVALID);
        panic("unexpected value for how: %d", how);
        NOT_REACHABLE;
    }

    NOT_REACHABLE;
}
Beispiel #16
0
/*init the first process*/
static void init_user_process()
{
    TASK* p_task = NULL;
    /*struct task_struct* p_proc	= proc_table + NR_SYSTEM_PROCS;*/
    struct task_struct *tsk = NULL;
    union thread_union *thread_union = NULL;

    int i,j,prio, eflags;
    char privilege,rpl;

    unsigned int k_base,k_limit;
    get_kernel_map(&k_base,&k_limit);

    /*privilege = PRIVILEGE_USER;*/
    /*rpl = RPL_USER;*/
    /*eflags = 0x1202;*/
    /*prio = USER_PRIO;*/

    privilege = PRIVILEGE_TASK;
    rpl = RPL_TASK;
    eflags = 0x1202;
    prio = KERNEL_PRIOR;

    /*for(i = 0;i < NR_USER_PROCS; ++i,++p_proc)*/
    for(i = 0;i < NR_USER_PROCS; ++i)
    {
        p_task = user_proc_table + i ;

        tsk = (struct task_struct *)kmem_get_obj(tsk_cachep);
        if(tsk == NULL)
            return;

        thread_union = (union thread_union*)kmem_get_obj(thread_union_cachep);
        if(thread_union == NULL)
            return;

        thread_union->thread_info.task = tsk;

        tsk->state = TASK_RUNNING;
        strcpy(tsk->command, p_task->command);	// name of the process
        if((tsk->pid = get_pidmap()) < 0)
            return;
        tsk->parent = NULL;
        tsk->next = tsk->sibling = NULL;

        for(j = 0; j < NR_SIGNALS;++j)
        {
            tsk->sig_action[j].sa_flags = 0;
            tsk->sig_action[j].sa_handler = do_signal;
        }
        for(j = 0;j < NR_OPEN; ++j)
        {
            tsk->filp[j] = NULL;
        }
        tsk->signal = 0x0; //设置信号为空
        tsk->ldt_sel = selector_ldt;

        init_descriptor(&gdt[selector_ldt>>3],vir2phys(seg2phys(SELECTOR_KERNEL_DS), tsk->ldts),LDT_SIZE * sizeof(DESCRIPTOR) - 1,DA_LDT);

        tsk->ldts[INDEX_LDT_C] = gdt[SELECTOR_KERNEL_CS >> 3];
        tsk->ldts[INDEX_LDT_C].attr1 = DA_C | privilege << 5;// change the DPL
        tsk->ldts[INDEX_LDT_D] = gdt[SELECTOR_KERNEL_DS >> 3];
        tsk->ldts[INDEX_LDT_D].attr1 = DA_DRW | privilege<< 5;// change the DPL

        /*init_descriptor(&tsk->ldts[INDEX_LDT_C],0,(k_base + k_limit) >> LIMIT_4K_SHIFT,DA_32 | DA_LIMIT_4K | DA_C| privilege <<5);*/
        /*init_descriptor(&tsk->ldts[INDEX_LDT_D],0,(k_base + k_limit) >> LIMIT_4K_SHIFT,DA_32 | DA_LIMIT_4K | DA_DRW | privilege << 5);*/

        char *stack = (char *)thread_union->stack;
        tsk->regs.esp = (unsigned int)(stack + sizeof(union thread_union));

        tsk->regs.cs = (unsigned int)(((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.ds = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.es = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.fs = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.ss = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.gs = (unsigned int)((SELECTOR_KERNEL_GS & SA_RPL_MASK) | rpl);
        tsk->regs.eip = (unsigned int)p_task->initial_eip;

        tsk->regs.eflags = eflags;	
        tsk->ticks = tsk->priority = prio;

        tsk->sched_entity.vruntime = i;
        tsk->sched_class = &rr_sched;
        tsk->sched_class->enqueue_task(&(sched_rq),tsk,0,0);

        p_task++;
        selector_ldt += 1 << 3;
    }

    k_reenter	= 0;
    ticks		= 0;
}
Beispiel #17
0
/*init the first process*/
static void init_kernel_thread()
{
    TASK* p_task = NULL;
    /*struct task_struct* p_proc	= proc_table;*/
    struct task_struct *tsk = NULL;
    union thread_union *thread_union = NULL;
    char* p_task_stack = task_stack + STACK_SIZE_TOTAL;
    int i,j,prio,eflags;
    char privilege,rpl;

    unsigned int k_base,k_limit;
    get_kernel_map(&k_base,&k_limit);

    privilege = PRIVILEGE_TASK;
    rpl = RPL_TASK;
    eflags = 0x1202;
    prio = KERNEL_PRIOR;

    printk("  PrettyOS SoftIRQ.");
    /*printk("  [email protected] .\n");*/
    /*printk("  UESTC.\n");*/
    /*disp_str("\t\tprocess init begins\n");*/
    /*for(i = 0;i < NR_SYSTEM_PROCS ;++i, ++p_proc)*/
    for(i = 0;i < NR_SYSTEM_PROCS ;++i)
    {
        p_task = task_table + i;

        tsk = (struct task_struct *)kmem_get_obj(tsk_cachep);
        if(tsk == NULL)
            return;

        thread_union = (union thread_union*)kmem_get_obj(thread_union_cachep);
        if(thread_union == NULL)
            return;

        thread_union->thread_info.task = tsk;

        tsk->state = TASK_RUNNING;
        strcpy(tsk->command, p_task->command);	// name of the process
        if((tsk->pid = get_pidmap()) < 0)
            return;
        tsk->parent = NULL;
        tsk->next = tsk->sibling = NULL;

        /*proc_table[0].nr_tty = 0;		// tty */
        for(j = 0; j < NR_SIGNALS;++j)
        {
            tsk->sig_action[j].sa_flags = 0;
            tsk->sig_action[j].sa_handler = do_signal;
        }
        for(j = 0;j < NR_OPEN; ++j)
        {
            tsk->filp[j] = NULL;
        }
        tsk->signal = 0x0; //设置信号为空
        tsk->ldt_sel = selector_ldt;

        init_descriptor(&gdt[selector_ldt>>3],vir2phys(seg2phys(SELECTOR_KERNEL_DS), tsk->ldts),LDT_SIZE * sizeof(DESCRIPTOR) - 1,DA_LDT);

        init_descriptor(&tsk->ldts[INDEX_LDT_C],0,(k_base + k_limit) >> LIMIT_4K_SHIFT,DA_32 | DA_LIMIT_4K | DA_C| privilege <<5);
        init_descriptor(&tsk->ldts[INDEX_LDT_D],0,(k_base + k_limit) >> LIMIT_4K_SHIFT,DA_32 | DA_LIMIT_4K | DA_DRW | privilege << 5);
        tsk->regs.esp	= (unsigned int)p_task_stack;
        p_task_stack -= STACK_SIZE_DEFAULT;

        tsk->regs.cs = (unsigned int)(((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.ds = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.es = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.fs = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.ss = (unsigned int)(((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl);
        tsk->regs.gs = (unsigned int)((SELECTOR_KERNEL_GS & SA_RPL_MASK) | rpl);
        tsk->regs.eip = (unsigned int)p_task->initial_eip;

        tsk->regs.eflags = eflags;	
        tsk->ticks = tsk->priority = prio;
        tsk->sched_entity.vruntime = i;
        tsk->sched_class = &rr_sched;
        if(tsk->pid != INIT_PID)
            tsk->sched_class->enqueue_task(&(sched_rq),tsk,0,0);

        p_task++;
        selector_ldt += 1 << 3;
    }

    k_reenter	= 0;
    ticks		= 0;
}
Beispiel #18
0
//--------------------------------------------------------------------------
//  init_prot
//--------------------------------------------------------------------------
void init_prot()
{
    init_8259A();

    // 全部初始化成中断门(没有陷阱门)
    init_idt_desc(INT_VECTOR_DIVIDE, DA_386IGate,
                  divide_error, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_DEBUG, DA_386IGate,
                  single_step_exception, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_NMI, DA_386IGate,
                  nmi, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_BREAKPOINT, DA_386IGate,
                  breakpoint_exception, PRIVILEGE_USER);

    init_idt_desc(INT_VECTOR_OVERFLOW, DA_386IGate,
                  overflow, PRIVILEGE_USER);

    init_idt_desc(INT_VECTOR_BOUNDS, DA_386IGate,
                  bounds_check, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_INVAL_OP, DA_386IGate,
                  inval_opcode, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_COPROC_NOT, DA_386IGate,
                  copr_not_available, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_DOUBLE_FAULT, DA_386IGate,
                  double_fault, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_COPROC_SEG, DA_386IGate,
                  copr_seg_overrun, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_INVAL_TSS, DA_386IGate,
                  inval_tss, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_SEG_NOT, DA_386IGate,
                  segment_not_present, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_STACK_FAULT, DA_386IGate,
                  stack_exception, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_PROTECTION, DA_386IGate,
                  general_protection, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_PAGE_FAULT, DA_386IGate,
                  page_fault, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_COPROC_ERR, DA_386IGate,
                  copr_error, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate,
                  hwint00, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate,
                  hwint01, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate,
                  hwint02, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate,
                  hwint03, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate,
                  hwint04, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate,
                  hwint05, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate,
                  hwint06, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate,
                  hwint07, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate,
                  hwint08, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate,
                  hwint09, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate,
                  hwint10, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate,
                  hwint11, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate,
                  hwint12, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate,
                  hwint13, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate,
                  hwint14, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate,
                  hwint15, PRIVILEGE_KRNL);

    init_idt_desc(INT_VECTOR_SYS_CALL,  DA_386IGate,
              sys_call, PRIVILEGE_USER);
        
    //填充 GDT 中 TSS 这个描述符
    memset(&tss, 0, sizeof(tss));
    tss.ss0     = SELECTOR_KERNEL_DS;
    init_descriptor(&gdt[INDEX_TSS],
                    vir2phys(seg2phys(SELECTOR_KERNEL_DS), &tss),
                    sizeof(tss) - 1,
                    DA_386TSS);
    tss.iobase  = sizeof(tss);  // 没有I/O许可位图

    // 填充 GDT 中进程的 LDT 的描述符
    int i;
    PROCESS* p_proc = proc_table;
    u16 selector_ldt = INDEX_LDT_FIRST << 3;
    for(i=0;i<NR_TASKS;i++){
        init_descriptor(&gdt[selector_ldt>>3],
                        vir2phys(seg2phys(SELECTOR_KERNEL_DS),
                        proc_table[i].ldts),
                        LDT_SIZE * sizeof(DESCRIPTOR) - 1,
                        DA_LDT);
        p_proc++;
        selector_ldt += 1 << 3;
    }

}
Beispiel #19
0
/**
* \brief Set up tables for protected mode
*        All GDT slots are allocated at compile time
*/
void prot_init()
{
  struct gate_table_s *gtp;
  struct desctableptr_s *dtp;
  unsigned ldt_index;
  struct proc *rp;
  static struct gate_table_s {
    void (*gate)(void);
    unsigned char vec_nr;
    unsigned char privilege;
  } gate_table[] = {
    { divide_error, DIVIDE_VECTOR, INTR_PRIVILEGE },
    { single_step_exception, DEBUG_VECTOR, INTR_PRIVILEGE },
    { nmi, NMI_VECTOR, INTR_PRIVILEGE },
    { breakpoint_exception, BREAKPOINT_VECTOR, USER_PRIVILEGE },
    { overflow, OVERFLOW_VECTOR, USER_PRIVILEGE },
    { bounds_check, BOUNDS_VECTOR, INTR_PRIVILEGE },
    { inval_opcode, INVAL_OP_VECTOR, INTR_PRIVILEGE },
    { copr_not_available, COPROC_NOT_VECTOR, INTR_PRIVILEGE },
    { double_fault, DOUBLE_FAULT_VECTOR, INTR_PRIVILEGE },
    { copr_seg_overrun, COPROC_SEG_VECTOR, INTR_PRIVILEGE },
    { inval_tss, INVAL_TSS_VECTOR, INTR_PRIVILEGE },
    { segment_not_present, SEG_NOT_VECTOR, INTR_PRIVILEGE },
    { stack_exception, STACK_FAULT_VECTOR, INTR_PRIVILEGE },
    { general_protection, PROTECTION_VECTOR, INTR_PRIVILEGE },
    { page_fault, PAGE_FAULT_VECTOR, INTR_PRIVILEGE },
    { copr_error, COPROC_ERR_VECTOR, INTR_PRIVILEGE },
    { hwint00, IRQ0_VECTOR + CLOCK_IRQ, INTR_PRIVILEGE },
    { hwint01, IRQ0_VECTOR + KEYBOARD_IRQ, INTR_PRIVILEGE },
    { hwint02, IRQ0_VECTOR + CASCADE_IRQ, INTR_PRIVILEGE },
    { hwint03, IRQ0_VECTOR + ETHER_IRQ, INTR_PRIVILEGE },
    { hwint04, IRQ0_VECTOR + RS232_IRQ, INTR_PRIVILEGE },
    { hwint05, IRQ0_VECTOR + 5, INTR_PRIVILEGE },
    { hwint06, IRQ0_VECTOR + 6, INTR_PRIVILEGE },
    { hwint07, IRQ0_VECTOR + 7, INTR_PRIVILEGE },
    { hwint08, IRQ0_VECTOR + 8, INTR_PRIVILEGE },
    { hwint09, IRQ0_VECTOR + 9, INTR_PRIVILEGE },
    { hwint10, IRQ0_VECTOR + 10, INTR_PRIVILEGE },
    { hwint11, IRQ0_VECTOR + 11, INTR_PRIVILEGE },
    { hwint12, IRQ0_VECTOR + 12, INTR_PRIVILEGE },
    { hwint13, IRQ0_VECTOR + 13, INTR_PRIVILEGE },
    { hwint14, IRQ0_VECTOR + IDE_IRQ, INTR_PRIVILEGE },
    { hwint15, IRQ0_VECTOR + 15, INTR_PRIVILEGE },
    { s_call, SYS_VECTOR, USER_PRIVILEGE },	// system call
    { level0_call, LEVEL0_VECTOR, TASK_PRIVILEGE },
  };

  /* since it is now in protected mode and it enters protected mode
   * in boot loader where global segment descriptor is set up to
   * map all physical memory, that is base is 0, and limit is MAX
   * physical memory - 1
   *
   * so here when apply vir2phys ( kinfo.data_base + vir ), still
   * get vir
   */

  // Build gdt and idt pointers in GDT where the BIOS expects them
  dtp = (struct desctableptr_s *) &gdt[GDT_INDEX];
  *((u16_t *) dtp->limit) = (sizeof gdt) - 1;
  *((u32_t *) dtp->base) = vir2phys(gdt);

  dtp = (struct desctableptr_s *) &gdt[IDT_INDEX];
  *((u16_t *) dtp->limit) = (sizeof idt) - 1;
  *((u32_t *) dtp->base) = vir2phys(idt);

  // Build segment descriptors for tasks and interrupt handlers
  init_codeseg(&gdt[CS_INDEX], kinfo.code_base, kinfo.code_size, INTR_PRIVILEGE);
  init_dataseg(&gdt[DS_INDEX], kinfo.data_base, kinfo.data_size, INTR_PRIVILEGE);
  init_dataseg(&gdt[ES_INDEX], 0L, 0, TASK_PRIVILEGE);

  // Build scratch descriptors for functions in klib88
  init_dataseg(&gdt[DS_286_INDEX], 0L, 0, TASK_PRIVILEGE);
  init_dataseg(&gdt[ES_286_INDEX], 0L, 0, TASK_PRIVILEGE);

  /* Build local descriptors in GDT for LDT's in process table.
   * The LDT's are allocated at compile time in the process table, and
   * initialized whenever a process' map is initialized or changed.
   */
  for (rp = BEG_PROC_ADDR, ldt_index = FIRST_LDT_INDEX; rp < END_PROC_ADDR; ++rp, ldt_index++)
  {
    init_dataseg(&gdt[ldt_index], vir2phys(rp->p_ldt), sizeof(rp->p_ldt), INTR_PRIVILEGE);
    gdt[ldt_index].access = PRESENT | LDT;
    rp->p_ldt_sel = ldt_index * DESC_SIZE;
  }

  /* Build main TSS.
   * This is used only to record the stack pointer to be used after an interrupt.
   * Actually it points to stackframe of proc
   *
   * The pointer is set up so that an interrupt automatically saves the
   * current process's registers eip:cs:eflags:esp:ss in the correct slots in the
   * process table.
   */
  tss.ss0 = DS_SELECTOR;
  init_dataseg(&gdt[TSS_INDEX], vir2phys(&tss), sizeof(tss), INTR_PRIVILEGE);
  gdt[TSS_INDEX].access = PRESENT | (INTR_PRIVILEGE << DPL_SHIFT) | TSS_TYPE;

  // Build descriptors for interrupt gates in IDT
  for (gtp = &gate_table[0]; gtp < &gate_table[sizeof gate_table / sizeof gate_table[0]]; ++gtp)
  {
    int_gate(gtp->vec_nr, (vir_bytes) gtp->gate,
             PRESENT | INT_GATE_TYPE | (gtp->privilege << DPL_SHIFT));
  }

  // Complete building of main TSS
  tss.iobase = sizeof tss;	// empty i/o permissions map
}
Beispiel #20
0
		lock_enqueue(rp);		/* add to scheduling queues */
	} else {
		rp->p_rts_flags = NO_MAP;	/* prevent from running */
	}

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

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

  /* MINIX is now ready. All boot image processes are on the ready queue.
   * Return to the assembly code to start running the current process. 
   */
  bill_ptr = proc_addr(IDLE);		/* it has to point somewhere */
  announce();				/* print MINIX startup banner */
  restart();
}

/*===========================================================================*
Beispiel #21
0
/*===========================================================================*
 *				main                                         *
 *===========================================================================*/
PUBLIC void main()
{
/* Start the ball rolling. */
  struct boot_image *ip;	/* boot image pointer */
  register struct proc *rp;	/* process pointer */
  register struct priv *sp;	/* privilege structure pointer */
  register int i, s;
  // a.out 头部数组的索引.
  int hdrindex;			/* index to array of a.out headers */
  phys_clicks text_base;
  vir_clicks text_clicks, data_clicks;
  // 内核任务栈的基地址(低端)
  reg_t ktsb;			/* kernel task stack base */
  // 用来放置 a.out 头部的一个副本.
  struct exec e_hdr;		/* for a copy of an a.out header */

  /* Initialize the interrupt controller. */
  // 初始化 8259 中断控制器芯片.
  intr_init(1);

  /* Clear the process table. Anounce each slot as empty and set up mappings 
   * for proc_addr() and proc_nr() macros. Do the same for the table with 
   * privilege structures for the system processes. 
   */
  // 初如化进程表与进程指针表.
  // BEG_PROC_ADDR: 进程表地址;
  for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
	  // 将进程表中每一项都设置为空闲.
  	rp->p_rts_flags = SLOT_FREE;		/* initialize free slot */
	// 进程号, i 的初值为 -NR_TASKS, 可见系统任务拥有负的进程号
	rp->p_nr = i;				/* proc number from ptr */
	// 建立进程数组与进程指针数组之间的映射关系
        (pproc_addr + NR_TASKS)[i] = rp;        /* proc ptr from number */
  }
  // 初始化优先级表
  for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
	sp->s_proc_nr = NONE;			/* initialize as free */
	sp->s_id = i;				/* priv structure index */
	// 建立特权级表与特权级指针表之间的映射关系
	ppriv_addr[i] = sp;			/* priv ptr from number */
  }

  /* Set up proc table entries for tasks and servers.  The stacks of the
   * kernel tasks are initialized to an array in data space.  The stacks
   * of the servers have been added to the data segment by the monitor, so
   * the stack pointer is set to the end of the data segment.  All the
   * processes are in low memory on the 8086.  On the 386 only the kernel
   * is in low memory, the rest is loaded in extended memory.
   */
  /*
   * 为任务和服务进程设置进程表项. 内核任务的栈被初始化成一个在数据空间中的
   * 数组. 服务进程的栈已经由控制器添加到数据段中, 所有它们的栈指针开始时
   * 指向数据段的末尾. 所有的进程都在 8086 的低内存. 对于 386, 只有内核在
   * 低内存, 剩下的都在扩展内存中.
   */

  /* Task stacks. */
  /* 任务栈 */
  ktsb = (reg_t) t_stack;
 // 为那些包含在系统引导映像文件中的程序分配进程表项.
  for (i=0; i < NR_BOOT_PROCS; ++i) {
	ip = &image[i];				/* process' attributes */
	// 获取进程指针
	rp = proc_addr(ip->proc_nr);		/* get process pointer */
	// 最大调度优先级
	rp->p_max_priority = ip->priority;	/* max scheduling priority */
	// 当前调度优先级
	rp->p_priority = ip->priority;		/* current priority */
	// 时间片原子值
	rp->p_quantum_size = ip->quantum;	/* quantum size in ticks */
	// 剩余时间片
	rp->p_ticks_left = ip->quantum;		/* current credit */
	// 将程序名复制到进程表项中
	strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
	// 为进程分配一个特权级结构体, 即 从系统特权级表中分配一项
	(void) get_priv(rp, (ip->flags & SYS_PROC));    /* assign structure */
	// 初始化特权级结构体的标志.
	priv(rp)->s_flags = ip->flags;			/* process flags */
	// 初始化特权级结构体的 允许的系统调用陷井
	priv(rp)->s_trap_mask = ip->trap_mask;		/* allowed traps */
	priv(rp)->s_call_mask = ip->call_mask;		/* kernel call mask */
	// 初始化进程的消息发送位图
	priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to;	/* restrict targets */
	// 如果进程是内核任务
	if (iskerneln(proc_nr(rp))) {		/* part of the kernel? */ 
		// 如果进程的栈大小大于 0, 设置进程的栈警戒字, 
		if (ip->stksize > 0) {		/* HARDWARE stack size is 0 */
			// 设置内核任务栈警戒字指针.
			rp->p_priv->s_stack_guard = (reg_t *) ktsb;
			// 指针运算符(->) 要比取值运行符 (*) 的优先级要高.
			// 等价于: 
			// *(rp->p_priv->s_stack_guard) = STACK_GUARD
			// 效果是在栈的最顶端(在低地址)放置一个特殊值,
			// 这个值就是栈警戒字.
			*rp->p_priv->s_stack_guard = STACK_GUARD;
		}
		ktsb += ip->stksize;	/* point to high end of stack */
		// 初始进程的栈指针
		rp->p_reg.sp = ktsb;	/* this task's initial stack ptr */
		// kinfo ???
		// 内核代码的基地址右移 CLICK_SHIFT 位, 赋给 text_base.
		text_base = kinfo.code_base >> CLICK_SHIFT;
					/* processes that are in the kernel */
		// 内核任务使用同一个 a.out 头部信息
		hdrindex = 0;		/* all use the first a.out header */
	} else {
		// 非内核任务, 计算它的 a.out 头部数组索引, 因为 0 号项
		// 留给了内核任务, 所以需 加 1.
		hdrindex = 1 + i-NR_TASKS;	/* servers, drivers, INIT */
	}

	/* The bootstrap loader created an array of the a.out headers at
	 * absolute address 'aout'. Get one element to e_hdr.
	 */
	/*
	 * 引导加载程序会在绝对地址 'aout' 处放置一个 a.out 头部数组.
	 * 从中取一项复制到 e_hdr.
	 */
	phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
						(phys_bytes) A_MINHDR);
	/* Convert addresses to clicks and build process memory map */
	/* 将地址转换为以 click 为单位, 并建立进程内存映射 */
	// 既然这里要设置 text_base, 那 146 行附近的 
	// text_base = kinfo.code_base >> CLICK_SHIFT;
	// 岂不是多余的??
	// 将 a.out 头部的符号表大小右移 CLICK_SHIFT 位,赋给 text_base.
	text_base = e_hdr.a_syms >> CLICK_SHIFT;
	// 计算程序文本段大小, 以 click 为单位, 上取整.
	text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
	// 如果 a.out 头部指明它的 I/D 是合并的 ???
	if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0;	   /* common I&D */
	// 计算程序占用的内存量, 以 click 为单位, 上取整.
	data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
	// 初始化进程的内存映射数据结构
	rp->p_memmap[T].mem_phys = text_base;
	rp->p_memmap[T].mem_len  = text_clicks;
	rp->p_memmap[D].mem_phys = text_base + text_clicks;
	rp->p_memmap[D].mem_len  = data_clicks;
	rp->p_memmap[S].mem_phys = text_base + text_clicks + data_clicks;
	rp->p_memmap[S].mem_vir  = data_clicks;	/* empty - stack is in data */

	/* Set initial register values.  The processor status word for tasks 
	 * is different from that of other processes because tasks can
	 * access I/O; this is not allowed to less-privileged processes 
	 */
	/*
	 * 设置寄存器的初始值. 与其他进程相比, 内核任务的处理器状态字
	 * 稍有不同, 因为内核任务可以访问 I/O; 而对于非特权进来来说, 这是不
	 * 允许的.
	 */
	// 初始化进程的 PC 和 processor status word.
	rp->p_reg.pc = (reg_t) ip->initial_pc;
	rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;

	/* Initialize the server stack pointer. Take it down one word
	 * to give crtso.s something to use as "argc".
	 */
	/*
	 * 初始化服务器进程的栈指针. 下移一个字的空间, 使得 crtso.s 有
	 * 空间放置 "argc".
	 */
	if (isusern(proc_nr(rp))) {		/* user-space process? */ 
		rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
				rp->p_memmap[S].mem_len) << CLICK_SHIFT;
		rp->p_reg.sp -= sizeof(reg_t);
	}
	
	/* Set ready. The HARDWARE task is never ready. */
	if (rp->p_nr != HARDWARE) {
		// 如果进程不是 HARDWARE, 清空进程标志, 并加入调度队列.
		rp->p_rts_flags = 0;		/* runnable if no flags */
		lock_enqueue(rp);		/* add to scheduling queues */
	} else {
		// 对于  HARDWARE 任务, 则阻止其运行. ???
		rp->p_rts_flags = NO_MAP;	/* prevent from running */
	}

	/* Code and data segments must be allocated in protected mode. */
	/* 数据与代码段必须在保护模式下分配 */
	alloc_segments(rp);
  }
Beispiel #22
0
void pg_info(reg_t *pagedir_ph, u32_t **pagedir_v)
{
	*pagedir_ph = vir2phys(pagedir);
	*pagedir_v = pagedir;
}
Beispiel #23
0
/*===========================================================================*
 *                                   main                                    *
 *===========================================================================*/
PUBLIC void main()
{
/* Start the ball rolling. */

  register struct proc *rp;
  register int t;
  int hdrindex;
  phys_clicks text_base;
  vir_clicks text_clicks;
  vir_clicks data_clicks;
  phys_bytes phys_b;
  reg_t ktsb;			/* kernel task stack base */
  struct memory *memp;
  struct tasktab *ttp;
  struct exec e_hdr;

  licznik_elementow = 0;

  /* Initialize the interrupt controller. */
  intr_init(1);

  /* Interpret memory sizes. */
  mem_init();

  /* Clear the process table.
   * Set up mappings for proc_addr() and proc_number() macros.
   */
  for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
	rp->p_nr = t;		/* proc number from ptr */
        (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
  }

  /* Resolve driver selections in the task table. */
  mapdrivers();

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

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

  for (t = -NR_TASKS; t <= LOW_USER; ++t) {
	rp = proc_addr(t);			/* t's process slot */
	ttp = &tasktab[t + NR_TASKS];		/* t's task attributes */
	strcpy(rp->p_name, ttp->name);
	if (t < 0) {
		if (ttp->stksize > 0) {
			rp->p_stguard = (reg_t *) ktsb;
			*rp->p_stguard = STACK_GUARD;
		}
		ktsb += ttp->stksize;
		rp->p_reg.sp = ktsb;
		text_base = code_base >> CLICK_SHIFT;
					/* tasks are all in the kernel */
		hdrindex = 0;		/* and use the first a.out header */
		rp->p_priority = PPRI_TASK;
	} else {
		hdrindex = 1 + t;	/* MM, FS, INIT follow the kernel */
		rp->p_priority = t < LOW_USER ? PPRI_SERVER : PPRI_USER;
	}

	/* The bootstrap loader has created an array of the a.out headers at
	 * absolute address 'aout'.
	 */
	phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
							(phys_bytes) A_MINHDR);
	text_base = e_hdr.a_syms >> CLICK_SHIFT;
	text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
	if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0;	/* Common I&D */
	data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
	rp->p_map[T].mem_phys = text_base;
	rp->p_map[T].mem_len  = text_clicks;
	rp->p_map[D].mem_phys = text_base + text_clicks;
	rp->p_map[D].mem_len  = data_clicks;
	rp->p_map[S].mem_phys = text_base + text_clicks + data_clicks;
	rp->p_map[S].mem_vir  = data_clicks;	/* empty - stack is in data */

	/* Remove server memory from the free memory list.  The boot monitor
	 * promises to put processes at the start of memory chunks.
	 */
	for (memp = mem; memp < &mem[NR_MEMS]; memp++) {
		if (memp->base == text_base) {
			memp->base += text_clicks + data_clicks;
			memp->size -= text_clicks + data_clicks;
		}
	}

	/* Set initial register values. */
	rp->p_reg.pc = (reg_t) ttp->initial_pc;
	rp->p_reg.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;

	if (t >= 0) {
		/* Initialize the server stack pointer.  Take it down one word
		 * to give crtso.s something to use as "argc".
		 */
		rp->p_reg.sp = (rp->p_map[S].mem_vir +
				rp->p_map[S].mem_len) << CLICK_SHIFT;
		rp->p_reg.sp -= sizeof(reg_t);
	}

	if (!isidlehardware(t)) lock_ready(rp);	/* IDLE, HARDWARE neveready */
	rp->p_flags = 0;

	alloc_segments(rp);
  }
Beispiel #24
0
void init_trap()
{
    int i;
    init_8259A();

    //soft interrupt
    set_trap_gate(INT_VECTOR_DIVIDE,divide_error);
    set_trap_gate(INT_VECTOR_DEBUG,		single_step_exception);
    set_trap_gate(INT_VECTOR_NMI,		nmi);
    set_system_gate(INT_VECTOR_BREAKPOINT,	breakpoint_exception);
    set_system_gate(INT_VECTOR_OVERFLOW, overflow);
    set_system_gate(INT_VECTOR_BOUNDS, bounds_check);
    set_trap_gate(INT_VECTOR_INVAL_OP, inval_opcode);
    set_trap_gate(INT_VECTOR_COPROC_NOT,	copr_not_available);
    set_trap_gate(INT_VECTOR_DOUBLE_FAULT, double_fault);
    set_trap_gate(INT_VECTOR_COPROC_SEG, copr_seg_overrun);
    set_trap_gate(INT_VECTOR_INVAL_TSS, inval_tss);
    set_trap_gate(INT_VECTOR_SEG_NOT, segment_not_present);
    set_trap_gate(INT_VECTOR_STACK_FAULT, stack_exception);
    set_trap_gate(INT_VECTOR_PROTECTION, general_protection);
    set_trap_gate(INT_VECTOR_PAGE_FAULT, page_fault);
    set_trap_gate(INT_VECTOR_COPROC_ERR, copr_error);
    // hard interrupt IRQ0-IRQ15
    set_intr_gate(INT_VECTOR_IRQ0 + 0,	 clock_intr); //clock interrupt
    set_intr_gate(INT_VECTOR_IRQ0 + 1,	 kb_intr); //keyboard interrupt
    set_intr_gate(INT_VECTOR_IRQ0 + 2,	 hwint02);
    set_intr_gate(INT_VECTOR_IRQ0 + 3,	 hwint03);
    set_intr_gate(INT_VECTOR_IRQ0 + 4,	 hwint04);
    set_intr_gate(INT_VECTOR_IRQ0 + 5,	 hwint05);
    set_intr_gate(INT_VECTOR_IRQ0 + 6,	 hwint06);
    set_intr_gate(INT_VECTOR_IRQ0 + 7,	 hwint07);
    set_intr_gate(INT_VECTOR_IRQ8 + 0,	 hwint08);
    set_intr_gate(INT_VECTOR_IRQ8 + 1,	 hwint09);
    set_intr_gate(INT_VECTOR_IRQ8 + 2,	 hwint10);
    set_intr_gate(INT_VECTOR_IRQ8 + 3,	 hwint11);
    set_intr_gate(INT_VECTOR_IRQ8 + 4,	 hwint12);
    set_intr_gate(INT_VECTOR_IRQ8 + 5,	 hwint13);
    set_intr_gate(INT_VECTOR_IRQ8 + 6,	 hd_intr);//hard disk interrupt
    set_intr_gate(INT_VECTOR_IRQ8 + 7,	 hwint15);
    //init 80 interrupt
    set_syscall_gate(INT_VECTOR_SYS_CALL,	 sys_call);

    memset((char *)&tss, 0, sizeof(tss));
    tss.ss0		= SELECTOR_KERNEL_DS;
    //¿¿TSS
    init_descriptor(&gdt[INDEX_TSS],
            vir2phys(seg2phys(SELECTOR_KERNEL_DS), &tss),
            sizeof(tss) - 1,
            DA_386TSS);
    tss.iobase	= sizeof(tss);	
    PROCESS* p_proc	= proc_table;
    t16 selector_ldt = INDEX_LDT_FIRST << 3;

    //¿¿GDT¿¿¿¿¿¿¿LDT 
    for(i=0;i<NR_SYSTEM_PROCS + NR_USER_PROCS;i++)
    {	
        init_descriptor(&gdt[selector_ldt>>3],
                vir2phys(seg2phys(SELECTOR_KERNEL_DS), proc_table[i].ldts),
                LDT_SIZE * sizeof(DESCRIPTOR) - 1,
                DA_LDT);
        p_proc++;
        selector_ldt += 1 << 3;
    }
}