百度网盘下载地址:
https://pan.baidu.com/s/1_-IznMWL3z1CROziiD6mCw
kernel.c
typedef char * va_list;
#ifdef __cplusplus
#define _ADDRESSOF(v) ( &reinterpret_cast<const char &>(v) )
#else
#define _ADDRESSOF(v) ( &(v) )
#endif
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap) ( ap = (va_list)0 )
#define Test_va_start _crt_va_start
#define Test_va_arg _crt_va_arg
#define Test_va_end _crt_va_end
#define ZEROPAD 1
#define SIGN 2
#define PLUS 4
#define SPACE 8
#define LEFT 16
#define SPECIAL 32
#define LARGE 64
int _div(long* n,unsigned base);
static inline int isdigit(int ch);
static int skip_atoi(const char **s);
static char *Test_number(char *str, long num, int base, int size, int precision, int type);
int Test_vsprintf(char *buf, const char *fmt, va_list args);
int strnlen(const char * s, int precision);
int sprintf(char *buf, const char *fmt, ...);
void fillbox(int color, int x0, int y0, int x1, int y1);
void myfillbox(int color, int x0, int y0, int x1, int y1);
void makefont16 (int color, int x, int y, short *font);
void print_gb2312(int color, int x, int y, unsigned char *str);
void delay(int count);
void *memcpy(void *dest, void *source, int count);
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];
}process, *Process;
// end process data struct
void mypaint(unsigned int eax, unsigned int ebx);
void load_idtr(int limit, int addr);
void load_gdtr(int limit, int addr);
void set_descriptor(Descriptor sd, unsigned int limit, int base, int attrib);
void set_gate(Gate gd, int offset, int selector, int attrib);
void asm_inthandler_all(void);
void asm_inthandler_0xd(void);
//void inthandler_all(int *esp);
void ud2(void);
void func_a(void);
void func_b(void);
typedef struct mystack {
char stack[0x200];
}mystack, *Mystack;
mystack func_stack[20];
char *func_a_stack;
void set_eflags(int value);
void goto_ring3(void);
void ltr(int tr);
void init_tss(Tss mytss);
void init_proc_table(Process myproc);
process p_proc[20];
Process p_proc_ready, myproc;
tss tss0;
Tss mytss;
char string[] = "系统宕机!";
int kernel_main (unsigned int eax, unsigned int ebx) {
func_a_stack = (char *)(func_stack + 0x200);
p_proc_ready = myproc = p_proc;
mytss = &tss0;
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
set_descriptor(mygdt + 3, 8 * 0x10 - 1, (int)p_proc[0].ldt, 0xc0e2); //3 * 8
set_descriptor(mygdt + 4, sizeof(tss0) - 1, (int)mytss, 0xc0e9); //4 * 8
int k;
for(k = 0; k < 256; k++) {
set_gate(myidt + k, (int) asm_inthandler_all, 0x8, 0x8e);
}
set_gate(myidt + 0xd, (int) asm_inthandler_0xd, 0x8, 0x8e);
load_idtr(256 * 8 - 1, (int) myidt);
load_gdtr(256 * 8 - 1, (int) mygdt);
mypaint(eax, ebx);
set_eflags(0xffffbfff);
init_tss(mytss);
init_proc_table(p_proc_ready);
ltr(4 * 8);
goto_ring3();
// int divzero = 2 / 0;
// ud2();
return -1;
}
void mypaint(unsigned int eax, unsigned int ebx) {
fillbox(0x001e90ff, 0, 0, 799, 599);
char buf[0x100], buf0[0x100];
sprintf(buf, "eax = 0x%x ebx = 0x%x buf 的地址是 0x%x", eax, ebx, buf);
print_gb2312(0xfffffff, 0, 0, buf);
int i, j;
for(i = 0; i < 400; i += 16) {
fillbox(0xdddddddd, 16 + i, 16, 32 + i, 32);
delay(0xffffff);
}
for(i = 0; i < 200; i += 16) {
fillbox(0x88888888, 16 + i, 32, 32 + i, 48);
delay(0xffffff);
}
for(i = 0; i < 100; i += 16) {
fillbox(0x22222222, 16 + i, 48, 32 + i, 64);
delay(0xffffff);
}
print_gb2312(0x00000000, 0, 568, (char *) memcpy(buf0, buf, 0x100));
return;
}
void init_proc_table(Process myproc) {
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)func_a;
myproc->procstack.cs = 0x7;
// myproc->procstack.eflags = 0x1202;
myproc->procstack.esp = (int)func_a_stack;
myproc->procstack.ss = 0xf;
myproc->ldt_selector = 3 * 8;
set_descriptor(myproc->ldt + 0, 0xffffffff, 0x0, 0xc0fa); //0 * 8 + 7
set_descriptor(myproc->ldt + 1, 0xffffffff, 0x0, 0xc0f2); //1 * 8 + 7
}
void init_tss(Tss mytss) {
mytss->backlink = 0;
mytss->esp0 = 0;
mytss->ss0 = 1 * 8;
mytss->esp1= 0x0;
mytss->ss1 = 0x0;
mytss->esp2 = 0;
mytss->ss2 = 0;
mytss->cr3 = 0;
mytss->eflags = 0x200;
mytss->eax = 0;
mytss->ecx = 0;
mytss->edx = 0;
mytss->esp = (int)func_a_stack;
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 = 3 * 8;
mytss->trap = 0;
mytss->iobase = 0x8000;
}
void fillbox(int color, int x0, int y0, int x1, int y1) {
int *myfb = (int *)0xe0000000;
int xsize = 800;
int x, y;
for (y = 0; y <= y1 - y0; y++) {
for (x = 0; x <= x1 - x0; x++) {
myfb[x0 + x + (y0 + y) * xsize] = color;
}
}
}
void print_ascii (int color, int x, int y, char *font) {
int *myfb = (int *)0xe0000000;
int xsize = 800;
char d;
int *p;
int i;
for (i = 0; i < 16; i++){
p = myfb + (y + i) * xsize + x;
d = font[i];
if ((d & 0x80) != 0) {p[0] = color;}
if ((d & 0x40) != 0) {p[1] = color;}
if ((d & 0x20) != 0) {p[2] = color;}
if ((d & 0x10) != 0) {p[3] = color;}
if ((d & 0x08) != 0) {p[4] = color;}
if ((d & 0x04) != 0) {p[5] = color;}
if ((d & 0x02) != 0) {p[6] = color;}
if ((d & 0x01) != 0) {p[7] = color;}
}
return;
}
void makefont16 (int color, int x, int y, short *font) {
int *myfb = (int *)0xe0000000;
int xsize = 800;
short d;
int *p;
int i;
for (i = 0; i < 16; i++){
p = myfb + (y + i) * xsize + x;
d = font[i];
if ((d & 0x80) != 0) {p[0] = color;}
if ((d & 0x40) != 0) {p[1] = color;}
if ((d & 0x20) != 0) {p[2] = color;}
if ((d & 0x10) != 0) {p[3] = color;}
if ((d & 0x08) != 0) {p[4] = color;}
if ((d & 0x04) != 0) {p[5] = color;}
if ((d & 0x02) != 0) {p[6] = color;}
if ((d & 0x01) != 0) {p[7] = color;}
if ((d & 0x8000) != 0) {p[8] = color;}
if ((d & 0x4000) != 0) {p[9] = color;}
if ((d & 0x2000) != 0) {p[10] = color;}
if ((d & 0x1000) != 0) {p[11] = color;}
if ((d & 0x800) != 0) {p[12] = color;}
if ((d & 0x400) != 0) {p[13] = color;}
if ((d & 0x200) != 0) {p[14] = color;}
if ((d & 0x100) != 0) {p[15] = color;}
}
return;
}
void print_gb2312(int color, int x, int y, unsigned char *str) {
extern short font[0x8000];
extern char myfont[0x1000];
int i = 0, j = 0;
unsigned char a, b;
unsigned int offset;
while (str[i] != 0) {
if (str[i] < 0x80) {
a = str[i];
print_ascii (color, x + j, y, myfont + a * 16);
if (str[i + 1] == 0)
break;
i++;
j += 8;
} else {
a = str[i] - 0xa0;
b = str[i + 1] - 0xa0;
offset = ((a - 1) * 94 + (b - 1)) * 16;
makefont16 (color, x + j , y, font + offset);
i += 2;
j += 16;
}
}
return;
}
int sprintf(char *buf, const char *fmt, ...)
{
va_list args;
int val = 1;
Test_va_start(args, fmt);
Test_vsprintf(buf, fmt, args);
Test_va_end(args);
return val;
}
int _div(long* n,unsigned base)
{
int __res;
__res = ((unsigned long) *n) % (unsigned) base;
*n = ((unsigned long) *n) / (unsigned) base;
return __res;
}
#define do_div(n,base) _div(&n,base)
static inline int isdigit(int ch)
{
return (ch >= '0') && (ch <= '9');
}
static int skip_atoi(const char **s)
{
int i = 0;
while (isdigit(**s))
i = i * 10 + *((*s)++) - '0';
return i;
}
static char *Test_number(char *str, long num, int base, int size, int precision, int type)
{
char c, sign, tmp[66];
const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
int i;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if (num < 0) {
sign = '-';
num = -num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
{
tmp[i++] = '0';
}
else
{
while (num != 0)
{
tmp[i++] = digits[do_div(num, base)];
}
}
if (i > precision)
precision = i;
size -= precision;
if (!(type & (ZEROPAD + LEFT)))
while (size-- > 0)
*str++ = ' ';
if (sign)
*str++ = sign;
if (type & SPECIAL) {
if (base == 8)
*str++ = '0';
else if (base == 16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
return str;
}
int Test_vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
unsigned long num;
int i, base;
char *str;
const char *s;
int flags;
int field_width;
int precision;
int qualifier;
for (str = buf; *fmt; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
flags = 0;
repeat:
++fmt;
switch (*fmt) {
case '-':
flags |= LEFT;
goto repeat;
case '+':
flags |= PLUS;
goto repeat;
case ' ':
flags |= SPACE;
goto repeat;
case '#':
flags |= SPECIAL;
goto repeat;
case '0':
flags |= ZEROPAD;
goto repeat;
}
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
field_width = Test_va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
precision = -1;
if (*fmt == '.') {
++fmt;
if (isdigit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
precision = Test_va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
qualifier = *fmt;
++fmt;
}
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char)Test_va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
continue;
case 's':
s = Test_va_arg(args, char *);
len = strnlen(s, precision);
if (!(flags & LEFT))
while (len < field_width--)
*str++ = ' ';
for (i = 0; i < len; ++i)
*str++ = *s++;
while (len < field_width--)
*str++ = ' ';
continue;
case 'p':
if (field_width == -1) {
field_width = 2 * sizeof(void *);
flags |= ZEROPAD;
}
str = Test_number(str,
(unsigned long)Test_va_arg(args, void *), 16,
field_width, precision, flags);
continue;
case 'n':
if (qualifier == 'l') {
long *ip = Test_va_arg(args, long *);
*ip = (str - buf);
} else {
int *ip = Test_va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
*str++ = '%';
continue;
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
continue;
}
if (qualifier == 'l')
num = Test_va_arg(args, unsigned long);
else if (qualifier == 'h') {
num = (unsigned short)Test_va_arg(args, int);
if (flags & SIGN)
num = (short)num;
} else if (flags & SIGN)
num = Test_va_arg(args, int);
else
num = Test_va_arg(args, unsigned int);
str = Test_number(str, num, base, field_width, precision, flags);
}
*str = '\0';
return str - buf;
}
int strnlen(const char * s, int precision) {
int len = 0;
while (*s++ != 0) {
len++;
}
return len;
}
void *memcpy(void *dest, void *source, int count) {
int i;
for(i = 0; i < count; i++) {
*((char *)dest++) = *((char *)source++);
}
return dest;
}
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) {
char buf[0x100];
sprintf(buf, "发生了异常 0x%x", *esp);
print_gb2312(0xffffffff, 400, 584, buf);
return;
}
void inthandler_0xd(int *esp) {
char buf[0x100];
sprintf(buf, "发生通用保护异常 0x%x", *esp);
print_gb2312(0xffffffff, 400, 552 - 32, buf);
return;
}
void func_a(void) {
char buf[0x100];
int i = 0;
while (1) {
sprintf(buf, "我是进程A %d", i++);
print_gb2312(0x00000000, 600, 0, buf);
delay(0xffffff);
fillbox(0x001e90ff, 600, 0, 600 + 128, 16);
}
return;
}
void func_b(void) {
char buf[0x100];
int i = 0;
while (1) {
sprintf(buf, "我是进程B %d", i++);
print_gb2312(0x00000000, 600, 0, buf);
delay(0xffffff);
fillbox(0x001e90ff, 600, 0 + 16, 600 + 128, 16 + 16);
}
return;
}
boot.s
bits 32
section .text
global _start
extern _kernel_main, _print_gb2312, _string
_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 32
framebuffer_tag_end:
align 8
dw 0x0
dw 0x0
dd 0x8
header_end:
align 8
mystart:
mov esp, _stack_start
push 0
popf
push ebx
push eax
call _kernel_main
add esp, 4 * 2
here:
push _string
push dword [y]
push dword [x]
push dword [color]
call _print_gb2312
add esp, 4 * 4
hlt
jmp here
y: dd 584
x: dd 0
color:
dd 0x00ff0000
global _stack_start
times 0x1000 db 0
align 0x1000
_stack_start:
global _delay
_delay: ;void(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 _ud2
_ud2: ; void ud2(void);
ud2
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 _set_eflags
_set_eflags: ; void set_eflags(int value);
pushf
mov eax, [esp + 8]
and [esp + 0], eax
popf
ret
global _sti
_sti: ; void sti(void);
sti
ret
global _cli
_cli: ; void cli(void);
cli
ret