zoukankan      html  css  js  c++  java
  • 46 多进程并行执行(上)

    参考

    https://blog.51cto.com/13475106/category6.html及狄泰软件相关课程

    主要代码:

    kmain.c

    #include "kernel.h"
    #include "screen.h"
    #include "global.h"
    
    void (* const InitInterrupt)() = NULL;
    void (* const EnableTimer)() = NULL;
    void (* const SendEOI)(uint port) = NULL;
    
    volatile Task* gCTaskAddr = NULL;
    Task p = {0};
    Task t = {0};
    TSS gTSS = {0};
    
    void InitTask(Task* pt, void(*entry)())
    {
        pt->rv.cs = LDT_CODE32_SELECTOR;
        pt->rv.gs = LDT_VIDEO_SELECTOR;
        pt->rv.ds = LDT_DATA32_SELECTOR;
        pt->rv.es = LDT_DATA32_SELECTOR;
        pt->rv.fs = LDT_DATA32_SELECTOR;
        pt->rv.ss = LDT_DATA32_SELECTOR;
        
        pt->rv.esp = (uint)pt->stack + sizeof(pt->stack);
        pt->rv.eip = (uint)entry;
        pt->rv.eflags = 0x3202;
        
        gTSS.ss0 = GDT_DATA32_FLAT_SELECTOR;
        gTSS.esp0 = (uint)&pt->rv + sizeof(pt->rv);
        gTSS.iomb = sizeof(TSS);
        
        SetDescValue(pt->ldt + LDT_VIDEO_INDEX,  0xB8000, 0x07FFF, DA_DRWA + DA_32 + DA_DPL3);
        SetDescValue(pt->ldt + LDT_CODE32_INDEX, 0x00,    0xFFFFF, DA_C + DA_32 + DA_DPL3);
        SetDescValue(pt->ldt + LDT_DATA32_INDEX, 0x00,    0xFFFFF, DA_DRW + DA_32 + DA_DPL3);
        
        pt->ldtSelector = GDT_TASK_LDT_SELECTOR;
        pt->tssSelector = GDT_TASK_TSS_SELECTOR;
        
        SetDescValue(&gGdtInfo.entry[GDT_TASK_LDT_INDEX], (uint)&pt->ldt, sizeof(pt->ldt)-1, DA_LDT + DA_DPL0);
        SetDescValue(&gGdtInfo.entry[GDT_TASK_TSS_INDEX], (uint)&gTSS, sizeof(gTSS)-1, DA_386TSS + DA_DPL0);
    }
    
    void Delay(int n)
    {
        while( n > 0 )
        {
            int i = 0;
            int j = 0;
            
            for(i=0; i<1000; i++)
            {
                for(j=0; j<1000; j++)
                {
                    asm volatile ("nop
    ");
                }
            }
            
            n--;
        }
    }
    
    void TaskA()
    {
        int i = 0;
        
        SetPrintPos(0, 12);
        
        PrintString("Task A: ");
        
        while(1)
        {
            SetPrintPos(8, 12);
            PrintChar('A' + i);
            i = (i + 1) % 26;
            Delay(1);
        }
    }
    
    void TaskB()
    {
        int i = 0;
        
        SetPrintPos(0, 13);
        
        PrintString("Task B: ");
        
        while(1)
        {
            SetPrintPos(8, 13);
            PrintChar('0' + i);
            i = (i + 1) % 10;
            Delay(1);
        }
    }
    
    void ChangeTask()
    {
        gCTaskAddr = (gCTaskAddr == &p) ? &t : &p;
        
        gTSS.ss0 = GDT_DATA32_FLAT_SELECTOR;
        gTSS.esp0 = (uint)&gCTaskAddr->rv.gs + sizeof(RegValue);
        
        SetDescValue(&gGdtInfo.entry[GDT_TASK_LDT_INDEX], (uint)&gCTaskAddr->ldt, sizeof(gCTaskAddr->ldt)-1, DA_LDT + DA_DPL0);
        
        LoadTask(gCTaskAddr);
    }
    
    void TimerHandlerEntry();
    
    void TimerHandler()
    {
        static uint i = 0;
        
        i = (i + 1) % 5;
        
        if( i == 0 )
        {
            ChangeTask();
        }
        
        SendEOI(MASTER_EOI_PORT);
    }
    
    void KMain()
    {
        int n = PrintString("D.T.OS
    ");
        uint temp = 0;
        
        PrintString("GDT Entry: ");
        PrintIntHex((uint)gGdtInfo.entry);
        PrintChar('
    ');
        
        PrintString("GDT Size: ");
        PrintIntDec((uint)gGdtInfo.size);
        PrintChar('
    ');
        
        PrintString("IDT Entry: ");
        PrintIntHex((uint)gIdtInfo.entry);
        PrintChar('
    ');
        
        PrintString("IDT Size: ");
        PrintIntDec((uint)gIdtInfo.size);
        PrintChar('
    ');
        
        InitTask(&t, TaskB);
        InitTask(&p, TaskA);
        
        
        SetIntHandler(gIdtInfo.entry + 0x20, (uint)TimerHandlerEntry);
        
        InitInterrupt();
        
        EnableTimer();
        
        gCTaskAddr = &p;
        
        RunTask(gCTaskAddr);
    }
    

    loader.asm

    %include "blfunc.asm"
    %include "common.asm"
    
    org BaseOfLoader
    
    interface:
        BaseOfStack    equ    BaseOfLoader
        BaseOfTarget   equ    BaseOfKernel
        Target db  "KERNEL     "
        TarLen equ ($-Target)
    
    [section .gdt]
    ; GDT definition
    ;                                       Base,         Limit,                Attribute
    GDT_ENTRY            :     Descriptor    0,            0,                   0
    CODE32_DESC          :     Descriptor    0,            Code32SegLen - 1,    DA_C + DA_32 + DA_DPL0
    VIDEO_DESC           :     Descriptor    0xB8000,      0x07FFF,             DA_DRWA + DA_32 + DA_DPL0
    CODE32_FLAT_DESC     :     Descriptor    0,            0xFFFFF,             DA_C + DA_32 + DA_DPL0
    DATA32_FLAT_DESC     :     Descriptor    0,            0xFFFFF,             DA_DRW + DA_32 + DA_DPL0
    TASK_LDT_DESC        :     Descriptor    0,            0,                   0
    TASK_TSS_DESC        :     Descriptor    0,            0,                   0
    ; GDT end
    
    GdtLen    equ   $ - GDT_ENTRY
    
    GdtPtr:
              dw   GdtLen - 1
              dd   0
              
              
    ; GDT Selector
    Code32Selector        equ (0x0001 << 3) + SA_TIG + SA_RPL0
    VideoSelector         equ (0x0002 << 3) + SA_TIG + SA_RPL0
    Code32FlatSelector    equ (0x0003 << 3) + SA_TIG + SA_RPL0
    Data32FlatSelector    equ (0x0004 << 3) + SA_TIG + SA_RPL0
    
    
    ; end of [section .gdt]
    
    [section .idt]
    align 32
    [bits 32]
    IDT_ENTRY:
    ; IDT definition
    ;                        Selector,             Offset,       DCount,    Attribute
    %rep 256
                  Gate      Code32Selector,    DefaultHandler,   0,         DA_386IGate + DA_DPL0
    %endrep
    
    IdtLen    equ    $ - IDT_ENTRY
    
    IdtPtr:
              dw    IdtLen - 1
              dd    0
    
    ; end of [section .idt]
    
    [section .s16]
    [bits 16]
    BLMain:
        mov ax, cs
        mov ds, ax
        mov es, ax
        mov ss, ax
        mov sp, SPInitValue
        
        ; initialize GDT for 32 bits code segment
        mov esi, CODE32_SEGMENT
        mov edi, CODE32_DESC
        
        call InitDescItem
        
        ; initialize GDT pointer struct
        mov eax, 0
        mov ax, ds
        shl eax, 4
        add eax, GDT_ENTRY
        mov dword [GdtPtr + 2], eax
        
        ; initialize IDT pointer struct
        mov eax, 0
        mov ax, ds
        shl eax, 4
        add eax, IDT_ENTRY
        mov dword [IdtPtr + 2], eax
        
        call LoadTarget
    	
    	cmp dx, 0
    	jz output
    	
    	call StoreGlobal
    
        ; 1. load GDT
        lgdt [GdtPtr]
        
        ; 2. close interrupt
        ;    load IDT
        ;    set IOPL to 3
        cli 
        
        lidt [IdtPtr]
        
        pushf
        pop eax
        
        or eax, 0x3000
        
        push eax
        popf
        
        ; 3. open A20
        in al, 0x92
        or al, 00000010b
        out 0x92, al
        
        ; 4. enter protect mode
        mov eax, cr0
        or eax, 0x01
        mov cr0, eax
        
        ; 5. jump to 32 bits code
        jmp dword Code32Selector : 0
    
    output:	
        mov bp, ErrStr
        mov cx, ErrLen
    	call Print
    	
    	jmp $
    
    ; esi    --> code segment label
    ; edi    --> descriptor label
    InitDescItem:
        push eax
    
        mov eax, 0
        mov ax, cs
        shl eax, 4
        add eax, esi
        mov word [edi + 2], ax
        shr eax, 16
        mov byte [edi + 4], al
        mov byte [edi + 7], ah
        
        pop eax
        
        ret
    
    ;
    ;
    StoreGlobal:
        mov dword [RunTaskEntry], RunTask
        mov dword [LoadTaskEntry], LoadTask
        mov dword [InitInterruptEntry], InitInterrupt
        mov dword [EnableTimerEntry], EnableTimer
        mov dword [SendEOIEntry], SendEOI
        
        mov eax, dword [GdtPtr + 2]
        mov dword [GdtEntry], eax
        
        mov dword [GdtSize], GdtLen / 8
        
        mov eax, dword [IdtPtr + 2]
        mov dword [IdtEntry], eax
        
        mov dword [IdtSize], IdtLen / 8
        
        ret
    
    [section .sfunc]
    [bits 32]
    ;
    ;
    Delay:
        %rep 5
        nop
        %endrep
        ret
        
    ;
    ;
    Init8259A:
        push ax
        
        ; master
        ; ICW1
        mov al, 00010001B
        out MASTER_ICW1_PORT, al
        
        call Delay
        
        ; ICW2
        mov al, 0x20
        out MASTER_ICW2_PORT, al
        
        call Delay
        
        ; ICW3
        mov al, 00000100B
        out MASTER_ICW3_PORT, al
        
        call Delay
        
        ; ICW4
        mov al, 00010001B
        out MASTER_ICW4_PORT, al
        
        call Delay
        
        ; slave
        ; ICW1
        mov al, 00010001B
        out SLAVE_ICW1_PORT, al
        
        call Delay
        
        ; ICW2
        mov al, 0x28
        out SLAVE_ICW2_PORT, al
        
        call Delay
        
        ; ICW3
        mov al, 00000010B
        out SLAVE_ICW3_PORT, al
        
        call Delay
        
        ; ICW4
        mov al, 00000001B
        out SLAVE_ICW4_PORT, al
        
        call Delay
        
        pop ax
        
        ret
        
    ; al --> IMR register value
    ; dx --> 8259A port
    WriteIMR:
        out dx, al
        call Delay
        ret
        
    ; dx --> 8259A
    ; return:
    ;     ax --> IMR register value
    ReadIMR:
        in ax, dx
        call Delay
        ret
    
    ;
    ; dx --> 8259A port
    WriteEOI:
        push ax
        
        mov al, 0x20
        out dx, al
        
        call Delay
        
        pop ax
        
        ret
    
    [section .gfunc]
    [bits 32]
    ;
    ;  parameter  ===> Task* pt
    RunTask:
        push ebp
        mov ebp, esp
        
        mov esp, [ebp + 8]
        
        lldt word [esp + 200]
        ltr word [esp + 202]
        
        pop gs
        pop fs
        pop es
        pop ds
        
        popad
        
        add esp, 4
        
        iret
        
    ; void LoadTask(Task* pt);
    ;
    LoadTask:
        push ebp
        mov ebp, esp
        
        mov eax, [ebp + 8]
        
        lldt word [eax + 200]
        
        leave
        
        ret
           
    ;
    ;
    InitInterrupt:
        push ebp
        mov ebp, esp
        
        push ax
        push dx
        
        call Init8259A
        
        sti
        
        mov ax, 0xFF
        mov dx, MASTER_IMR_PORT
        
        call WriteIMR
        
        mov ax, 0xFF
        mov dx, SLAVE_IMR_PORT
        
        call WriteIMR
        
        pop dx
        pop ax
        
        leave 
        ret
    
    ;
    ;
    EnableTimer:
        push ebp
        mov ebp, esp
        
        push ax
        push dx
        
        mov dx, MASTER_IMR_PORT
        
        call ReadIMR
        
        and ax, 0xFE
        
        call WriteIMR
        
        pop dx
        pop ax
        
        leave
        ret  
        
    ; void SendEOI(uint port);
    ;    port ==> 8259A port
    SendEOI:
        push ebp
        mov ebp, esp
        
        mov edx, [ebp + 8]
        
        mov al, 0x20
        out dx, al
        
        call Delay
        
        leave
        ret 
        
    [section .s32]
    [bits 32]
    CODE32_SEGMENT:
        mov ax, VideoSelector
        mov gs, ax
        
        mov ax, Data32FlatSelector
        mov ds, ax
        mov es, ax
        mov fs, ax
        
        mov ax, Data32FlatSelector
        mov ss, ax
        mov esp, BaseOfLoader
        
        jmp dword Code32FlatSelector : BaseOfKernel
        
    ;
    ;
    DefaultHandlerFunc:
        iret
        
    DefaultHandler    equ    DefaultHandlerFunc - $$
    
    Code32SegLen    equ    $ - CODE32_SEGMENT
    
    ErrStr db  "No KERNEL"	
    ErrLen equ ($-ErrStr)
    
    Buffer db  0
    

     

    更多代码见相关课程 

  • 相关阅读:
    科学开源项目 : 建立一个 新的 光衍射 模型
    光不是电磁波 摩擦力不是电磁力
    收录一篇 贝尔不等式 的 文章
    数学家 程序员 哲学家 艺术家
    论 数学 的 工具性
    数学 怎么用?
    随便说说 广义相对论 的 时间膨胀
    逻辑物理学 : 光子 有 质量 吗 ?
    我对 “光子有质量 , 引力对光子有作用” 存疑
    收录一些 高等数学 的 文章
  • 原文地址:https://www.cnblogs.com/lh03061238/p/14750113.html
Copyright © 2011-2022 走看看