?? c_kernel.c
字號:
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 + -