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

📄 c_kernel.c

📁 The kernel compiled with C
💻 C
📖 第 1 页 / 共 2 页
字号:
assembly code material of Dennis Marer- many thanks to him!

  
  "The product" is intended only for teaching and demonstration purposes
  and has no warranty.

*/

#define DPL_SYS 0       /* System privilege level */
#define DPL_USER        3       /* User privilege level */
#define PRESENT 1       /* Segment is present in memory */
#define SEG_SYS 0       /* Segment is system*/
#define SEG_DC  1       /* Segment is data or code */
#define TYPE_DATA       3       /* Descriptor type fields */
#define TYPE_CODE       0x0f    /* b?*/
#define TYPE_TSS        0x09    /* b!!*/
#define TYPE_LDT        0x02    /* a??*/
#define TYPE_INT        0x0e    /*e  */
#define TYPE_TASK_GATE  0x05
#define X_BIT_C 0       /*1   X- bit code */
#define X_BIT_D       0       /*1   X- bit data */
#define X_BIT_LDT       0
#define X_BIT_TSS       0
#define NOFINTERRUPTS     47
#define TSS_DESCR_BASE  6       /* Start of task state segment descriptors in GDT*/

#define DPL_3_STACK_OFFSET      1024
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*=============================================================================
;  The 386/486 Protected Mode structures and definitions.
;
;
; Description:
;  This file defines the structures and equates for use in setting up and
;  using the 386 Protected Mode.  This includes all types of descriptors,
;  Task State Segments (TSS).
;
; Portability:
;  Requires BORLAND C++ 3.1  or better to be compiled.
;  Dependent on a 386 or later microprocessor.
;  No other platform or hardware dependencies.
;
;=============================================================================*/

/* Segment descriptor definition - see Intel literature  for other information */
typedef struct {

        unsigned int limit_0    : 16;   /* segment limit, 15-0 */
        unsigned int base_0     : 16;   /* segment base, 15-0 */
        unsigned int base_16    :  8;   /* segment base, 23-16 */
        unsigned int type       :  4;   /* type */
        unsigned int segment    :  1;   /* segment */
        unsigned int DPL        :  2;   /* Descriptor Privilege Level */
        unsigned int present    :  1;   /* segment present bit */
        unsigned int limit_16   :  4;   /* segment limit, bits 19-16 */
        unsigned int avail      :  1;   /* available bit */
        unsigned int unused     :  1;   /* unused bit */
        unsigned int X          :  1;   /* X bit */
        unsigned int granul     :  1;   /* granularity bit */
        unsigned int base_24    :  8;   /* segment base, bits 31-24 */

} SEGMENT_DESCR;

/* Selector definition - see Intel literature  for other information */
typedef int SELECTOR;

typedef struct {

        unsigned int offset_0   : 16;   /* offset, 15-0 */
        unsigned int selector   : 16;   /* segment selector */
        unsigned int            :  5;   /* word count */
        unsigned int            :  3;   /* unused */
        unsigned int type       :  5;   /* descriptor type */
        unsigned int DPL        :  2;   /* Descriptor Privilege Level */
        unsigned int present    :  1;   /* segment present bit */
        unsigned int offset_16  : 16;   /* segment limit, bits 19-16 */

} GATE_DESCR;

/*-----------------------------------------------------------------------------
;  tss386 - A 386 Protected Mode Task State Segment.  Any amount of data may
;  exist between the I/O bitmap offset value and the I/O bitmap, definable
;  by the operating system.  Here, no extra memory is assumed, and the
;  I/O bitmap is fully defined (8192 bytes) for full access.
;-----------------------------------------------------------------------------*/
/*Task State Segment  definition - see Intel literature  for other information */
typedef struct {
        unsigned int    t3BackLink      : 16;   //** TSS backlink
        unsigned int    d1              : 16;   //** Reserved
        unsigned long   t3ESP0;                         //** Stack 0 pointer (CPL=0)
        unsigned int    t3SS0           : 16;   //** Stack 0 segment
        unsigned int    d2              : 16;   //** Reserved
        unsigned long   t3ESP1;                         //** Stack 1 pointer (CPL=1)
        unsigned int    t3SS1           : 16;   //** Stack 1 segment
        unsigned int    d3              : 16;   //** Reserved
        unsigned long   t3ESP2;                         //** Stack 2 pointer (CPL=2)
        unsigned int    t3SS2           : 16;   //** Stack 2 segment
        unsigned int    d4              : 16;   //** Reserved
        unsigned long   t3CR3;                          //** CR3
        unsigned long   t3EIP;                 //** Instruction pointer
        unsigned long   t3EFlags;               //** Extended flags
        unsigned long   t3EAX;                          //** Task general registers
        unsigned long   t3ECX;
        unsigned long   t3EDX;
        unsigned long   t3EBX;
        unsigned long   t3ESP;
        unsigned long   t3EBP;
        unsigned long   t3ESI;
        unsigned long   t3EDI;
        unsigned int    t3ES            : 16;   //** Task segment registers
        unsigned int    d5              : 16;   //** Reserved
        unsigned int    t3CS            : 16;
        unsigned int    d6              : 16;   //** Reserved
        unsigned int    t3SS            : 16;
        unsigned int    d7              : 16;   //** Reserved
        unsigned int    t3DS            : 16;
        unsigned int    d8              : 16;   //** Reserved
        unsigned int    t3FS            : 16;
        unsigned int    d9              : 16;   //** Reserved
        unsigned int    t3GS            : 16;
        unsigned int    d10             : 16;   //** Reserved
        unsigned int    t3LDT           : 16;   //** Task local descriptor table
        unsigned int    d11             : 16;   //** Reserved
        unsigned int    t3Trap          :  1;   //** Holds debug trap bit (T)
        unsigned int    d12             : 15;   //** Reserved
        unsigned int    t3IOOfs         : 16;   //** I/O map address offset
        unsigned int    t3IOMap[256];   //** Give full I/O access
        unsigned int    terminator      :  8;   //** Terminator 0FFh

} TSS_SEGMENT;
/* Not used */
typedef struct
 { int limit;
   long base;
 } INFO;     /* To be loaded to GDTR and IDTR */


/********************************************************************/
/*                                                                                                                                      */
/* FUNCTION PROTOTYPES                                                                                          */
/*                                                                                                                                      */
/********************************************************************/


#define  SelKernel             0x08     /* Kernel task state segment selector */
#define  SelDebug              0x0b0
#define  SelKCS        0x010    /* Kernel code segment selector */
#define  SelKDS        0x018    /* Kernel data and stack segment selector */
#define  SelScreen        0x020    /* Display memory segment selector */
#define  SelShm        0x028    /* Shared memory segment selector */
/*
  A simple protected mode priority based multitasking kernel for
  Intel 386/486/Pentium processors

  Written by Tuomo Kortesmaa 1995
  Copyright (c) 1995 Tuomo Kortesmaa (Email: tk@evitech.fi)
  Some constants (and also some ideas) to set up devices are found
  from an assembly code material of Dennis Marer- many thanks to him!

  Any license is not needed: If You find this material useful in any purpose,
  please send a short email notice to the author.
  All comments and corrections are appreciated.
  "The product" is intended only for teaching and demonstration purposes
  and has no warranty.


*/
#include "kernel.h"
/**************************************************************************/

void main ( )
{
        KERNELBASE   = (long)(16)*(long)(_CS);
        disable();     /* Interrupts are not allowed */
        asm pushfd;    /* Push 32- bit flag register */
        asm pop         eax;
        asm and         eax,0x0fff;
        asm push        eax;
        asm popfd;     /* Flags back */
        Setup_GDT();   /* Set up Global Descriptor Table */

        Setup_IDT();   /* Set up Interrupt Descriptor Table */
        Setup_SP ();   /* Set up Slave Processor 8042 */
        Setup_PIC();   /* Set up programmable interrupt controller */
        Setup_PIT();   /* Set up programmable interrupt timer */
        init_serial(); /* Set initialisation of the serial line */
        asm push SelKCS;      /* Set protected mode start point into stack*/
        _AX=(int)MainKernel;  /* Selector and offset*/
        asm push ax;
        DispInit();

        asm     {
                cli;
                lgdt    fword ptr GDTInfo;   /* Load GDT linear address into lgdt */
                lidt    fword ptr IDTInfo;   /* Load IDT linear address into lidt */
                mov     eax,cr0;
                or      al,0x01;             /* Protected mode bit into c0- register */
                mov     cr0,eax;             /* We are in protected mode */
                retf;                        /* Jump to the protected mode start address set earlier */
        }
}

//********************************************************//
//** Setup_GDT              1993                        **//
//**                                                    **//
//********************************************************//
//**                                                    **//
//** Luodaan Global Descriptors Table                   **//
//**                                                    **//
//********************************************************//
void Setup_GDT(void)
{
int                     loop;//,seg;
long int                diff;
SEGMENT_DESCR           *p_gdt = GDT;
SELECTOR                nullSel,SEL;
        _ES= 0x0b800;
        GDTInfo.limit= sizeof(GDT);                     /* Set linear addresses*/
        GDTInfo.base = (long)16*(long)_DS + (int)GDT;
        IDTInfo.limit= sizeof(IDT);
        IDTInfo.base = (long)16*(long)_DS + (int)IDT;
        nullSel      =  0;
        set_descriptor(p_gdt++,0L,0L,0,0,0,0,0);        /* First entry is null descriptor */
        Kernel_descr =p_gdt;
                                                         /* Second entry is kernel TSS descriptor*/
        set_tss_descriptor(p_gdt++,sizeof(TSS_SEGMENT)-1,
                    ( long)16*(long)_DS+(int)&TSS_Kernel,DPL_SYS);
        KCS_descr    = p_gdt;                            /* Kernel Code segment descriptor*/
        set_code_descriptor(p_gdt++,(long)SEGSIZE-1,KERNELBASE,DPL_SYS);
                                                        //** Kernel code & data descriptor
        KDS_descr = p_gdt;
        diff      = KERNELBASE - (long)(16)*(long)(_DS);
        set_data_descriptor(p_gdt++,(long)(SEGSIZE-1)-diff,(long)(16)*(long)(_DS),DPL_SYS);
                                                        /* Set kernel TSS */
        set_tss(&TSS_Kernel,SelKCS,SelKDS,
                           (long)(SEGSIZE-1)/*ERROR*/, nullSel);
        TSS_Kernel.t3EFlags     =       0x002;          /* Set tss is tailored for user we must correct */
        TSS_Kernel.t3ESP        =       0L;
        Screen_descr            =       p_gdt;
        set_data_descriptor(p_gdt++,0xffff,0x0B8000L,DPL_USER);
        Shm_descr = p_gdt;
        set_data_descriptor(p_gdt++,0xffff,0x0B8000L,DPL_USER);

        for (loop=0;loop < _MAXPROCESS;loop++)
        {
         TSS_descr[loop]=p_gdt;
         set_tss_descriptor(p_gdt++,sizeof(TSS_SEGMENT)-1,
                      (long)(16)*(long)_DS+(int)&TSS[loop], DPL_SYS);
         SEL          =  (SELBASE +0x20 *loop);  /* Selectors and descriptors for user processes */
         Sel_TSS[loop]=  (SEL-0x8);
         CODESEL      =  (SEL) | DPL_USER;
         DATASEL      =  (SEL +0x08) | DPL_USER;
         SelData[loop+1]=  DATASEL;
         set_tss(&TSS[loop],CODESEL, DATASEL,(long)(SEGSIZE-1)-OFF[loop],0);
         TSS[loop].t3GS  =  DATASEL+0x08;
         set_code_descriptor(p_gdt++,SEGSIZE-1,
                              KERNELBASE+(loop+1)*SEGSIZE,DPL_USER);

         set_data_descriptor(p_gdt++,SEGSIZE-1-OFF[loop],
                             KERNELBASE+(loop+1)*SEGSIZE+OFF[loop],DPL_USER);
         set_data_descriptor(p_gdt++,15,
                                  (long)(16)*(long)_DS+(int)&PCB[loop].CommData,DPL_USER);

⌨️ 快捷键说明

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