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

📄 msx686.s

📁 一个朋友写的操作系统源码
💻 S
📖 第 1 页 / 共 2 页
字号:
#! This is the subroutine called by start386, it shares the same stack with! bootmanager, it will continue init the kernel execution environment..sect .textbegtext:.sect .rombegrom:.sect .databegdata:.sect .bssbegbss:#include "include/stuix/config.h"#include "include/stuix/const.h"#include "include/stuix/boot.h"#include "const.h"#include "protect.h"! 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 _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.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 _savu.define _retu.define _aretu.define _idle.define _gohome! Imported functions.extern _cstart.extern _swtch.extern _clock_handler.extern _kbd_hw_int.extern _trap.extern _nohandler! Exported variables.! Note: when used with a variable the .define does not reserve storage,! it makes the name externally visible so it may be linked to..define begbss.define begdata! Imported variables..extern _runrun             ! schedualing flag.extern _gdt                ! GDT table.extern _bm_sp.extern _usr_ppda_base      ! Page directory physical address.extern _usr_pagetab_ptr    ! kernel stack pointer at this position.sect .text!*===========================================================================*!*                            Stuix                                          *!*===========================================================================*STUIX:! Set up a C stack frame on the bootmanager stack, it shares the same stack with! boot manager. The stack won't switch until page is enabled.      push ebp      mov ebp, esp      push esi      push edi      mov (_bm_sp), esp   ! save return address                          ! to start386! Get the boot manager gdtr absolute address, it is used to switch back to real! address mode.       sgdt (_gdt + PNE_GDT_SELECTOR)  ! Copy the bootmanager global descriptor table to the address space of kernel! but don't switch over to it until the rest descriptors were all initialized ! by Prot_init() and the processor page unit is enabled.! FS contains the bootmanager data segment, used to copy first 8 descriptor! to the kernel address space for referencing.      mov esi, BM_GDT_OFFSET  ! 4*3 + 1024      mov ebx, _gdt           ! kernel gdt address      mov ecx, 8*8copygdt: fseg  movb al,(esi)      movb (ebx),al      inc esi      inc ebx      loop copygdt! Locate the kernel image segment information! and call C startup code to set up a proper! environment to run main()      mov esi, A_TEXT_OFFfseg  mov ebx, (esi)      mov esi, A_DATA_OFFfseg  mov edx, (esi)      mov esi, A_BSS_OFFfseg  mov eax, (esi)      push eax      push edx      push ebx      push KERNEL_DATA_SELECTOR      push KERNEL_CODE_SELECTOR      call _cstart    ! cstart(cs, ds, textsize, datasize, bssize)      add esp, 5*4! Enable processor page unit, identity pages is required by the proceesor! to guarantees the correctly address referencing during critical section.! this makes the machine dependence code extremely hard to understand. Do! not try to figure out how it works if you are novice to the architecture! of IA-32. if you insist, we recommand you to read <Intel Architecture! Software Developer's Manual> volume 3, chapter 9. Also start386.asm need! to be grasped, since it highly coorperates with msx686.s! The PDBR aways points to the physical address of current process's PPDA,  ! the first two page directory entries in PPDA point to the physical address! of two kernel tables in contingous 8k space respectly. the thired page! directory entry in PPDA point to the usr 4k page table.! As soon as the processor page unit is enabled, don't use long jump, it will! cause the processor deed lock, this characteristic was not referred by the! Intel document.      mov eax, (_usr_ppda_base)      mov cr3, eax      mov eax, cr0      or  eax, 0x80000000      mov cr0, eax      jmp csinitcsinit:! we are in identity mapped kernel code and data page now, load our new! GDT, IDT, LDT and switch to the new environment to call _main      lgdt (_gdt + GDT_SELECTOR)      lidt (_gdt + IDT_SELECTOR) o16  mov ax, LDT_SELECTOR      lldt ax             jmpf KERNEL_VCODE_SELECTOR:csvinitcsvinit: o16  mov ax, KERNEL_VDATA_SELECTOR      mov ds, ax      mov ss, ax      mov es, ax      mov fs, ax      mov gs, ax! Load our 0# process kernel stack      mov esp, (_usr_pagetab_ptr)        ! Load our first and only task as the requirement of processor o16  mov ax, KERNEL_TSS_SELECTOR       ltr ax      push 0     ! set flags to known good state      popf       ! clear nested task and disable interrupt            call _mainRING0 = 3        ! Processor code segment RPL!*===========================================================================*!*                        interrupt handlers                                 *!*===========================================================================*!*===========================================================================*!*                          hwint00 - 07                                     *!*===========================================================================*! Note this is a macro, it looks like a subroutine.#define hwint_master(irq, handler)       \        cld                     /* set direction flag to a know value     */;\        push 0                  /* padding for error code                 */;\        push irq                /* interrupt irq                          */;\        pushad                  /* save general registers                 */;\        push ds                 /* save ds                                */;\        push es                 /* save es                                */;\        push fs                 /* save fs                                */;\        push gs                 /* save gs                                */;\   o16  mov ax, KERNEL_VDATA_SELECTOR                                       ;\        mov ds, ax              /* we don't touch ss, becasue it was      */;\        mov es, ax              /* already setup by kernel TSS if the     */;\        mov fs, ax              /* previous mode is user. If the previous */;\        mov gs, ax              /* mode is kernel, reload is trivial.     */;\        mov eax,esp             /* use eax as a base pointer.             */;\        push esp                /* esp points to common stack frame       */;\        push 60(eax)            /* get cs pushed.                         */;\        inb INT_CTLMASK                                                     ;\        orb al, [1<<irq]                                                    ;\        outb INT_CTLMASK        /* disable the irq                        */;\        movb al, ENABLE                                                     ;\        outb INT_CTL            /* reenable master 8259                   */;\        sti                     /* enable interrupts                      */;\        test (esp), RING0                                                   ;\        je 1f                   /* if ring0                               */;\        call [handler]          /* call interrupt handler                 */;\        add esp, 4*2            /* pop used C arguments                   */;\     2: cli                     /* disable interrupts                     */;\        cmpb (_runrun), 0                                                   ;\        je 2f                                                               ;\        sti                     /* unlock                                 */;\        call _swtch                                                         ;\        jmp 2b                                                              ;\     2: pop gs                  /* return to user mode                    */;\        pop fs                                                              ;\        pop es                                                              ;\        pop ds                                                              ;\        popad                                                               ;\        add esp, 4*2            /* pop padding space                      */;\        inb INT_CTLMASK                                                     ;\        andb al, ~[1<<irq]                                                  ;\        outb INT_CTLMASK        /* enable irq                             */;\        iretd                                                               ;\     1: call [handler]          /* call interrupt handler                 */;\        add esp, 4*2            /* pop used C arguemts                    */;\        cli                     /* disable interrupts                     */;\        pop gs                  /* return to kernel mode                  */;\        pop fs                                                              ;\        pop es                                                              ;\        pop ds                                                              ;\        popad                                                               ;\        add esp, 4*2            /* pop padding space                      */;\        inb INT_CTLMASK                                                     ;\        andb al, ~[1<<irq]                                                  ;\        outb INT_CTLMASK        /* enable irq                             */;\        iretd                                                               ;\! Each of tese entry points is an expansion of the hwint_master macro        .align 16_hwint00:            ! Interrupt routine for clock interrupt.        hwint_master(0, _clock_handler)        .align 16_hwint01:            ! Interrupt routine for keyboard interrup.        hwint_master(1, _kbd_hw_int)                .align 16_hwint02:        hwint_master(2, _nohandler)        .align 16_hwint03:        hwint_master(3, _nohandler)        .align 16_hwint04:        hwint_master(4, _nohandler)        .align 16_hwint05:        hwint_master(5, _nohandler)        .align 16_hwint06:        hwint_master(6, _nohandler)        .align 16_hwint07:        hwint_master(7, _nohandler)!*===========================================================================*!*                          hwint08 - 15                                     *!*===========================================================================*! Note this is a macro, it looks like a subroutine.#define hwint_slave(irq, handler)        \        cld                     /* set direction flag to a know value     */;\        push 0                  /* padding for error code                 */;\        push irq                /* interrupt irq                          */;\        pushad                  /* save general registers                 */;\        push ds                 /* save ds                                */;\        push es                 /* save es                                */;\        push fs                 /* save fs                                */;\        push gs                 /* save gs                                */;\   o16  mov ax, KERNEL_VDATA_SELECTOR                                       ;\        mov ds, ax              /* we don't touch ss, becasue it was      */;\        mov es, ax              /* already setup by kernel TSS if the     */;\        mov fs, ax              /* previous mode is user. If the previous */;\        mov gs, ax              /* mode is kernel, reload is trivial.     */;\        mov eax,esp             /* use eax as a base pointer.             */;\        push esp                /* esp points to common stack frame       */;\        push 60(eax)            /* get cs pushed.                         */;\        inb INT2_CTLMASK                                                    ;\        orb al, [1<<[irq-8]]                                                ;\        outb INT2_CTLMASK       /* disable the irq                        */;\        movb al, ENABLE                                                     ;\        outb INT_CTL            /* reenable master 8259                   */;\        jmp .+2                 /* delay                                  */;\        outb INT2_CTL           /* reenable slave 8259                    */;\        sti                     /* enable interrupts                      */;\

⌨️ 快捷键说明

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