⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 system.asm

📁 别人的根据linux0.11改的一个小的操作系统
💻 ASM
字号:
[bits 32]
[section .text]
	global	_sysEntry			;system kernel entry
	extern	_main                           ;we must programme use gcc
;ok,kernel start at here
_sysEntry:
	;move itself to 9000h,and jmp to execute
	mov	ax,DATASEL
	mov	ds,ax
	mov	es,ax
	mov	esi,SYS_ENTRY
	add	esi,17000h-09000h               ;source address :17000h+SYS_ENTRY
	mov	edi,SYS_ENTRY                   ;destination address :SYS_ENTRY
	mov	ecx,SYS_END-SYS_ENTRY+4800h	   ;it's length
	shr	ecx,02h                         ;move it as double word
	inc	ecx                            ;length >= length of itself
	cld
	rep	movsd
	jmp CODESEL:dword SYS_ENTRY

SYS_ENTRY:
	mov	ax,DATASEL
	mov	ds,ax
	mov	es,ax
	mov	fs,ax
	mov	gs,ax
	mov	ss,ax
	mov esp,_stack0_ptr
	;call	set_base
	call setIdt
	call setGdt
    mov	ax,DATASEL
	mov	ds,ax
	mov	fs,ax
	mov	gs,ax
	mov	es,ax
	mov	ss,ax
	mov	esp,_stack0_ptr
;initialize 8253/54
	call setClk
	mov	esi,msg
	mov	edi,160*5
	call printMsg
	call setPdt

	xor	eax,eax
	push eax
	push eax
	push eax
	push L
	push _main
	ret
L:
	jmp	$
;----------------------------------------
setPdt:
	mov	ax,DATASEL
	mov	ds,ax
	mov	es,ax
	mov	ecx,PG_DIR_LEN+(PGS*PG_LEN)
	shr	ecx,02h
	mov	edi,PG_DIR
	xor	eax,eax
	cld
	rep	stosd

	mov	dword [PG_DIR],PG0+07h
	mov	dword [PG_DIR+(04h*1)],PG1+07h
	mov	dword [PG_DIR+(04h*2)],PG2+07h
	mov	dword [PG_DIR+(04h*3)],PG3+07h
	mov	dword [PG_DIR+(04h*4)],PG4+07h
	mov	dword [PG_DIR+(04h*5)],PG5+07h
	mov	dword [PG_DIR+(04h*6)],PG6+07h
	mov	dword [PG_DIR+(04h*7)],PG7+07h

	mov	edi,PG0
	mov	eax,00000007h
	mov	ecx,1024*8
	cld
rp_fill:
	stosd
	add	eax,1000h
	loop rp_fill

	xor	eax,eax
	mov	cr3,eax

	mov	eax,cr0
	or eax,80000000h
	mov	cr0,eax
	ret
;----------------------------------------
;set GDTR
setGdt:
	lgdt	[_gdtr]
	ret
;----------------------------------------
;you must set the interrupt descriptor one by one
;of cource,these is easy implement of interrupt,in the
;furture,we must define more applier interrupt routine
setIdt:
    cli
	mov	eax,ignore_int
	mov	edx,00080000h
	mov	dx,ax
	mov	ax,8e00h
	mov	esi,_idt
	mov	ecx,256
rp_setIdt:
	mov	[esi],edx
	mov	[esi+4],eax
	add	esi,08h
	loop rp_setIdt
	;fill timer interrupt handler
	mov	eax,timerInt
	mov	edx,00080000h
	mov	dx,ax
	mov	ax,8e00h
	mov	esi,_idt+20h*08h
	mov	[esi],edx
	mov	[esi+4],eax
	;fill system call interrupt 80h
	mov	eax,system_interrupt
	mov	edx,00080000h
	mov	dx,ax
	mov	ax,0ef00h
	mov	esi,_idt+80h*08h
	mov	[esi],edx
	mov	[esi+4],eax

	lidt [_idtr]
	ret
;----------------------------------------
setClk:
	mov	al,36h
	out	43h,al
	wait
	;mov	ax,11930
    mov ax,0ffffh
	out	40h,al
	wait
	mov	al,ah
	out	40h,al
	wait
	ret
;----------------------------------------
;esi:msg offset
;edi:screen position
printMsg:
	push es
	push ax
	mov ax,VIDEOSEL
	mov es,ax
	mov	ah,07h
	cld
nextChar:
	lodsb
	or al,al
	jz tip
	stosw
	jmp nextChar
tip:
	pop ax
	pop es
	ret
;-----------------------------------
;interrupt handler
ignore_int:
    push ds
    push es
    push fs


	mov	ax,DATASEL
	mov	ds,ax
	mov	dx,0c4bh
	call __write_char

	pop fs
	pop es
	pop ds
	iret
;-----------------------------------------
	extern _do_timer
;timer interrupt routine 20h
timerInt:
    push ds
    push es
    push edx
    push eax
	mov	ax,DATASEL
	mov	ds,ax
	mov es,ax
	inc	dword [ds:__jiffies]

    mov	al,20h
	out	20h,al
	call	_do_timer

    pop eax
    pop edx
    pop es
    pop ds
	iret
;----------------------------------------
system_interrupt:
    push    ebx
    push    ds

	mov	ebx,10h
	mov	ds,bx
	mov	ebx,eax
	shl	ebx,02h
	add	ebx,__call
	call	dword [ebx]

    pop     ds
    pop     ebx
	iret
;---------------------------------------
	global	_kb_interrupt
	extern	_do_kb_interrupt
_kb_interrupt:
	push	eax
	push	edx
	push	ds

	in     al,60h
	mov    ah,al
	wait
	in     al,61h
	wait
    or     al,80h
	out    61h,al
	wait
	and    al,7fh
	out    61h,al

    mov	   al,20h
	out	   20h,al
    mov     al,ah
    and     eax,00ffh
	push	eax
	call	_do_kb_interrupt
	pop	eax

	pop	ds
	pop	edx
	pop	eax
	iret
;---------------------------------------
	global	__write_char
__write_char:
    push   eax
	push   ebx
	push   ecx
	push   es

	mov	ax,VIDEOSEL
    mov	es,ax
	mov	ebx,[__scr_loc]
	shl	ebx,01h
	mov	[es:ebx],dx
	shr	ebx,01h
	inc	ebx
	cmp	ebx,2000
	jb	.ff1
.ff0:
	mov ebx,0
.ff1:
    mov	[__scr_loc],ebx
.to_out:
	pop	   es
	pop    ecx
	pop    ebx
	pop    eax
	ret
;---------------------------------------
    global  _putchark
_putchark:
	push   ds
	push   eax
	push   edx
    push   ebp
	mov	   ebp,esp

    mov    ax,DATASEL
	mov    ds,ax
    mov	edx, [ebp+20]
	and	edx, 00ffh
	or	edx, 0c00h
	call   __write_char

    pop    ebp
	pop    edx
	pop    eax
	pop    ds
	ret
;---------------------------------------
	global	_putchar       ;for user mode show a char
_putchar:
	push	ebp
	mov	ebp,esp
	mov	edx, [ebp+8]
	and	edx, 00ffh
	or	edx, 0700h
	mov	eax, 0002h
	int	80h
	pop	ebp
	ret
;--------------------------------------

;--------------------------------------
	extern	__clrscr
	extern	__scr_up
;system call tables
__call:
	dd	00000000h, __clrscr, __write_char, __scr_up
;--------------------------------------
;system constant
	CODESEL    equ 0008h
	DATASEL    equ 0010h
	VIDEOSEL   equ 0018h

	PG_DIR     equ 0000h
	PG_DIR_LEN equ 1000h

	PGS        equ 0008h
	PG_LEN     equ 1000h

	PG0        equ 1000h
	PG1        equ 2000h
	PG2        equ 3000h
	PG3        equ 4000h
	PG4        equ 5000h
	PG5        equ 6000h
	PG6        equ 7000h
	PG7        equ 8000h
;-----------------------------------------
align	4
;variables areas
	global	__current
	global	__scr_loc
	global	__jiffies
__jiffies:	dd	00h
__current:	dd	0000h
__scr_loc:	dd	0000h
	global	__gdt
	global	__idt
	global	__stack_ptr
	global	__tss0
	global	__ldt0
__gdt:		dd	_gdt
__idt:		dd	_idt
__stack_ptr:	dd	_stack0_krn_ptr
__tss0:		dd	_tss0
__ldt0:		dd	_ldt0
;-----------------------------------------
align	4
_gdtr:  dw	256*8-1
        dd	_gdt
_idtr:  dw	256*8-1
        dd	_idt
;-----------------------------------------
;message
msg:    db	"------MINIOS is Starting.------", 00h
;------------------------------------------
;GDT tables
align	4
_gdt:	dd	00000000h, 00000000h        ;dummy
		dd	00000fffh, 00c09a00h        ;08h, system code segment
		dd	00000fffh, 00c09200h        ;10h, system data segment
		dd	80000008h, 00c0920bh        ;18h, screen buffer
times	252	dd	00000000h, 00000000h
;IDT tables
_idt:
times	256	dd	00000000h, 00000000h
;----------------------------------------------
;TSS0 for task 0,when it is used,the cpu is running
;user mode,we must have a TSS for save cpu status
_tss0:	dd	0000h                  ;back link
		dd	_stack0_krn_ptr, 0010h ;esp0,  ss0
		dd	0000h, 0000h           ;esp1,  ss1
		dd	0000h, 0000h           ;esp2,  ss2
		dd	0000h                  ;cr3
		dd	0000h                  ;eip
		dd	0200h                  ;eflags
		dd	0000h, 0000h, 0000h, 0000h
                                   ;eax,  ecx,  edx,  ebx
		dd	_stack0_ptr            ;esp
		dd	0000h, 0000h, 0000h    ;ebp, esi, edi
		dd	0017h, 000fh, 0017h, 0017h, 0017h, 0017h
						           ;es,  cs,  ss,  ds,  fs,  gs
		dd	0028h			       ;ldt
		dd	8000000h		       ;trace bitmap
;LDT0 for task 0,Every task must have private ldt.
_ldt0:	dd	00000000h, 00000000h   ;dummy
		dd	00000fffh, 00c0fa00h   ;task 0 code segment
		dd	00000fffh, 00c0f200h   ;task 0 data segment
		dd	00000000h, 00000000h
;this block used for system stack
align   4
times	128-($-_tss0)/4	dd	00000000h ;128*4 = 512 bytes for kernel mode stack.
_stack0_krn_ptr:
times   128             dd  00000000h ;512bytes.This block be used for user mode stack.
_stack0_ptr;
;--------------------------------------------------
SYS_END:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -