📄 system.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 + -