整理文件夹

我们把所有的东西都放到了main.c中,一开始代码量很小其实无所谓,但随着代码量的增加我们有必要分门别类整理一下了

首先将下面代码放到io.h中

//读port端口
#define inb(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \
_v; \
})
//带延时的向port端口写value,用两条跳转语句做延时
#define outb_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
		"\tjmp 1f\n" \
		"1:\tjmp 1f\n" \
		"1:"::"a" (value),"d" (port))
//带延时的读port端口
#define inb_p(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
	"\tjmp 1f\n" \
	"1:\tjmp 1f\n" \
	"1:":"=a" (_v):"d" (port)); \
_v; \
})

将下面的代码放到system.h中

#define set_registers() \
__asm__ ("movl $0x17,%%eax\n\t" \
	"movw %%ax,%%ds\n\t" \
	"movw %%ax,%%es\n\t" \
	"movw %%ax,%%fs\n\t" \
	"movw $0x18,%%ax\n\t" \
	"movw %%ax,%%gs" \
	:::"ax")
#define set_stack_registers() \
__asm__ ("movl $0x10,%%eax\n\t" \
	"movw %%ax,%%ds\n\t" \
	"movw %%ax,%%es\n\t" \
	"movw %%ax,%%ss\n\t" \
	"lss  stack_start,%%esp"\
	:::"ax")
#define move_to_user_mode2() \
__asm__ ("movl %%esp,%%eax\n\t" \
	"pushl $0x17\n\t" \
	"pushl %%eax\n\t" \
	"pushfl\n\t"\
	"pushl $0xf\n\t" \
	"pushl $testA\n\t" \
	"iret\n" \
	:::"ax")
#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \
	"pushl $0x17\n\t" \
	"pushl %%eax\n\t" \
	"pushfl\n\t" \
	"pushl $0x0f\n\t" \
	"pushl $1f\n\t" \
	"iret\n" \
	"1:\tmovl $0x17,%%eax\n\t" \
	"movw %%ax,%%ds\n\t" \
	"movw %%ax,%%es\n\t" \
	"movw %%ax,%%fs\n\t" \
	"movw $0x18,%%ax\n\t" \
	"movw %%ax,%%gs" \
	:::"ax")
	
下面代码放到head.h中

typedef	unsigned int		u32;
typedef	unsigned short	u16;
typedef	unsigned char		u8;

typedef struct Descriptor		
{
	u16	limit_low;		/* Limit */
	u16	base_low;		/* Base */
	u8	base_mid;		/* Base */
	u8	attr1;			/* P(1) DPL(2) DT(1) TYPE(4) */
	u8	limit_high_attr2;	/* G(1) D(1) 0(1) AVL(1) LimitHigh(4) */
	u8	base_high;		/* Base */
}DESCRIPTOR;
#define DA_C    	0x98    
#define DA_32   	0x4000 	
#define	DA_DPL3		0x60
#define	DA_DPL0		0x00
#define	DA_DRWA 	0x93
#define	DA_DRW 		0x92
#define	SA_RPL3  	3 
#define	DA_CR		0x9A
#define	DA_LIMIT_4K	0x8000
#define	DA_386TSS 0x89	
#define DA_LDT  0x82

在include\linux下新建一个文件sched.h

#ifndef _SCHED_H
#define _SCHED_H
typedef struct tss_struct {
	u32	backlink;
	u32	esp0;	/* stack pointer to use during interrupt */
	u32	ss0;	/*   "   segment  "  "    "        "     */
	u32	esp1;
	u32	ss1;
	u32	esp2;
	u32	ss2;
	u32	cr3;
	u32	eip;
	u32	flags;
	u32	eax;
	u32	ecx;
	u32	edx;
	u32	ebx;
	u32	esp;
	u32	ebp;
	u32	esi;
	u32	edi;
	u32	es;
	u32	cs;
	u32	ss;
	u32	ds;
	u32	fs;
	u32	gs;
	u32	ldt;
	u16	trap;
	u16	iobase;		/* I/O位图基址大于或等于TSS段界限,就表示没有I/O许可位图 */
}TSS;
#define FIRST_TSS_ENTRY 4
#define FIRST_LDT_ENTRY 5
#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
#define switch_to(n) {\
struct {long a,b;} __tmp; \
__asm__("movw %%dx,%1\n\t" \
	"ljmp %0\n\t" \
	::"m" (*&__tmp.a),"m" (*&__tmp.b), \
	"d" (_TSS(n))); \
}
#define PAGE_SIZE 4096
#define NR_TASKS 64
struct task_struct {
	long state;
	long pid,father;
	struct desc_struct ldt[3];
/* tss for this task */
	struct tss_struct tss;
};
union task_union {
	struct task_struct task;
	char stack[PAGE_SIZE];
};
struct stack_struct{
	char stack[256];
	int  top;
};
#define INIT_TASK \
{  0,0,0,\
	{ \
		{0,0}, \
/* ldt */	{0x9f,0xc0fa00}, \
		{0x9f,0xc0f200}, \
	}, \
/*tss*/	{\
	}, \
}
#define lldt() \
__asm__ ("movw $0x28,%%ax\n\t" \
	"lldt     %%ax\n\t" \
	:::"ax")
		
#define ltr() \
__asm__ ("movw $0x20,%%ax\n\t" \
	"ltr     %%ax\n\t" \
	:::"ax")

extern void registe_task(union task_union * task,struct stack_struct *stack,void *test);

extern long volatile jiffies;

typedef struct {
	long * a;
	short b;
	} STACK_START;
extern STACK_START stack_start;
#endif


在kernel中新建chr_drv文件夹,并将keyboard.S移到这里,然后新建console.c、key_board.c、Makefile

chr_drv中的console.c

#include <linux/head.h>
#include <asm/system.h>
#include <asm/io.h>
extern void keyboard_interrupt(void);	
void con_init(void)
{
	register unsigned char a;
	set_trap_gate(0x21,&keyboard_interrupt);
	outb_p(inb_p(0x21)&0xfd,0x21);
	a=inb_p(0x61);
	outb_p(a|0x80,0x61);
	outb(a,0x61);

}

chr_drv中的key_board.c

#include <asm/io.h>
void none(void)
{
	disp_str("none");
}

void do_self(void)
{
	disp_str("do_self");
}

void ctrl(void)
{
	disp_str("ctrl");
}
void lshift(void)
{
	disp_str("lshift");
}
void rshift(void)
{
	disp_str("rshift");
}
void minus(void)
{
	disp_str("minus");
}
void alt(void)
{
	disp_str("alt");
}
void caps(void)
{
	disp_str("caps");
}
void func(void)
{
	disp_str("func");
}
void num(void)
{
	disp_str("num");
}
void scroll(void)
{
	disp_str("scroll");
}
void cursor(void)
{
	disp_str("cursor");
}
void unctrl(void)
{
	disp_str("unctrl");
}
void unlshift(void)
{
	disp_str("unlshift");
}
void unrshift(void)
{
	disp_str("unrshift");
}
void unalt(void)
{
	disp_str("unalt");
}
void uncaps(void)
{
	disp_str("uncaps");
}

typedef void (*function)(void);
#define Function(address)   (*(function)address)()
static function key_table[] =
{
   none,do_self,do_self,do_self	/* 00-03 s0 esc 1 2 */
	,do_self,do_self,do_self,do_self	/* 04-07 3 4 5 6 */
	,do_self,do_self,do_self,do_self	/* 08-0B 7 8 9 0 */
	,do_self,do_self,do_self,do_self	/* 0C-0F + ' bs tab */
	,do_self,do_self,do_self,do_self	/* 10-13 q w e r */
	,do_self,do_self,do_self,do_self	/* 14-17 t y u i */
	,do_self,do_self,do_self,do_self	/* 18-1B o p } ^ */
	,do_self,ctrl,do_self,do_self	/* 1C-1F enter ctrl a s */
	,do_self,do_self,do_self,do_self	/* 20-23 d f g h */
	,do_self,do_self,do_self,do_self	/* 24-27 j k l | */
	,do_self,do_self,lshift,do_self	/* 28-2B { para lshift , */
	,do_self,do_self,do_self,do_self	/* 2C-2F z x c v */
	,do_self,do_self,do_self,do_self	/* 30-33 b n m , */
	,do_self,minus,rshift,do_self	/* 34-37 . - rshift * */
	,alt,do_self,caps,func		/* 38-3B alt sp caps f1 */
	,func,func,func,func		/* 3C-3F f2 f3 f4 f5 */
	,func,func,func,func		/* 40-43 f6 f7 f8 f9 */
	,func,num,scroll,cursor		/* 44-47 f10 num scr home */
	,cursor,cursor,do_self,cursor	/* 48-4B up pgup - left */
	,cursor,cursor,do_self,cursor	/* 4C-4F n5 right + end */
	,cursor,cursor,cursor,cursor	/* 50-53 dn pgdn ins del */
	,none,none,do_self,func		/* 54-57 sysreq ? < f11 */
	,func,none,none,none		/* 58-5B f12 ? ? ? */
	,none,none,none,none		/* 5C-5F ? ? ? ? */
	,none,none,none,none		/* 60-63 ? ? ? ? */
	,none,none,none,none		/* 64-67 ? ? ? ? */
	,none,none,none,none		/* 68-6B ? ? ? ? */
	,none,none,none,none		/* 6C-6F ? ? ? ? */
	,none,none,none,none		/* 70-73 ? ? ? ? */
	,none,none,none,none		/* 74-77 ? ? ? ? */
	,none,none,none,none		/* 78-7B ? ? ? ? */
	,none,none,none,none		/* 7C-7F ? ? ? ? */
	,none,none,none,none		/* 80-83 ? br br br */
	,none,none,none,none		/* 84-87 br br br br */
	,none,none,none,none		/* 88-8B br br br br */
	,none,none,none,none		/* 8C-8F br br br br */
	,none,none,none,none		/* 90-93 br br br br */
	,none,none,none,none		/* 94-97 br br br br */
	,none,none,none,none		/* 98-9B br br br br */
	,none,unctrl,none,none		/* 9C-9F br unctrl br br */
	,none,none,none,none		/* A0-A3 br br br br */
	,none,none,none,none		/* A4-A7 br br br br */
	,none,none,unlshift,none		/* A8-AB br br unlshift br */
	,none,none,none,none		/* AC-AF br br br br */
	,none,none,none,none		/* B0-B3 br br br br */
	,none,none,unrshift,none		/* B4-B7 br br unrshift br */
	,unalt,none,uncaps,none		/* B8-BB unalt br uncaps br */
	,none,none,none,none		/* BC-BF br br br br */
	,none,none,none,none		/* C0-C3 br br br br */
	,none,none,none,none		/* C4-C7 br br br br */
	,none,none,none,none		/* C8-CB br br br br */
	,none,none,none,none		/* CC-CF br br br br */
	,none,none,none,none		/* D0-D3 br br br br */
	,none,none,none,none		/* D4-D7 br br br br */
	,none,none,none,none		/* D8-DB br ? ? ? */
	,none,none,none,none		/* DC-DF ? ? ? ? */
	,none,none,none,none		/* E0-E3 e0 e1 ? ? */
	,none,none,none,none		/* E4-E7 ? ? ? ? */
	,none,none,none,none		/* E8-EB ? ? ? ? */
	,none,none,none,none		/* EC-EF ? ? ? ? */
	,none,none,none,none		/* F0-F3 ? ? ? ? */
	,none,none,none,none		/* F4-F7 ? ? ? ? */
	,none,none,none,none		/* F8-FB ? ? ? ? */
	,none,none,none,none		/* FC-FF ? ? ? ? */
};
void do_keyboard(void)
{
	register unsigned char scan_code;
	scan_code=inb_p(0x60);
	if(scan_code==0xe0)
	{
		disp_str("0xe0");
	}
	else if(scan_code==0xe1)
	{
		disp_str("0xe1");
	}
	else
	{
		key_table[scan_code]();
	}
}	

makefile

# Makefile for the simple example kernel.
AS    =as
LD    =ld
LDFLAGS   = --oformat binary -N -e start -Ttext 0x0
CC    =gcc
CFLAGS	  = -I../../include

.c.s:
	$(CC) $(CFLAGS) \
	-S -o $*.s $<
.s.o:
	$(AS) -c -o $*.o $<
.c.o:
	$(CC) $(CFLAGS) \
	-c -o $*.o $<
OBJS  = keyboard.o key_board.o console.o
chr_drv.o:$(OBJS)
	$(LD) -r -o chr_drv.o $(OBJS)
	sync
clean:
	rm -f  *.o *.s

kernel目录下新建sched.c

#include <linux/head.h>
#include <linux/sched.h>
int current_task=0;

unsigned int TOTAL_TASK=0;
long volatile jiffies=0;
long user_stack [ PAGE_SIZE>>2 ] ;

STACK_START stack_start = { & user_stack [PAGE_SIZE>>2] , 0x20 };
void do_timer(void)
{

int next_task = current_task+1;
if(next_task>TOTAL_TASK-1)
	next_task = 0;
if(next_task!=current_task){
	current_task=next_task;
	switch_to(next_task);

}

}
void registe_task(union task_union * task,struct stack_struct *stack,void *process)
{
		//填充task1的TSS
	task->task.tss.backlink = 0;
	task->task.tss.esp0=PAGE_SIZE+(long)task;
	task->task.tss.ss0=0x10;
	task->task.tss.eip=process;
	task->task.tss.esp = &stack->top;

	task->task.tss.flags=0x200;
	task->task.tss.es=0x17;
	task->task.tss.cs=0xf;
	task->task.tss.ss=0x17;
	task->task.tss.ds=0x17;
	task->task.tss.fs=0x17;
	task->task.tss.gs=0x18;

	task->task.tss.ldt=(FIRST_LDT_ENTRY+TOTAL_TASK*2)*8;
	task->task.tss.trap=0x8000;
	task->task.tss.iobase=0x0;
	
	//init_task的LDT  0x28
	_set_gdt_desc(&gdt[FIRST_LDT_ENTRY+TOTAL_TASK*2],&(task->task.ldt[0]),0x40,DA_LDT);
	//task1的TSS  0x30
	_set_gdt_desc(&gdt[FIRST_TSS_ENTRY+TOTAL_TASK*2],&(task->task.tss),0x68,DA_386TSS+DA_DPL3);
	TOTAL_TASK++;

}

kernel目录下新建Makefile

# Makefile for the simple example kernel.
AS    =as
LD    =ld
LDFLAGS   = --oformat binary -N -e start -Ttext 0x0
CC    =gcc
CFLAGS	  = -I../include

.c.s:
	$(CC) $(CFLAGS) \
	-S -o $*.s $<
.s.o:
	$(AS) -c -o $*.o $<
.c.o:
	$(CC) $(CFLAGS) \
	-c -o $*.o $<

OBJS  = asm.o kliba.o System_call.o chr_drv/chr_drv.o Traps.o sched.o
kernel.o:$(OBJS)
	$(LD) -r -o kernel.o $(OBJS)
	sync

chr_drv/chr_drv.o:
	(cd chr_drv; make)

clean:
	rm -f  *.o *.s
	(cd chr_drv;make clean)

顶层Makefile修改成这样

# Makefile for the simple example kernel.
AS    =as
LD    =ld
LDFLAGS   = --oformat binary -N -e start -Ttext 0x0


all:Image
Image:boot/bootsect boot/setup system
	cat boot/bootsect boot/setup system >Image	
boot/bootsect:boot/bootsect.s
	$(AS) -o boot/bootsect.o -a boot/bootsect.s
	$(LD) $(LDFLAGS) -o boot/bootsect boot/bootsect.o
boot/setup:boot/setup.s
	$(AS) -o boot/setup.o -a boot/setup.s
	$(LD) $(LDFLAGS) -o boot/setup boot/setup.o
boot/head.o:boot/head.s
	$(AS) -o boot/head.o -a boot/head.s
init/main.o: init/main.c
	gcc -Iinclude -c -o init/main.o init/main.c
kernel/kernel.o:
	(cd kernel; make)
	
system:	boot/head.o  init/main.o kernel/kernel.o
	$(LD) $(LDFLAGS) -o system boot/head.o kernel/kernel.o init/main.o 
clean:
	rm -f  Image  system *.o *.s
	rm -f boot/head.o boot/setup boot/bootsect
	rm -f init/*.o
	(cd kernel; make clean)

整理后的main.c

#include <linux/head.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/sched.h>
void disp_str(char *info);
extern void timer_interrupt(void);
static union task_union init_task = {INIT_TASK,};


struct stack_struct stack0;
struct stack_struct stack1;
static union task_union task1 = {INIT_TASK,};
	

void delay(int time)
{
	int i, j, k;
	for (k = 0; k < time; k++) {
		for (i = 0; i < 10; i++) {
			for (j = 0; j < 10000; j++) {}
		}
	}
}


void testC(void)		
{
	while(1){
		disp_str("C");
		delay(2);
	}
}


void _set_gdt_desc(struct desc_struct *descriptor_addr,u32 base,u32 limit,u16 attr)
{
	DESCRIPTOR *descriptor = (DESCRIPTOR *)descriptor_addr;
	descriptor->limit_low	= limit & 0x0FFFF;
	descriptor->base_low		= base & 0x0FFFF;
	descriptor->base_mid		= (base >> 16) & 0x0FF;
	descriptor->attr1			= attr & 0xFF;
	descriptor->limit_high_attr2= ((limit>>16) & 0x0F) | (attr>>8) & 0xF0;
	descriptor->base_high	= (base >> 24) & 0x0FF;
}
void rebuid_gdt(void)
{
	_set_gdt_desc(&gdt[1],0x0000,0x7ff,DA_CR+DA_32+DA_LIMIT_4K);
	//堆栈段 0x10
	_set_gdt_desc(&gdt[2],0x0000,0x7ff,DA_DRW+DA_32+DA_LIMIT_4K);
	//视频段 0x18
	_set_gdt_desc(&gdt[3],0xb8000,0x2,DA_DRW+DA_32+DA_DPL3+DA_LIMIT_4K);
}
void timer_init(void)
{
	set_intr_gate(32,&timer_interrupt);
}

		
void main(void)
{

	disp_str("How old are you?\n");
	con_init();
	timer_init();
	rebuid_gdt();
	stack_start.b=0x10;
	set_stack_registers();
	registe_task(&init_task,&stack0,0);
	registe_task(&task1,&stack1,&testC);
	ltr();//加载tss
	lldt();//加载ldt
	sti();//开中断
	move_to_user_mode();

	while(1){
		disp_str("M");
		delay(2);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值