⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpx386.s

📁 Minix比较全的源码
💻 S
📖 第 1 页 / 共 2 页
字号:
# ! This file, mpx386.s, is included by mpx.s when Minix is compiled for ! 32-bit Intel CPUs. The alternative mpx88.s is compiled for 16-bit CPUs.! This file is part of the lowest layer of the MINIX kernel.  (The other part! is "proc.c".)  The lowest layer does process switching and message handling.! Furthermore it contains the assembler startup code for Minix and the 32-bit! interrupt handlers.  It cooperates with the code in "start.c" to set up a ! good environment for main().! Every transition to the kernel goes through this file.  Transitions to the ! kernel may be nested.  The initial entry may be with a system call (i.e., ! send or receive a message), an exception or a hardware interrupt;  kernel ! reentries may only be made by hardware interrupts.  The count of reentries ! is kept in "k_reenter". It is important for deciding whether to switch to ! the kernel stack and for protecting the message passing code in "proc.c".! For the message passing trap, most of the machine state is saved in the! proc table.  (Some of the registers need not be saved.)  Then the stack is! switched to "k_stack", and interrupts are reenabled.  Finally, the system! call handler (in C) is called.  When it returns, interrupts are disabled! again and the code falls into the restart routine, to finish off held-up! interrupts and run the process or task whose pointer is in "proc_ptr".! Hardware interrupt handlers do the same, except  (1) The entire state must! be saved.  (2) There are too many handlers to do this inline, so the save! routine is called.  A few cycles are saved by pushing the address of the! appropiate restart routine for a return later.  (3) A stack switch is! avoided when the stack is already switched.  (4) The (master) 8259 interrupt! controller is reenabled centrally in save().  (5) Each interrupt handler! masks its interrupt line using the 8259 before enabling (other unmasked)! interrupts, and unmasks it after servicing the interrupt.  This limits the! nest level to the number of lines and protects the handler from itself.! For communication with the boot monitor at startup time some constant! data are compiled into the beginning of the text segment. This facilitates ! reading the data at the start of the boot process, since only the first! sector of the file needs to be read.! Some data storage is also allocated at the end of this file. This data ! will be at the start of the data segment of the kernel and will be read! and modified by the boot monitor before the kernel starts.! sections.sect .textbegtext:.sect .rombegrom:.sect .databegdata:.sect .bssbegbss:#include <minix/config.h>#include <minix/const.h>#include <minix/com.h>#include <ibm/interrupt.h>#include <archconst.h>#include "../../const.h"#include "sconst.h"/* Selected 386 tss offsets. */#define TSS3_S_SP0	4! Exported functions! Note: in assembly language the .define statement applied to a function name ! is loosely equivalent to a prototype in C code -- it makes it possible to! link to an entity declared in the assembly code but does not create! the entity..define	_restart.define	save.define	_divide_error.define	_single_step_exception.define	_nmi.define	_breakpoint_exception.define	_overflow.define	_bounds_check.define	_inval_opcode.define	_copr_not_available.define	_double_fault.define	_copr_seg_overrun.define	_inval_tss.define	_segment_not_present.define	_stack_exception.define	_general_protection.define	_page_fault.define	_copr_error.define	_hwint00	! handlers for hardware interrupts.define	_hwint01.define	_hwint02.define	_hwint03.define	_hwint04.define	_hwint05.define	_hwint06.define	_hwint07.define	_hwint08.define	_hwint09.define	_hwint10.define	_hwint11.define	_hwint12.define	_hwint13.define	_hwint14.define	_hwint15.define	_s_call.define	_p_s_call.define	_level0_call! Exported variables..define	begbss.define	begdata.sect .text!*===========================================================================*!*				MINIX					     *!*===========================================================================*MINIX:				! this is the entry point for the MINIX kernel	jmp	over_flags	! skip over the next few bytes	.data2	CLICK_SHIFT	! for the monitor: memory granularityflags:	.data2	0x01FD		! boot monitor flags:				!	call in 386 mode, make bss, make stack,				!	load high, don't patch, will return,				!	uses generic INT, memory vector,				!	new boot code return	nop			! extra byte to sync up disassemblerover_flags:! Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds! right.  The ss descriptor still references the monitor data segment.)	movzx	esp, sp		! monitor stack is a 16 bit stack	push	ebp	mov	ebp, esp	push	esi	push	edi	cmp	4(ebp), 0	! monitor return vector is	jz	noret		! nonzero if return possible	inc	(_mon_return)noret:	mov	(_mon_sp), esp	! save stack pointer for later return! Copy the monitor global descriptor table to the address space of kernel and! switch over to it.  Prot_init() can then update it with immediate effect.	sgdt	(_gdt+GDT_SELECTOR)		! get the monitor gdtr	mov	esi, (_gdt+GDT_SELECTOR+2)	! absolute address of GDT	mov	ebx, _gdt			! address of kernel GDT	mov	ecx, 8*8			! copying eight descriptorscopygdt: eseg	movb	al, (esi)	movb	(ebx), al	inc	esi	inc	ebx	loop	copygdt	mov	eax, (_gdt+DS_SELECTOR+2)	! base of kernel data	and	eax, 0x00FFFFFF			! only 24 bits	add	eax, _gdt			! eax = vir2phys(gdt)	mov	(_gdt+GDT_SELECTOR+2), eax	! set base of GDT	lgdt	(_gdt+GDT_SELECTOR)		! switch over to kernel GDT! Locate boot parameters, set up kernel segment registers and stack.	mov	ebx, 8(ebp)	! boot parameters offset	mov	edx, 12(ebp)	! boot parameters length	mov	eax, 16(ebp)	! address of a.out headers	mov	(_aout), eax	mov	ax, ds		! kernel data	mov	es, ax	mov	fs, ax	mov	gs, ax	mov	ss, ax	mov	esp, k_stktop	! set sp to point to the top of kernel stack! Call C startup code to set up a proper environment to run main().	push	edx	push	ebx	push	SS_SELECTOR	push	DS_SELECTOR	push	CS_SELECTOR	call	_cstart		! cstart(cs, ds, mds, parmoff, parmlen)	add	esp, 5*4! Reload gdtr, idtr and the segment registers to global descriptor table set! up by prot_init().	lgdt	(_gdt+GDT_SELECTOR)	lidt	(_gdt+IDT_SELECTOR)	jmpf	CS_SELECTOR:csinitcsinit:    o16	mov	ax, DS_SELECTOR	mov	ds, ax	mov	es, ax	mov	fs, ax	mov	gs, ax	mov	ss, ax    o16	mov	ax, TSS_SELECTOR	! no other TSS is used	ltr	ax	push	0			! set flags to known good state	popf				! esp, clear nested task and int enable	jmp	_main			! main()!*===========================================================================*!*				interrupt handlers			     *!*		interrupt handlers for 386 32-bit protected mode	     *!*===========================================================================*!*===========================================================================*!*				hwint00 - 07				     *!*===========================================================================*! Note this is a macro, it just looks like a subroutine.#define hwint_master(irq)	\	call	save			/* save interrupted process state */;\	push	(_irq_handlers+4*irq)	/* irq_handlers[irq]		  */;\	call	_intr_handle		/* intr_handle(irq_handlers[irq]) */;\	pop	ecx							    ;\	cmp	(_irq_actids+4*irq), 0	/* interrupt still active?	  */;\	jz	0f							    ;\	inb	INT_CTLMASK		/* get current mask */		    ;\	orb	al, [1<<irq]		/* mask irq */			    ;\	outb	INT_CTLMASK		/* disable the irq		  */;\0:	movb	al, END_OF_INT						    ;\	outb	INT_CTL			/* reenable master 8259		  */;\	ret				/* restart (another) process      */! Each of these entry points is an expansion of the hwint_master macro	.align	16_hwint00:		! Interrupt routine for irq 0 (the clock).	hwint_master(0)	.align	16_hwint01:		! Interrupt routine for irq 1 (keyboard)	hwint_master(1)	.align	16_hwint02:		! Interrupt routine for irq 2 (cascade!)	hwint_master(2)	.align	16_hwint03:		! Interrupt routine for irq 3 (second serial)	hwint_master(3)	.align	16_hwint04:		! Interrupt routine for irq 4 (first serial)	hwint_master(4)	.align	16_hwint05:		! Interrupt routine for irq 5 (XT winchester)	hwint_master(5)	.align	16_hwint06:		! Interrupt routine for irq 6 (floppy)	hwint_master(6)	.align	16_hwint07:		! Interrupt routine for irq 7 (printer)	hwint_master(7)!*===========================================================================*!*				hwint08 - 15				     *!*===========================================================================*! Note this is a macro, it just looks like a subroutine.#define hwint_slave(irq)	\	call	save			/* save interrupted process state */;\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -