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

📄 mpx386.s.cpp

📁 一个简单的操作系统minix的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				src/kernel/mpx386.s	 	 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

05900	#
05901	! This file contains the assembler startup code for Minix and the 32-bit
05902	! interrupt handlers.  It cooperates with start.c to set up a good
05903	! environment for main().
05904	
05905	! This file is part of the lowest layer of the MINIX kernel.  The other part
05906	! is "proc.c".  The lowest layer does process switching and message handling.
05907	
05908	! Every transition to the kernel goes through this file.  Transitions are
05909	! caused by sending/receiving messages and by most interrupts.  (RS232
05910	! interrupts may be handled in the file "rs2.s" and then they rarely enter
05911	! the kernel.)
05912	
05913	! Transitions to the kernel may be nested.  The initial entry may be with a
05914	! system call, exception or hardware interrupt; reentries may only be made
05915	! by hardware interrupts.  The count of reentries is kept in "k_reenter".
05916	! It is important for deciding whether to switch to the kernel stack and
05917	! for protecting the message passing code in "proc.c".
05918	
05919	! For the message passing trap, most of the machine state is saved in the
05920	! proc table.  (Some of the registers need not be saved.)  Then the stack is
05921	! switched to "k_stack", and interrupts are reenabled.  Finally, the system
05922	! call handler (in C) is called.  When it returns, interrupts are disabled
05923	! again and the code falls into the restart routine, to finish off held-up
05924	! interrupts and run the process or task whose pointer is in "proc_ptr".
05925	
05926	! Hardware interrupt handlers do the same, except  (1) The entire state must
05927	! be saved.  (2) There are too many handlers to do this inline, so the save
05928	! routine is called.  A few cycles are saved by pushing the address of the
05929	! appropiate restart routine for a return later.  (3) A stack switch is
05930	! avoided when the stack is already switched.  (4) The (master) 8259 interrupt
05931	! controller is reenabled centrally in save().  (5) Each interrupt handler
05932	! masks its interrupt line using the 8259 before enabling (other unmasked)
05933	! interrupts, and unmasks it after servicing the interrupt.  This limits the
05934	! nest level to the number of lines and protects the handler from itself.
05935	
05936	! For communication with the boot monitor at startup time some constant
05937	! data are compiled into the beginning of the text segment. This facilitates 
05938	! reading the data at the start of the boot process, since only the first
05939	! sector of the file needs to be read.
05940	
05941	! Some data storage is also allocated at the end of this file. This data 
05942	! will be at the start of the data segment of the kernel and will be read
05943	! and modified by the boot monitor before the kernel starts.
05944	
05945	! sections
05946	
05947	.sect .text
05948	begtext:
05949	.sect .rom
05950	begrom:
05951	.sect .data
05952	begdata:
05953	.sect .bss
05954	begbss:
05955	
05956	#include <minix/config.h>
05957	#include <minix/const.h>
05958	#include <minix/com.h>
05959	#include "const.h"
05960	#include "protect.h"
05961	#include "sconst.h"
05962	
05963	/* Selected 386 tss offsets. */
05964	#define TSS3_S_SP0      4
05965	
05966	! Exported functions
05967	! Note: in assembly language the .define statement applied to a function name 
05968	! is loosely equivalent to a prototype in C code -- it makes it possible to
05969	! link to an entity declared in the assembly code but does not create
05970	! the entity.
05971	
05972	.define _idle_task
05973	.define _restart
05974	.define save
05975	
05976	.define _divide_error
05977	.define _single_step_exception
05978	.define _nmi
05979	.define _breakpoint_exception
05980	.define _overflow
05981	.define _bounds_check
05982	.define _inval_opcode
05983	.define _copr_not_available
05984	.define _double_fault
05985	.define _copr_seg_overrun
05986	.define _inval_tss
05987	.define _segment_not_present
05988	.define _stack_exception
05989	.define _general_protection
05990	.define _page_fault
05991	.define _copr_error
05992	
05993	.define _hwint00        ! handlers for hardware interrupts
05994	.define _hwint01
05995	.define _hwint02
05996	.define _hwint03
05997	.define _hwint04
05998	.define _hwint05
05999	.define _hwint06
06000	.define _hwint07
06001	.define _hwint08
06002	.define _hwint09
06003	.define _hwint10
06004	.define _hwint11
06005	.define _hwint12
06006	.define _hwint13
06007	.define _hwint14
06008	.define _hwint15
06009	
06010	.define _s_call
06011	.define _p_s_call
06012	.define _level0_call
06013	
06014	! Imported functions.
06015	
06016	.extern _cstart
06017	.extern _main
06018	.extern _exception
06019	.extern _interrupt
06020	.extern _sys_call
06021	.extern _unhold
06022	
06023	! Exported variables.
06024	! Note: when used with a variable the .define does not reserve storage,
06025	! it makes the name externally visible so it may be linked to. 
06026	
06027	.define begbss
06028	.define begdata
06029	.define _sizes
06030	
06031	! Imported variables.
06032	
06033	.extern _gdt
06034	.extern _code_base
06035	.extern _data_base
06036	.extern _held_head
06037	.extern _k_reenter
06038	.extern _pc_at
06039	.extern _proc_ptr
06040	.extern _ps_mca
06041	.extern _tss
06042	.extern _level0_func
06043	.extern _mon_sp
06044	.extern _mon_return
06045	.extern _reboot_code
06046	
06047	.sect .text
06048	!*===========================================================================*
06049	!*                              MINIX                                        *
06050	!*===========================================================================*
06051	MINIX:                          ! this is the entry point for the MINIX kernel
06052	        jmp     over_flags      ! skip over the next few bytes
06053	        .data2  CLICK_SHIFT     ! for the monitor: memory granularity
06054	flags:
06055	        .data2  0x002D          ! boot monitor flags:
06056	                                !       call in 386 mode, make stack,
06057	                                !       load high, will return
06058	        nop                     ! extra byte to sync up disassembler
06059	over_flags:
06060	
06061	! Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds
06062	! right.  The ss descriptor still references the monitor data segment.)
06063	        movzx   esp, sp         ! monitor stack is a 16 bit stack
06064	        push    ebp
06065	        mov     ebp, esp
06066	        push    esi
06067	        push    edi
06068	        cmp     4(ebp), 0       ! nonzero if return possible
06069	        jz      noret
06070	        inc     (_mon_return)
06071	noret:  mov     (_mon_sp), esp  ! save stack pointer for later return
06072	
06073	! Copy the monitor global descriptor table to the address space of kernel and
06074	! switch over to it.  Prot_init() can then update it with immediate effect.
06075	
06076	        sgdt    (_gdt+GDT_SELECTOR)             ! get the monitor gdtr
06077	        mov     esi, (_gdt+GDT_SELECTOR+2)      ! absolute address of GDT
06078	        mov     ebx, _gdt                       ! address of kernel GDT
06079	        mov     ecx, 8*8                        ! copying eight descriptors
06080	copygdt:
06081	 eseg   movb    al, (esi)
06082	        movb    (ebx), al
06083	        inc     esi
06084	        inc     ebx
06085	        loop    copygdt
06086	        mov     eax, (_gdt+DS_SELECTOR+2)       ! base of kernel data
06087	        and     eax, 0x00FFFFFF                 ! only 24 bits
06088	        add     eax, _gdt                       ! eax = vir2phys(gdt)
06089	        mov     (_gdt+GDT_SELECTOR+2), eax      ! set base of GDT
06090	        lgdt    (_gdt+GDT_SELECTOR)             ! switch over to kernel GDT
06091	
06092	! Locate boot parameters, set up kernel segment registers and stack.
06093	        mov     ebx, 8(ebp)     ! boot parameters offset
06094	        mov     edx, 12(ebp)    ! boot parameters length
06095	        mov     ax, ds          ! kernel data
06096	        mov     es, ax
06097	        mov     fs, ax
06098	        mov     gs, ax
06099	        mov     ss, ax
06100	        mov     esp, k_stktop   ! set sp to point to the top of kernel stack
06101	
06102	! Call C startup code to set up a proper environment to run main().
06103	        push    edx
06104	        push    ebx
06105	        push    SS_SELECTOR
06106	        push    MON_CS_SELECTOR
06107	        push    DS_SELECTOR
06108	        push    CS_SELECTOR
06109	        call    _cstart         ! cstart(cs, ds, mcs, mds, parmoff, parmlen)
06110	        add     esp, 6*4
06111	
06112	! Reload gdtr, idtr and the segment registers to global descriptor table set
06113	! up by prot_init().
06114	
06115	        lgdt    (_gdt+GDT_SELECTOR)
06116	        lidt    (_gdt+IDT_SELECTOR)
06117	
06118	        jmpf    CS_SELECTOR:csinit
06119	csinit:
06120	    o16 mov     ax, DS_SELECTOR
06121	        mov     ds, ax
06122	        mov     es, ax
06123	        mov     fs, ax
06124	        mov     gs, ax
06125	        mov     ss, ax
06126	    o16 mov     ax, TSS_SELECTOR        ! no other TSS is used
06127	        ltr     ax
06128	        push    0                       ! set flags to known good state
06129	        popf                            ! esp, clear nested task and int enable
06130	
06131	        jmp     _main                   ! main()
06132	
06133	
06134	!*===========================================================================*
06135	!*                              interrupt handlers                           *
06136	!*              interrupt handlers for 386 32-bit protected mode             *
06137	!*===========================================================================*
06138	
06139	!*===========================================================================*
06140	!*                              hwint00 - 07                                 *
06141	!*===========================================================================*
06142	! Note this is a macro, it looks like a subroutine.
06143	#define hwint_master(irq)       \
06144	        call    save                    /* save interrupted process state */;\
06145	        inb     INT_CTLMASK                                                 ;\
06146	        orb     al, [1<<irq]                                                ;\
06147	        outb    INT_CTLMASK             /* disable the irq                */;\
06148	        movb    al, ENABLE                                                  ;\
06149	        outb    INT_CTL                 /* reenable master 8259           */;\
06150	        sti                             /* enable interrupts              */;\
06151	        push    irq                     /* irq                            */;\
06152	        call    (_irq_table + 4*irq)    /* eax = (*irq_table[irq])(irq)   */;\
06153	        pop     ecx                                                         ;\
06154	        cli                             /* disable interrupts             */;\
06155	        test    eax, eax                /* need to reenable irq?          */;\
06156	        jz      0f                                                          ;\
06157	        inb     INT_CTLMASK                                                 ;\
06158	        andb    al, ~[1<<irq]                                               ;\
06159	        outb    INT_CTLMASK             /* enable the irq                 */;\
06160	0:      ret                             /* restart (another) process      */
06161	
06162	! Each of these entry points is an expansion of the hwint_master macro
06163	        .align  16
06164	_hwint00:               ! Interrupt routine for irq 0 (the clock).
06165	        hwint_master(0)
06166	
06167	        .align  16
06168	_hwint01:               ! Interrupt routine for irq 1 (keyboard)
06169	        hwint_master(1)
06170	
06171	        .align  16
06172	_hwint02:               ! Interrupt routine for irq 2 (cascade!)
06173	        hwint_master(2)
06174	
06175	        .align  16
06176	_hwint03:               ! Interrupt routine for irq 3 (second serial)
06177	        hwint_master(3)
06178	
06179	        .align  16
06180	_hwint04:               ! Interrupt routine for irq 4 (first serial)
06181	        hwint_master(4)
06182	
06183	        .align  16
06184	_hwint05:               ! Interrupt routine for irq 5 (XT winchester)
06185	        hwint_master(5)
06186	
06187	        .align  16
06188	_hwint06:               ! Interrupt routine for irq 6 (floppy)
06189	        hwint_master(6)
06190	
06191	        .align  16
06192	_hwint07:               ! Interrupt routine for irq 7 (printer)
06193	        hwint_master(7)
06194	
06195	!*===========================================================================*
06196	!*                              hwint08 - 15                                 *

⌨️ 快捷键说明

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