Skip to content

Commit

Permalink
保护操作系统(2)
Browse files Browse the repository at this point in the history
  • Loading branch information
yourtion committed May 4, 2016
1 parent 17b1469 commit 0fd3455
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 23 deletions.
2 changes: 1 addition & 1 deletion 21_day/bootpack.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void asm_inthandler27(void);
void asm_inthandler2c(void);
unsigned int memtest_sub(unsigned int start, unsigned int end);
void farjmp(int eip, int cs);
void farcall(int eip, int cs);
void start_app(int eip, int cs, int esp, int ds);
void asm_hrb_api(void);

/* fifo.c */
Expand Down
7 changes: 5 additions & 2 deletions 21_day/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
struct FILEINFO *finfo;
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
char name[18], *p;
char name[18], *p, *q;
int i;

/*根据命令行生成文件名*/
Expand All @@ -284,9 +284,11 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
if (finfo != 0) {
/*找到文件的情况*/
p = (char *) memman_alloc_4k(memman, finfo->size);
q = (char *) memman_alloc_4k(memman, 64 * 1024);
*((int *) 0xfe8) = (int) p;
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER);
set_segmdesc(gdt + 1004, 64 * 1024 - 1, (int) q, AR_DATA32_RW);
if (finfo->size >= 8 && strncmp(p + 4, "Hari", 4) == 0) {
p[0] = 0xe8;
p[1] = 0x16;
Expand All @@ -295,8 +297,9 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
p[4] = 0x00;
p[5] = 0xcb;
}
farcall(0, 1003 * 8);
start_app(0, 1003 * 8, 64 * 1024, 1004 * 8);
memman_free_4k(memman, (int) p, finfo->size);
memman_free_4k(memman, (int) q, 64 * 1024);
cons_newline(cons);
return 1;
}
Expand Down
197 changes: 177 additions & 20 deletions 21_day/naskfunc.nas
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
GLOBAL _asm_inthandler20, _asm_inthandler21
GLOBAL _asm_inthandler27, _asm_inthandler2c
GLOBAL _memtest_sub
GLOBAL _farjmp, _farcall
GLOBAL _farjmp, _start_app
GLOBAL _asm_hrb_api
EXTERN _inthandler20, _inthandler21
EXTERN _inthandler27, _inthandler2c
Expand Down Expand Up @@ -116,29 +116,77 @@ _asm_inthandler20:
PUSH ES
PUSH DS
PUSHAD
MOV EAX,ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler20
POP EAX
MOV AX,SS
CMP AX,1*8
JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler20
ADD ESP,8
POPAD
POP DS
POP ES
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler20
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
IRETD

_asm_inthandler21:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH EAX
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler21
ADD ESP,8
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler21
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
Expand All @@ -148,13 +196,37 @@ _asm_inthandler27:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH EAX
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler27
ADD ESP,8
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX ],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler27
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
Expand All @@ -164,13 +236,38 @@ _asm_inthandler2c:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app
; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH EAX
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler2c
ADD ESP,8
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX ],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler2c
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
Expand Down Expand Up @@ -213,15 +310,75 @@ _farjmp: ; void farjmp(int eip, int cs);
JMP FAR [ESP+4] ; eip, cs
RET

_farcall: ; void farcall(int eip, int cs);
CALL FAR [ESP+4] ; eip, cs
_start_app: ; void start_app(int eip, int cs, int esp, int ds);
PUSHAD ; 将32位寄存器的值全部保存起来
MOV EAX,[ESP+36] ; 应用程序用EIP
MOV ECX,[ESP+40] ; 应用程序用CS
MOV EDX,[ESP+44] ; 应用程序用ESP
MOV EBX,[ESP+48] ; 应用程序用DS/SS
MOV [0xfe4],ESP ; 操作系统用ESP
CLI ; 在切换过程中禁止中断请求
MOV ES,BX
MOV SS,BX
MOV DS,BX
MOV FS,BX
MOV GS,BX
MOV ESP,EDX
STI ; 切换完成后恢复中断请求
PUSH ECX ; 用于far-CALL的PUSH(cs)
PUSH EAX ; 用于far-CALL的PUSH(eip)
CALL FAR [ESP] ; 调用应用程序 ; 应用程序结束后返回此处
MOV EAX,1*8 ; 操作系统用DS/SS
CLI ; 再次进行切换,禁止中断请求
MOV ES,AX
MOV SS,AX
MOV DS,AX
MOV FS,AX
MOV GS,AX
MOV ESP,[0xfe4]
STI ; 切换完成后恢复中断请求
POPAD ; 恢复之前保存的寄存器值
RET

_asm_hrb_api:
STI
PUSHAD ; 用于保存寄存器值的PUSH
PUSHAD ; 用于向hrb_api传值的PUSH
; 为方便起见从开头就禁止中断请求
PUSH DS
PUSH ES
PUSHAD ; 用于保存的PUSH
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-40
MOV [ECX+32],ESP ; 保存应用程序的ESP
MOV [ECX+36],SS ; 保存应用程序的SS
; 将PUSHAD后的值复制到系统栈
MOV EDX,[ESP ]
MOV EBX,[ESP+ 4]
MOV [ECX ],EDX ; 复制传递给hrb_api
MOV [ECX+ 4],EBX ; 复制传递给hrb_api
MOV EDX,[ESP+ 8]
MOV EBX,[ESP+12]
MOV [ECX+ 8],EDX ; 复制传递给hrb_api
MOV [ECX+12],EBX ; 复制传递给hrb_api
MOV EDX,[ESP+16]
MOV EBX,[ESP+20]
MOV [ECX+16],EDX ; 复制传递给hrb_api
MOV [ECX+20],EBX ; 复制传递给hrb_api
MOV EDX,[ESP+24]
MOV EBX,[ESP+28]
MOV [ECX+24],EDX ; 复制传递给hrb_api
MOV [ECX+28],EBX ; 复制传递给hrb_api
MOV ES,AX ; 将剩余的段寄存器也设为操作系统用
MOV SS,AX
MOV ESP,ECX
STI ; 恢复中断请求
CALL _hrb_api
ADD ESP,32
MOV ECX,[ESP+32] ; 取出应用程序的ESP
MOV EAX,[ESP+36] ; 取出应用程序的SS
CLI
MOV SS,AX
MOV ESP,ECX
POPAD
IRETD
POP ES
POP DS
IRETD ; 这个命令会自动执行STI

0 comments on commit 0fd3455

Please sign in to comment.