昨天,光标能够跟随了,不过系统调用不能正常工作,还没找到原因,暂时也搞不懂,就这样吧

/************************************************************************/
/*                          Macros Declaration                          */
/************************************************************************/
#define	KB_IN_BYTES	32	/* size of keyboard input buffer */
#define MAP_COLS	3	/* Number of columns in keymap */
#define NR_SCAN_CODES	0x80	/* Number of scan codes (rows in keymap) */

#define FLAG_BREAK	0x0080		/* Break Code			*/
#define FLAG_EXT	0x0100		/* Normal function keys		*/
#define FLAG_SHIFT_L	0x0200		/* Shift key			*/
#define FLAG_SHIFT_R	0x0400		/* Shift key			*/
#define FLAG_CTRL_L	0x0800		/* Control key			*/
#define FLAG_CTRL_R	0x1000		/* Control key			*/
#define FLAG_ALT_L	0x2000		/* Alternate key		*/
#define FLAG_ALT_R	0x4000		/* Alternate key		*/
#define FLAG_PAD	0x8000		/* keys in num pad		*/

#define MASK_RAW	0x01FF		/* raw key value = code passed to tty & MASK_RAW
					   the value can be found either in the keymap column 0
					   or in the list below */

/* Special keys */
#define ESC		(0x01 + FLAG_EXT)	/* Esc		*/
#define TAB		(0x02 + FLAG_EXT)	/* Tab		*/
#define ENTER		(0x03 + FLAG_EXT)	/* Enter	*/
#define BACKSPACE	(0x04 + FLAG_EXT)	/* BackSpace	*/

#define GUI_L		(0x05 + FLAG_EXT)	/* L GUI	*/
#define GUI_R		(0x06 + FLAG_EXT)	/* R GUI	*/
#define APPS		(0x07 + FLAG_EXT)	/* APPS	*/

/* Shift, Ctrl, Alt */
#define SHIFT_L		(0x08 + FLAG_EXT)	/* L Shift	*/
#define SHIFT_R		(0x09 + FLAG_EXT)	/* R Shift	*/
#define CTRL_L		(0x0A + FLAG_EXT)	/* L Ctrl	*/
#define CTRL_R		(0x0B + FLAG_EXT)	/* R Ctrl	*/
#define ALT_L		(0x0C + FLAG_EXT)	/* L Alt	*/
#define ALT_R		(0x0D + FLAG_EXT)	/* R Alt	*/

/* Lock keys */
#define CAPS_LOCK	(0x0E + FLAG_EXT)	/* Caps Lock	*/
#define	NUM_LOCK	(0x0F + FLAG_EXT)	/* Number Lock	*/
#define SCROLL_LOCK	(0x10 + FLAG_EXT)	/* Scroll Lock	*/

/* Function keys */
#define F1		(0x11 + FLAG_EXT)	/* F1		*/
#define F2		(0x12 + FLAG_EXT)	/* F2		*/
#define F3		(0x13 + FLAG_EXT)	/* F3		*/
#define F4		(0x14 + FLAG_EXT)	/* F4		*/
#define F5		(0x15 + FLAG_EXT)	/* F5		*/
#define F6		(0x16 + FLAG_EXT)	/* F6		*/
#define F7		(0x17 + FLAG_EXT)	/* F7		*/
#define F8		(0x18 + FLAG_EXT)	/* F8		*/
#define F9		(0x19 + FLAG_EXT)	/* F9		*/
#define F10		(0x1A + FLAG_EXT)	/* F10		*/
#define F11		(0x1B + FLAG_EXT)	/* F11		*/
#define F12		(0x1C + FLAG_EXT)	/* F12		*/

/* Control Pad */
#define PRINTSCREEN	(0x1D + FLAG_EXT)	/* Print Screen	*/
#define PAUSEBREAK	(0x1E + FLAG_EXT)	/* Pause/Break	*/
#define INSERT		(0x1F + FLAG_EXT)	/* Insert	*/
#define DELETE		(0x20 + FLAG_EXT)	/* Delete	*/
#define HOME		(0x21 + FLAG_EXT)	/* Home		*/
#define END		(0x22 + FLAG_EXT)	/* End		*/
#define PAGEUP		(0x23 + FLAG_EXT)	/* Page Up	*/
#define PAGEDOWN	(0x24 + FLAG_EXT)	/* Page Down	*/
#define UP		(0x25 + FLAG_EXT)	/* Up		*/
#define DOWN		(0x26 + FLAG_EXT)	/* Down		*/
#define LEFT		(0x27 + FLAG_EXT)	/* Left		*/
#define RIGHT		(0x28 + FLAG_EXT)	/* Right	*/

/* ACPI keys */
#define POWER		(0x29 + FLAG_EXT)	/* Power	*/
#define SLEEP		(0x2A + FLAG_EXT)	/* Sleep	*/
#define WAKE		(0x2B + FLAG_EXT)	/* Wake Up	*/

/* Num Pad */
#define PAD_SLASH	(0x2C + FLAG_EXT)	/* /		*/
#define PAD_STAR	(0x2D + FLAG_EXT)	/* *		*/
#define PAD_MINUS	(0x2E + FLAG_EXT)	/* -		*/
#define PAD_PLUS	(0x2F + FLAG_EXT)	/* +		*/
#define PAD_ENTER	(0x30 + FLAG_EXT)	/* Enter	*/
#define PAD_DOT		(0x31 + FLAG_EXT)	/* .		*/
#define PAD_0		(0x32 + FLAG_EXT)	/* 0		*/
#define PAD_1		(0x33 + FLAG_EXT)	/* 1		*/
#define PAD_2		(0x34 + FLAG_EXT)	/* 2		*/
#define PAD_3		(0x35 + FLAG_EXT)	/* 3		*/
#define PAD_4		(0x36 + FLAG_EXT)	/* 4		*/
#define PAD_5		(0x37 + FLAG_EXT)	/* 5		*/
#define PAD_6		(0x38 + FLAG_EXT)	/* 6		*/
#define PAD_7		(0x39 + FLAG_EXT)	/* 7		*/
#define PAD_8		(0x3A + FLAG_EXT)	/* 8		*/
#define PAD_9		(0x3B + FLAG_EXT)	/* 9		*/
#define PAD_UP		PAD_8			/* Up		*/
#define PAD_DOWN	PAD_2			/* Down		*/
#define PAD_LEFT	PAD_4			/* Left		*/
#define PAD_RIGHT	PAD_6			/* Right	*/
#define PAD_HOME	PAD_7			/* Home		*/
#define PAD_END		PAD_1			/* End		*/
#define PAD_PAGEUP	PAD_9			/* Page Up	*/
#define PAD_PAGEDOWN	PAD_3			/* Page Down	*/
#define PAD_INS		PAD_0			/* Ins		*/
#define PAD_MID		PAD_5			/* Middle key	*/
#define PAD_DEL		PAD_DOT			/* Del		*/

/* Keymap for US MF-2 keyboard. */

int keymap[NR_SCAN_CODES * 3] = {

/* scan-code			!Shift		Shift		E0 XX	*/
/* ==================================================================== */
/* 0x00 - none		*/	0,		0,		0,
/* 0x01 - ESC		*/	ESC,		ESC,		0,
/* 0x02 - '1'		*/	'1',		'!',		0,
/* 0x03 - '2'		*/	'2',		'@',		0,
/* 0x04 - '3'		*/	'3',		'#',		0,
/* 0x05 - '4'		*/	'4',		'$',		0,
/* 0x06 - '5'		*/	'5',		'%',		0,
/* 0x07 - '6'		*/	'6',		'^',		0,
/* 0x08 - '7'		*/	'7',		'&',		0,
/* 0x09 - '8'		*/	'8',		'*',		0,
/* 0x0A - '9'		*/	'9',		'(',		0,
/* 0x0B - '0'		*/	'0',		')',		0,
/* 0x0C - '-'		*/	'-',		'_',		0,
/* 0x0D - '='		*/	'=',		'+',		0,
/* 0x0E - BS		*/	BACKSPACE,	BACKSPACE,	0,
/* 0x0F - TAB		*/	TAB,		TAB,		0,
/* 0x10 - 'q'		*/	'q',		'Q',		0,
/* 0x11 - 'w'		*/	'w',		'W',		0,
/* 0x12 - 'e'		*/	'e',		'E',		0,
/* 0x13 - 'r'		*/	'r',		'R',		0,
/* 0x14 - 't'		*/	't',		'T',		0,
/* 0x15 - 'y'		*/	'y',		'Y',		0,
/* 0x16 - 'u'		*/	'u',		'U',		0,
/* 0x17 - 'i'		*/	'i',		'I',		0,
/* 0x18 - 'o'		*/	'o',		'O',		0,
/* 0x19 - 'p'		*/	'p',		'P',		0,
/* 0x1A - '['		*/	'[',		'{',		0,
/* 0x1B - ']'		*/	']',		'}',		0,
/* 0x1C - CR/LF		*/	ENTER,		ENTER,		PAD_ENTER,
/* 0x1D - l. Ctrl	*/	CTRL_L,		CTRL_L,		CTRL_R,
/* 0x1E - 'a'		*/	'a',		'A',		0,
/* 0x1F - 's'		*/	's',		'S',		0,
/* 0x20 - 'd'		*/	'd',		'D',		0,
/* 0x21 - 'f'		*/	'f',		'F',		0,
/* 0x22 - 'g'		*/	'g',		'G',		0,
/* 0x23 - 'h'		*/	'h',		'H',		0,
/* 0x24 - 'j'		*/	'j',		'J',		0,
/* 0x25 - 'k'		*/	'k',		'K',		0,
/* 0x26 - 'l'		*/	'l',		'L',		0,
/* 0x27 - ';'		*/	';',		':',		0,
/* 0x28 - '\''		*/	'\'',		'"',		0,
/* 0x29 - '`'		*/	'`',		'~',		0,
/* 0x2A - l. SHIFT	*/	SHIFT_L,	SHIFT_L,	0,
/* 0x2B - '\'		*/	'\\',		'|',		0,
/* 0x2C - 'z'		*/	'z',		'Z',		0,
/* 0x2D - 'x'		*/	'x',		'X',		0,
/* 0x2E - 'c'		*/	'c',		'C',		0,
/* 0x2F - 'v'		*/	'v',		'V',		0,
/* 0x30 - 'b'		*/	'b',		'B',		0,
/* 0x31 - 'n'		*/	'n',		'N',		0,
/* 0x32 - 'm'		*/	'm',		'M',		0,
/* 0x33 - ','		*/	',',		'<',		0,
/* 0x34 - '.'		*/	'.',		'>',		0,
/* 0x35 - '/'		*/	'/',		'?',		PAD_SLASH,
/* 0x36 - r. SHIFT	*/	SHIFT_R,	SHIFT_R,	0,
/* 0x37 - '*'		*/	'*',		'*',    	0,
/* 0x38 - ALT		*/	ALT_L,		ALT_L,  	ALT_R,
/* 0x39 - ' '		*/	' ',		' ',		0,
/* 0x3A - CapsLock	*/	CAPS_LOCK,	CAPS_LOCK,	0,
/* 0x3B - F1		*/	F1,		F1,		0,
/* 0x3C - F2		*/	F2,		F2,		0,
/* 0x3D - F3		*/	F3,		F3,		0,
/* 0x3E - F4		*/	F4,		F4,		0,
/* 0x3F - F5		*/	F5,		F5,		0,
/* 0x40 - F6		*/	F6,		F6,		0,
/* 0x41 - F7		*/	F7,		F7,		0,
/* 0x42 - F8		*/	F8,		F8,		0,
/* 0x43 - F9		*/	F9,		F9,		0,
/* 0x44 - F10		*/	F10,		F10,		0,
/* 0x45 - NumLock	*/	NUM_LOCK,	NUM_LOCK,	0,
/* 0x46 - ScrLock	*/	SCROLL_LOCK,	SCROLL_LOCK,	0,
/* 0x47 - Home		*/	PAD_HOME,	'7',		HOME,
/* 0x48 - CurUp		*/	PAD_UP,		'8',		UP,
/* 0x49 - PgUp		*/	PAD_PAGEUP,	'9',		PAGEUP,
/* 0x4A - '-'		*/	PAD_MINUS,	'-',		0,
/* 0x4B - Left		*/	PAD_LEFT,	'4',		LEFT,
/* 0x4C - MID		*/	PAD_MID,	'5',		0,
/* 0x4D - Right		*/	PAD_RIGHT,	'6',		RIGHT,
/* 0x4E - '+'		*/	PAD_PLUS,	'+',		0,
/* 0x4F - End		*/	PAD_END,	'1',		END,
/* 0x50 - Down		*/	PAD_DOWN,	'2',		DOWN,
/* 0x51 - PgDown	*/	PAD_PAGEDOWN,	'3',		PAGEDOWN,
/* 0x52 - Insert	*/	PAD_INS,	'0',		INSERT,
/* 0x53 - Delete	*/	PAD_DOT,	'.',		DELETE,
/* 0x54 - Enter		*/	0,		0,		0,
/* 0x55 - ???		*/	0,		0,		0,
/* 0x56 - ???		*/	0,		0,		0,
/* 0x57 - F11		*/	F11,		F11,		0,	
/* 0x58 - F12		*/	F12,		F12,		0,	
/* 0x59 - ???		*/	0,		0,		0,	
/* 0x5A - ???		*/	0,		0,		0,	
/* 0x5B - ???		*/	0,		0,		GUI_L,	
/* 0x5C - ???		*/	0,		0,		GUI_R,	
/* 0x5D - ???		*/	0,		0,		APPS,	
/* 0x5E - ???		*/	0,		0,		0,	
/* 0x5F - ???		*/	0,		0,		0,
/* 0x60 - ???		*/	0,		0,		0,
/* 0x61 - ???		*/	0,		0,		0,	
/* 0x62 - ???		*/	0,		0,		0,	
/* 0x63 - ???		*/	0,		0,		0,	
/* 0x64 - ???		*/	0,		0,		0,	
/* 0x65 - ???		*/	0,		0,		0,	
/* 0x66 - ???		*/	0,		0,		0,	
/* 0x67 - ???		*/	0,		0,		0,	
/* 0x68 - ???		*/	0,		0,		0,	
/* 0x69 - ???		*/	0,		0,		0,	
/* 0x6A - ???		*/	0,		0,		0,	
/* 0x6B - ???		*/	0,		0,		0,	
/* 0x6C - ???		*/	0,		0,		0,	
/* 0x6D - ???		*/	0,		0,		0,	
/* 0x6E - ???		*/	0,		0,		0,	
/* 0x6F - ???		*/	0,		0,		0,	
/* 0x70 - ???		*/	0,		0,		0,	
/* 0x71 - ???		*/	0,		0,		0,	
/* 0x72 - ???		*/	0,		0,		0,	
/* 0x73 - ???		*/	0,		0,		0,	
/* 0x74 - ???		*/	0,		0,		0,	
/* 0x75 - ???		*/	0,		0,		0,	
/* 0x76 - ???		*/	0,		0,		0,	
/* 0x77 - ???		*/	0,		0,		0,	
/* 0x78 - ???		*/	0,		0,		0,	
/* 0x78 - ???		*/	0,		0,		0,	
/* 0x7A - ???		*/	0,		0,		0,	
/* 0x7B - ???		*/	0,		0,		0,	
/* 0x7C - ???		*/	0,		0,		0,	
/* 0x7D - ???		*/	0,		0,		0,	
/* 0x7E - ???		*/	0,		0,		0,
/* 0x7F - ???		*/	0,		0,		0
};


unsigned int disp_pos;

int code_with_E0 = 0;
int shift_l = 0;
int shift_r = 0;
int alt_l = 0;
int alt_r = 0;
int ctrl_l = 0;
int ctrl_r = 0;
int caps_lock = 0;
int num_lock = 0;
int scroll_lock = 0;
int column = 0;





#define irq_disable(irq) ({ \
__asm__ __volatile__(" \
	pushfl; \
	cli; \
	movb $1, %%ah; \
	rolb %%cl, %%ah;\
	cmpb $8, %%cl; \
	jae 2f; \
	1: \
	inb $0x21, %%al; \
	testb %%ah, %%al; \
	jnz 3f; \
	orb %%ah, %%al; \
	outb %%al, $0x21; \
	jmp 3f; \
	2: \
	inb $0xa1, %%al; \
	testb %%ah, %%al; \
	jnz 3f; \
	orb %%ah, %%al; \
	outb %%al, $0xa1; \
	3: \
	popfl" \
	::"c"(irq)); \
})

#define irq_enable(irq) ({ \
__asm__ __volatile__(" \
	pushfl; \
	cli; \
	movb $~1, %%ah; \
	rolb %%cl, %%ah; \
	cmpb $8, %%cl; \
	jae 2f; \
	1: \
	inb $0x21, %%al; \
	andb %%ah, %%al; \
	outb %%al, $0x21; \
	jmp 3f; \
	2: \
	inb $0xa1, %%al; \
	andb %%ah, %%al; \
	outb %%al, $0xa1; \
	3: \
	popfl" \
	::"c"(irq)); \
})

int k_reenter = -1;
// Descriptor

typedef struct descriptor {
	short limit_low;
	short base_low;
	char base_mid;
	char access_right;
	char limit_high;
	char base_high;
}descriptor, *Descriptor;

typedef struct gate {
	short offset_low;
	short selector;
	char dw_count;
	char access_right;
	short offset_high;
}gate, *Gate;

// start process data struct

typedef struct tss {
	int backlink;
	int esp0;
	int ss0;
	int esp1;
	int ss1;
	int esp2;
	int ss2;
	int cr3;
	int eip;
	int eflags;
	int eax;
	int ecx;
	int edx;
	int ebx;
	int esp;
	int ebp;
	int esi;
	int edi;
	int es;
	int cs;
	int ss;
	int ds;
	int fs;
	int gs;
	int ldt_sel;
	short trap;
	short iobase;
}tss, *Tss;

typedef struct proc_stack {
	int gs;
	int fs;
	int es;
	int ds;
	int edi;
	int esi;
	int ebp;
	int kernel_esp;
	int ebx;
	int edx;
	int ecx;
	int eax;
	int retaddr;
	int eip;
	int cs;
	int eflags;
	int esp;
	int ss;
}proc_stack;

typedef struct process {
	proc_stack procstack;
	
	short ldt_selector;
	descriptor ldt[0x10];
	int pid;
	char name[32];
	unsigned int ticks;
	unsigned int priority;
}process, *Process;

// end process data struct


void print_s(char *str, char color, int j);
void halt(void);

void delay(int count);
void load_gdtr(int limit, int addr);
void load_idtr(int limit, int addr);
void asm_inthandler_all(void);
void asm_inthandler_0xd(void);
void asm_inthandler_0x20(void);
void asm_inthandler_0x21(void);
void ud2(void);

void testa(void);
void testb(void);
void testc(void);
void testd(void);
void teste(void);
void testf(void);
void testg(void);
void testh(void);

void set_descriptor(Descriptor sd, unsigned int limit, int base, int attrib);
void set_gate(Gate gd, int offset, int selector, int attrib);

// S:copy from multiboot2 os example.
#define COLUMNS 80
#define LINES 24
#define ATTRIBUTE 7
#define VIDEO 0xb8000
     
static int xpos;
static int ypos;
static volatile unsigned char *video;
     
static void cls (void);
static void itoa (char *buf, int base, int d);
static void putchar (int c);
void printf (const char *format, ...);


void out(int port, int value);
int in(int port);
void sti(void);
void cli(void);
void init_8259a(void);
void init_8254(void);

int mycount = 0;

char *func_stack = (char *)0x800000;

process p_proc[8];
Process p_proc_ready, myproc;
tss tss0;
Tss mytss = &tss0;


typedef void (*task_f)(void);

typedef struct s_task {
	task_f initial_eip;
	int stacksize;
	char name[0x20];
}task, *Task;

task task_table[8] = {{testa, 0x400, "testa"}, \
					  {testb, 0x400, "testb"}, \
					  {testc, 0x400, "testc"}, \
					  {testd, 0x400, "testd"}, \
					  {teste, 0x400, "teste"}, \
					  {testf, 0x400, "testf"}, \
					  {testg, 0x400, "testg"}, \
					  {testh, 0x400, "testh"}};
					  

void goto_ring3(void);
void ltr(int tr);
void init_tss(Tss mytss, Descriptor mygdt);
void init_proc_table(Process myproc, Task mytask, Descriptor mygdt);
void schedule(Process p);


//keyboard

typedef struct kb_fifo {
	unsigned char *head;
	unsigned char *tail;
	int count;
	unsigned char buf[512];
}kb_fifo, *Kb_fifo;

kb_fifo myfifo;

void kb_fifo_init(Kb_fifo fifo) {
	fifo->count = 0;
	fifo->head = fifo->tail = fifo->buf;
}

void kb_fifo_put(Kb_fifo fifo, unsigned char ch) {
	if(fifo->head < 512 + fifo->buf) {
		*(fifo->head) = ch;
		fifo->head++;
		if(fifo->head == 512 + fifo->buf) {
			fifo->head = fifo->buf;
		}
		fifo->count++;
	}
}

unsigned char kb_fifo_get(Kb_fifo fifo) {
	unsigned char ch;
	while(fifo->count <= 0) {};
	
	cli();
	ch = *(fifo->tail);
	fifo->tail++;
	if(fifo->tail == 512 + fifo->buf) {
		fifo->tail = fifo->buf;
	}
	fifo->count--;
	sti();
	return ch;
	
}

void in_process(unsigned int key);
void keyboard_read(Kb_fifo fifo);

int sys_get_ticks(void);
typedef void *system_call;
system_call system_call_table[1] = {sys_get_ticks};
void system_interrupt(void);
int get_ticks(void);

int kernel_main(int eax, int ebx) {
	cls();	
	
	Process myproc;
	myproc = p_proc;
	
	Descriptor mygdt = (Descriptor) 0x7c00;
	Gate myidt = (Gate) 0x0;
	set_descriptor(mygdt + 0, 0, 0, 0); //0 * 8
	set_descriptor(mygdt + 1, 0xffffffff, 0x0, 0xc09a); //1 * 8
	set_descriptor(mygdt + 2, 0xffffffff, 0x0, 0xc092); //2 * 8
	load_idtr(256 * 8 - 1, (int) myidt);
	load_gdtr(256 * 8 - 1, (int) mygdt);
	
	Task p_task = task_table;
	init_proc_table(myproc, p_task, mygdt);
	int i;

	for(i = 0; i < 256; i++) {
		set_gate(myidt + i, (int) asm_inthandler_all, 1 * 8, 0x8e);
	}
	set_gate(myidt + 0xd, (int) asm_inthandler_0xd, 1 * 8, 0x8e);	
	set_gate(myidt + 0x20, (int) asm_inthandler_0x20, 1 * 8, 0x8e);
	set_gate(myidt + 0x21, (int) asm_inthandler_0x21, 1 * 8, 0x8e);
	set_gate(myidt + 0x80, (int) system_interrupt, 1 * 8, 0xee);


	init_tss(mytss, mygdt);
	
	init_8259a();
	init_8254();
	
	out(0x21, 0xff);
	out(0xa1, 0xff);
	
	irq_enable(0);
	irq_enable(1);
	
	kb_fifo_init(&myfifo);
	p_proc_ready = p_proc;
	goto_ring3();
	
	while(1) {
		print_s("I", 0xc, 10);
	}
	return 0;
}

void print_s(char *str, char color, int j) {
	int i = 0;
	while(*str) {
		while(*str == '\n') {
			str++;
			i = 0;
			j++;
		}
		if(!(*str)) {
			return;
		}
		*(video + i + j * 80 * 2) = *str++;
		*(video + i + 1 + j * 80 * 2) = color;
		i += 2;
	}
	return;
}
 
 
/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
static void cls (void) {
	int i;
	video = (unsigned char *) VIDEO;
	for (i = 0; i < COLUMNS * LINES * 2; i++)
		*(video + i) = 0;
	xpos = 0;
	ypos = 0;
	return;
}
     
/*  Convert the integer D to a string and save the string in BUF. If
BASE is equal to 'd', interpret that D is decimal, and if BASE is
equal to 'x', interpret that D is hexadecimal. */
static void itoa (char *buf, int base, int d) {
	char *p = buf;
	char *p1, *p2;
	unsigned long ud = d;
	int divisor = 10;

/*  If %d is specified and D is minus, put `-' in the head. */
	if (base == 'd' && d < 0) {
		*p++ = '-';
		buf++;
		ud = -d;
	}
	else if (base == 'x')
		divisor = 16;

/*  Divide UD by DIVISOR until UD == 0. */
	do {
		int remainder = ud % divisor;
		*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
	} while (ud /= divisor);

/*  Terminate BUF. */
	*p = 0;

/*  Reverse BUF. */
	p1 = buf;
	p2 = p - 1;
	while (p1 < p2) {
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2--;
	}
}

/*  Put the character C on the screen. */
static void putchar (int c) {
	if (c == '\n' || c == '\r') {
newline:
		xpos = 0;
		ypos++;
		if (ypos >= LINES)
			ypos = 0;
		return;
	}

	*(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
	*(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
	disp_pos = (xpos + ypos * COLUMNS) * 2;
	xpos++;
	if (xpos >= COLUMNS)
		goto newline;
}
     
/*  Format a string and print it on the screen, just like the libc
function printf. */
void printf (const char *format, ...) {
	char **arg = (char **) &format;
	int c;
	char buf[20];
	arg++;

	while ((c = *format++) != 0) {
		if (c != '%')
			putchar (c);
		else {
			char *p, *p2;
			int pad0 = 0, pad = 0;
			c = *format++;
			if (c == '0') {
				pad0 = 1;
				c = *format++;
			}

			if (c >= '0' && c <= '9')
				{
				pad = c - '0';
				c = *format++;
				}

			switch (c) {
				case 'd':
				case 'u':
				case 'x':
					itoa (buf, c, *((int *) arg++));
					p = buf;
					goto string;
					break;
				case 's':
					p = *arg++;
					if (! p)
					p = "(null)";
string:
					for (p2 = p; *p2; p2++);
					for (; p2 < p + pad; p2++)
					putchar (pad0 ? '0' : ' ');
					while (*p)
					putchar (*p++);
					break;
				default:
					putchar (*((int *) arg++));
					break;
			}
		}
	}
}

void *memcpy(void *dest, void *source, int count) {
	int i;
	void *temp = dest;
	for(i = 0; i < count; i++) {
		 *((char *)dest++) = *((char *)source++);
	}
	return temp;
}

void set_descriptor(Descriptor sd, unsigned int limit, int base, int attrib) {
	if(limit > 0xfffff) {
		attrib |= 0x8000;
		limit /= 0x1000;
	}
	sd->limit_low = limit & 0xffff;
	sd->base_low = base & 0xffff;
	sd->base_mid = (base >> 16) & 0xff;
	sd->access_right = attrib & 0xff;
	sd->limit_high = ((limit >> 16) & 0x0f) | ((attrib >> 8) & 0xf0);
	sd->base_high = (base >> 24) & 0xff;
	return;
}

void set_gate(Gate gd, int offset, int selector, int attrib) {
	gd->offset_low = offset & 0xffff;
	gd->selector = selector;
	gd->dw_count = (attrib >> 8) & 0xff;
	gd->access_right = attrib & 0xff;
	gd->offset_high = (offset >> 16) & 0xffff;
	return;
}

void inthandler_all(int *esp) {
	printf("Exception! 0x%x", esp);
	while(1) {
		halt();
	}
	return;
}

void inthandler_0xd(int *esp) {
	printf("general protection! 0x%x", esp);
	while(1) {
		halt();
	}
	return;
}




void inthandler_0x21(int *esp) {
	out(0x20, 0x60);
	char key = (char)in(0x60);
	kb_fifo_put(&myfifo, key);
	return;
}


int ia = 0;
void testa(void) {
	while(1) {
		keyboard_read(&myfifo);
	}
}


void keyboard_read(Kb_fifo fifo) {
	unsigned int make, key, *keyrow;
	unsigned char ch;
	if(fifo->count > 0) {		
		code_with_E0 = 0;
		ch = kb_fifo_get(fifo);
		if(ch == 0xe1) {
			int i; 
			unsigned char pausebrk_scode[] = {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5};
			int is_pausebreak = 1;
			for(i = 1; i < 6; i++) {
				if (kb_fifo_get(fifo) != pausebrk_scode[i]) {
					is_pausebreak = 0;
					break;
				}
			}
			if(is_pausebreak) {
				key = PAUSEBREAK;
			}	
		} else if(ch == 0xe0) {
			ch = kb_fifo_get(fifo);
			
			if (ch == 0x2a) {
				if(kb_fifo_get(fifo) == 0xe0) {
					if(kb_fifo_get(fifo) == 0x37) {
						key = PRINTSCREEN;
						make = 1;
					}
				}
			}
			
			if(ch == 0xb7) {
				if(kb_fifo_get(fifo) ==  0xe0) {
					if(kb_fifo_get(fifo) == 0xaa) {
						key = PRINTSCREEN;
						make = 0;
					}
				}
			}
			if(key == 0) {
				code_with_E0 = 1;
			}
		} 
		if((key != PAUSEBREAK) && (key != PRINTSCREEN)){
			make = (ch & 0x80 ? 0 : 1);
			keyrow = &keymap[(ch & 0x7f) * 3];
			column = 0;
			if(shift_l || shift_r) {
				column = 1;
			}
			if(code_with_E0) {
				column = 2;
				code_with_E0 = 0;
			}
			key = keyrow[column];
			
			switch(key) {
				case SHIFT_L:
					shift_l = make;
					break;
				case SHIFT_R:
					shift_r = make;
					break;
				case CTRL_L:
					ctrl_l = make;
					break;
				case CTRL_R:
					ctrl_r = make;
					break;
				case ALT_L:
					alt_l = make;
					break;
				case ALT_R:
					alt_r = make;
					break;
				default:
					break;		
			}
			if(make) {
				key |= shift_l ? FLAG_SHIFT_L : 0;
				key |= shift_r ? FLAG_SHIFT_R : 0;
				key |= ctrl_l ? FLAG_CTRL_L : 0;
				key |= ctrl_r ? FLAG_CTRL_R : 0;
				key |= alt_l ? FLAG_ALT_L : 0;
				key |= alt_r ? FLAG_ALT_R : 0;
				
				
				in_process(key);
			}	
		}                 
	}
}


void in_process(unsigned int key) {
	char output[2]= {'\0', '\0'};
	if(!(key & FLAG_EXT)) {
		output[0] = key & 0xff;
		printf("%s", output);
		cli();
		out(0x3d4, 0xe);
		out(0x3d5, ((disp_pos/2 >> 8) & 0xff));
		out(0x3d4, 0xf);
		out(0x3d5, ((disp_pos/2) & 0xff));
		sti();
	}
}

int ib = 0;
void testb(void) {
	char buf[0x20];
	for (;;) {
		itoa(buf, 10, ib++);
		print_s(buf, 0xc, 20);
	}
	return;
}


void testc(void) {
	char buf[0x20];
	while (1) {
//		itoa(buf, 10, get_ticks());
//		print_s(buf, 0xd, 21);
	}
	return;
}

int id = 0;
void testd(void) {
	while (1) {

	}
	return;
}

int ie = 0;
void teste(void) {
	while (1) {

	}
	return;
}

int iff = 0;
void testf(void) {
	while (1) {

	}
	return;
}

int ig = 0;
void testg(void) {
	while (1) {

	}
	return;
}

int ih = 0;
void testh(void) {
	while (1) {

	}
	return;
}



void init_8254(void) {
	out(0x43, 0x36);
	out(0x40, 0x9c);
	out(0x40, 0x2e);
	return;
}


void init_proc_table(Process myproc, Task mytask, Descriptor mygdt) {
	int i;
	for(i = 0; i < 8; i++) {
		myproc->ticks = myproc->priority = 1;
		if(!i) 
			myproc->ticks = myproc->priority = 15;
		myproc->pid = i;
		myproc->ldt_selector = (3 + i) * 8;
		set_descriptor(mygdt + (3 + i), 8 * 0x10 - 1, (int)myproc->ldt, 0xc0e2);
		set_descriptor(myproc->ldt + 0, 0xffffffff, 0x0, 0xc0fa); //0 * 8 + 7
		set_descriptor(myproc->ldt + 1, 0xffffffff, 0x0, 0xc0f2); //1 * 8 + 7
		myproc->procstack.gs = 0xf;
		myproc->procstack.fs = 0xf;
		myproc->procstack.es = 0xf;
		myproc->procstack.ds = 0xf;	
		myproc->procstack.edi = 0x0;
		myproc->procstack.esi = 0x0;
		myproc->procstack.ebp = 0x0;
		myproc->procstack.kernel_esp = 0;	
		myproc->procstack.ebx = 0x0;
		myproc->procstack.edx = 0x0;
		myproc->procstack.ecx = 0x0;
		myproc->procstack.eax = 0x0;
		myproc->procstack.retaddr = 0x0;	
		myproc->procstack.eip = (int)mytask->initial_eip;
		myproc->procstack.cs = 0x7;
		myproc->procstack.eflags = 0x3202;
		myproc->procstack.esp = (int)func_stack;
		myproc->procstack.ss = 0xf;
		
		myproc++;
		mytask++;
		func_stack -= 0x400;
	}
	return;
}

void init_tss(Tss mytss, Descriptor mygdt) {
	set_descriptor(mygdt + 20, sizeof(tss0), (int)mytss, 0xc0e9); //20 * 8
	mytss->backlink = 0;
	mytss->esp0 = 0;
	mytss->ss0 = 2 * 8;
	mytss->esp1= 0;
	mytss->ss1 = 0;
	mytss->esp2 = 0;
	mytss->ss2 = 0;
	mytss->cr3 = 0;
	mytss->eflags = 0;
	mytss->eax = 0;
	mytss->ecx = 0;
	mytss->edx = 0;
	mytss->esp = 0;
	mytss->ebp = 0;
	mytss->esi = 0;
	mytss->edi = 0;
	mytss->es = 0xf;
	mytss->cs = 0x7;
	mytss->ss = 0xf;
	mytss->ds = 0xf;
	mytss->fs = 0xf;
	mytss->gs = 0xf;
	mytss->ldt_sel = 0;
	mytss->trap = 0;
	mytss->iobase = sizeof(tss);
	ltr(20 * 8);
	return;
}

int ticks = 0;

void inthandler_0x20(int *esp) {
//	char buf[0x40];
//	print_s("timer interrupt!", 0xc, 23);
//	itoa(buf, 10, mycount++);
//	print_s(buf, 0xc, 24);
	ticks++;
	p_proc_ready->ticks--;
	if(p_proc_ready->ticks > 0)
		return;
	schedule(p_proc);
	return;
}

void schedule(Process p) {
//	p_proc_ready++;  // 时间片轮转法
//	if(p_proc_ready >= p_proc + 8)
//		p_proc_ready = p_proc;
	int myticks = 0; // 简单优先级法
	while(!myticks) {
		for(p = p_proc; p < p_proc + 8; p++) {
			if(p->ticks > myticks) {
				myticks = p->ticks;
				p_proc_ready = p;
			}
		}
		if(!myticks) {
			for(p = p_proc; p < p_proc + 8; p++) {
				p->ticks = p->priority;
			}
		}
	}
	return;
}

int sys_get_ticks(void) {
//	printf("%d", ticks);
	return ticks;
}
bits 32

section .text


_start:
	jmp mystart
align 8
header_start:
	dd 0xe85250d6
	dd 0x0
	dd header_end - header_start
	dd - (0xe85250d6 + 0x0 + (header_end - header_start))
	
add_tag_start:
	dw 0x2
	dw 0x0
	dd add_tag_end - add_tag_start
	dd header_start
	dd _start
	dd 0x0
	dd 0x0
add_tag_end:

entry_add_tag_start:
	dw 0x3
	dw 0x1
	dd entry_add_tag_end - entry_add_tag_start
	dd mystart
entry_add_tag_end:
align 8

;framebuffer_tag_start:
;	dw 0x5
;	dw 0x1
;	dd framebuffer_tag_end - framebuffer_tag_start
;	dd 800
;	dd 600
;	dd 16
;framebuffer_tag_end:
align 8

	dw 0x0
	dw 0x0
	dd 0x8
header_end:
align 8

bits 32
[section .text]
mystart:
	mov esp, _stack_start
	push 0
	popf
	cli	
	
	push ebx
	push eax
extern _kernel_main
	call _kernel_main
	add esp, 8

	jmp $
	
times 1024 dw 0
_stack_start:

times 1024 dw 0
_new_stack:

global _halt
_halt: ; void halt(void);
	hlt
	ret
	
	
global _delay
_delay: ;void delay(int count);
	push ecx
	mov ecx, [esp + 4 * 2]
next:
	loop next
	pop ecx
	ret

global _load_gdtr
_load_gdtr: ; void load_gdtr(int limit, int addr);
	mov ax, [esp + 4]
	mov [esp + 6], ax
	lgdt [esp + 6]
	
	jmp dword 0x8 : newstart
newstart:

	mov eax, 0x10
	mov ds, eax
	mov es, eax
	mov fs, eax
	mov gs, eax
	mov ss, eax

	ret

global _load_idtr
_load_idtr: ; void load_idtr(int limit, int addr);
	mov ax, [esp + 4]
	mov [esp + 6], ax
	lidt [esp + 6]
	ret
	
global _asm_inthandler_all
extern _inthandler_all
_asm_inthandler_all: ; void asm_inthandler_all(void);
	push es
	push ds
	pushad
	mov eax, esp
	push eax
	mov eax, ss
	mov ds, eax
	mov es, eax
	call _inthandler_all
	pop eax
	popad
	pop ds
	pop es
	iret
	
global _asm_inthandler_0xd
extern _inthandler_0xd
_asm_inthandler_0xd: ; void asm_inthandler_0xd(void);
	push es
	push ds
	pushad
	mov eax, esp
	push eax
	mov eax, ss
	mov ds, eax
	mov es, eax
	call _inthandler_0xd
	pop eax
	popad
	pop ds
	pop es
	iret
	
global _asm_inthandler_0x20
extern _inthandler_0x20, _p_proc_ready, _mytss, _k_reenter


_asm_inthandler_0x20: ; void asm_inthandler_0x20(void);
	sub esp, 4
	pushad
	push ds
	push es
	push fs
	push gs
	mov dx, ss
	mov ds, dx
	mov es, dx
		
	in al, 0x21
	or al, 1
	out 0x21, al
	
	mov al, 0x20
	out 0x20, al
	
	inc dword [_k_reenter]
	cmp dword [_k_reenter], 0
	jne .re_enter
	
	mov esp, _new_stack
	
	sti
	
	call _inthandler_0x20
	
	cli
	
	in al, 0x21
	and al, ~1
	out 0x21, al
	
	mov esp, [_p_proc_ready]
	lldt [esp + 72]
	lea eax, [esp + 72]
	mov [_mytss + 4], eax

.re_enter:
	dec dword [_k_reenter]
	pop gs
	pop fs
	pop es
	pop ds
	popad
	add esp, 4

	iretd
	
global _asm_inthandler_0x21
extern _inthandler_0x21
_asm_inthandler_0x21: ; void asm_inthandler_0x21(void);
	sub esp, 4
	pushad
	push ds
	push es
	push fs
	push gs
	mov dx, ss
	mov ds, dx
	mov es, dx
	
	mov al, 0x20
	out 0x20, al
	
	inc dword [_k_reenter]
	cmp dword [_k_reenter], 0
	jne .re_enter
	
	mov esp, _new_stack
	
	
	call _inthandler_0x21
	
	
	mov esp, [_p_proc_ready]
	lldt [esp + 72]
	lea eax, [esp + 72]
	mov [_mytss + 4], eax

.re_enter:
	dec dword [_k_reenter]
	
	pop gs
	pop fs
	pop es
	pop ds
	popad
	add esp, 4

	iretd

global _ud2
_ud2: ; void ud2(void);
	ud2
	ret
	
global _sti
_sti: ; void sti(void);
	sti
	ret

global _cli	
_cli: ; void cli(void);
	cli
	ret

global _init_8259a
_init_8259a:
	mov al, 0x11
	out 0x20, al
	nop
	out 0xa0, al
	nop
	mov al, 0x20
	out 0x21, al
	nop
	mov al, 0x28
	out 0xa1, al
	nop
	mov al, 0x04
	out 0x21, al
	nop
	mov al, 0x02
	out 0xa1, al
	nop
	mov al, 0x01
	out 0x21, al
	nop
	out 0xa1, al
	nop
	mov al, 0xff
	out 0x21, al
	nop
	out 0xa1, al
	nop
	ret	

global _out
_out: ; void out(int port, int value);
	mov edx, [esp + 1 * 4]
	mov eax, [esp + 2 * 4]
	out dx, al
	ret

global _in	
_in: ; unsigned char in(int port);
	mov edx, [esp + 1 * 4]
	xor eax, eax
	in al, dx
	ret
	
global _goto_ring3
extern _p_proc_ready, _mytss
_goto_ring3: ; void goto_ring3(void);
	mov esp, [_p_proc_ready]
	lldt [esp + 72]
	lea eax, [esp + 72]
	mov [_mytss + 4], eax
	
	pop gs
	pop fs
	pop es
	pop ds
	popad
	add esp, 4
	iretd

global _ltr	
_ltr: ; void ltr(short tr);
	mov ax, [esp + 4]
	ltr ax
	ret
	
	
global _system_interrupt
extern _sys_call, _p_proc_ready, _mytss, _k_reenter, _system_call_table


_system_interrupt: ; void system_interrupt(void);
	sub esp, 4
	pushad
	push ds
	push es
	push fs
	push gs
	mov dx, ss
	mov ds, dx
	mov es, dx
	
	mov edx, esp
	
	
	inc dword [_k_reenter]
	cmp dword [_k_reenter], 0
	jne .re_enter
	
	mov esp, _new_stack
	
	
	call [_system_call_table + eax * 4]
	mov [edx + 11 * 4 - 0], eax
	

	mov esp, [_p_proc_ready]
	lldt [esp + 72]
	lea eax, [esp + 72]
	mov [_mytss + 4], eax

.re_enter:
	dec dword [_k_reenter]
	pop gs
	pop fs
	pop es
	pop ds
	popad
	add esp, 4

	iret
	
global _get_ticks

_get_ticks:
	mov eax, 0
	int 0x80
	ret

猜你喜欢

转载自blog.csdn.net/weixin_39410618/article/details/85043430