📄 kernel.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; MenuetOS Copyright 2000-2007 Ville Turjanmaa
;;
;; See file COPYING for details with these additional details:
;; - All code written in 32 bit x86 assembly language
;; - No external code (eg. bios) at process execution time
;;
;; Ville Turjanmaa, vmt@menuetos.net
;; - main os coding/design
;; Jan-Michael Brummer, BUZZ2@gmx.de
;; - bugfixes in mouse & display drivers
;; - code for cd-player
;; Felix Kaiser, info@felix-kaiser.de
;; - AMD K6-II compatible IRQ's
;; - APM management
;; Paolo Minazzi, paolo.minazzi@inwind.it
;; - Sound Blaster
;; - Fat32 write
;; quickcode@mail.ru
;; - 320x200 palette & convert
;; - Vesa 1.2 bankswitch for S3 cards
;; Alexey, kgaz@crosswinds.net
;; - Voodoo compatible graphics
;; Juan M. Caravaca, bitrider@wanadoo.es
;; - Graphics optimizations
;; kristol@nic.fi
;; - Bootfix for some Pentium models
;; Mike Hibbett, mikeh@oceanfree.net
;; - SLIP driver and TCPIP stack (skeleton)
;; Lasse Kuusijarvi, kuusijar@lut.fi
;; - jumptable and modifications for syscalls
;; Jarek Pelczar, jarekp3@wp.pl
;; - AMD compatible MTRR's
;;
;; Compile with FASM 1.50+
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
max_processes equ 255
window_data equ 0x0000
tss_data equ 0x9A0000
tss_step equ (128+8192) ; tss & i/o - 65536 ports, * 256=2129920
draw_data equ 0xC00000
sysint_stack_data equ 0xC03000
twdw equ (0x3000-window_data)
fat_base equ 0x100000 ; ramdisk base
fat_table equ 0x280000 ; 0xD80000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Included files:
;;
;; Kernel16.inc
;; - Booteng.inc English text for bootup
;; - Bootcode.inc Hardware setup
;; - Pci16.inc PCI functions
;;
;; Kernel32.inc
;; - Sys32.inc Process management
;; - Shutdown.inc Shutdown and restart
;; - Fat32.inc Read / write hd
;; - Vesa12.inc Vesa 1.2 driver
;; - Vesa20.inc Vesa 2.0 driver
;; - Vga.inc VGA driver
;; - Stack.inc Network interface
;; - Mouse.inc Mouse pointer
;; - Scincode.inc Window skinning
;; - Pci32.inc PCI functions
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 16 BIT ENTRY FROM BOOTSECTOR ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
use16
org 0x0 ; For 16 bit code
kernel_start:
jmp start_of_code
version db 'Menuet32 0.84 (c) Ville Turjanmaa',13,10,13,10,0
dd endofcode-0x10000
db 'Boot02'
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
;
; Important!!
; Must be set to 2, to avoid two screenmode
; changes within a very short period of time.
display_atboot db 0 ; display text, yes/no (0 or 2)
preboot_graph db 0 ; graphics mode
preboot_mouse db 0 ; mouse port
preboot_mtrr db 0 ; mtrr graphics acceleration
preboot_lfb db 0 ; linear frame buffer
preboot_blogesc db 0 ; start immediately after bootlog
preboot_device db 0 ; load ramdisk from floppy/hd/kernelrestart
preboot_memory db 0 ; amount of memory
preboot_gprobe db 0 ; probe with vesa 2.0+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 16 BIT INCLUDED FILES ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "KERNEL16.INC"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SWITCH TO 32 BIT PROTECTED MODE ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
os_data equ os_data_l-gdts ; GDTs
os_code equ os_code_l-gdts
int_code equ int_code_l-gdts
int_data equ int_data_l-gdts
tss0sys equ tss0sys_l-gdts
graph_data equ 3+graph_data_l-gdts
tss0 equ tss0_l-gdts
tss0i equ tss0i_l-gdts
tss0t equ tss0t_l-gdts
app_code equ 3+app_code_l-gdts
app_data equ 3+app_data_l-gdts
ring3_data equ 3+ring3_data_l-gdts
ring3_code equ 3+ring3_code_l-gdts
ring2_data equ 2+ring2_data_l-gdts
ring2_code equ 2+ring2_code_l-gdts
ring1_data equ 1+ring1_data_l-gdts
ring1_code equ 1+ring1_code_l-gdts
; CR0 Flags - Protected mode and Paging
mov ecx,0x00000001
and ebx,65535
cmp ebx,00100000000000000b ; lfb -> paging
jb no_paging
mov ax,0x0000
mov es,ax
mov al,[es:0x901E]
cmp al,1
je no_paging
or ecx, 0x80000000
no_paging:
; Enabling 32 bit protected mode
;; sidt [cs:old_ints_h-0x10000]
cli ; disable all irqs
cld
mov al,255 ; mask all irqs
out 0xa1,al
out 0x21,al
l.5: in al, 0x64 ; Enable A20
test al, 2
jnz l.5
mov al, 0xD1
out 0x64, al
l.6: in al, 0x64
test al, 2
jnz l.6
mov al, 0xDF
out 0x60, al
lgdt [cs:gdts-0x10000] ; Load GDT
mov eax, cr0 ; Turn on paging // protected mode
or eax, ecx
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
mov cr0, eax
jmp shortjmp
shortjmp:
mov ax,os_data ; Selector for os
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x2FFFF ; Set stack
jmp pword os_code:B32 ; jmp to enable 32 bit mode
use32
kernel_32bit:
org ( 0x10000 + ( kernel_32bit - kernel_start ) )
macro align value { rb (value-1) - ($ + value-1) mod value }
boot_fonts db 'Fonts loaded',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
boot_devices db 'Detecting devices',0
boot_timer db 'Setting timer',0
boot_irqs db 'Reprogramming IRQs',0
boot_setmouse db 'Setting mouse',0
boot_windefs db 'Setting window defaults',0
boot_bgr db 'Calculating background',0
boot_resirqports db 'Reserving IRQs & ports',0
boot_setrports db 'Setting addresses for IRQs',0
boot_setostask db 'Setting OS task',0
boot_allirqs db 'Unmasking all IRQs',0
boot_tsc db 'Reading TSC',0
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_mtrr db 'Setting MTRR',0
boot_tasking db 'All set - press ESC to start',0
boot_y dd 10
boot_log:
ret
pusha
mov edx,esi
.bll3: inc edx
cmp [edx],byte 0
jne .bll3
sub edx,esi
mov eax,10*65536
mov ax,word [boot_y]
add [boot_y],dword 10
mov ebx,0xffffff
mov ecx,esi
mov edi,1
call dtext
mov [novesachecksum],1000
call checkEgaCga
cmp [preboot_blogesc],byte 1
je .bll2
cmp esi,boot_tasking
jne .bll2
.bll1: in al,0x64
in al,0x60
cmp al,129
jne .bll1
.bll2: popa
ret
cpuid_0 dd 0,0,0,0
cpuid_1 dd 0,0,0,0
cpuid_2 dd 0,0,0,0
cpuid_3 dd 0,0,0,0
firstapp db 'L','A','U','N','C','H','E','R',' ',' ',' '
char db 'C','H','A','R',' ',' ',' ',' ','M','T',' '
char2 db 'C','H','A','R','2',' ',' ',' ','M','T',' '
hdsysimage db 'M','S','E','T','U','P',' ',' ','E','X','E'
bootpath db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 32 BIT ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
B32:
; CLEAR 0x280000-0xF00000
xor eax,eax
mov edi,0x280000
mov ecx,(0x100000*0xF-0x280000) / 4
cld
rep stosd
; SAVE & CLEAR 0-0xffff
mov esi,0x0000
mov edi,0x2F0000
mov ecx,0x10000 / 4
cld
rep movsd
xor eax,eax
mov edi,0
mov ecx,0x10000 / 4
cld
rep stosd
; SAVE REAL MODE VARIABLES
movzx eax,byte [0x2f0000+0x9010] ; mouse port
mov [0xF604],al
mov al,[0x2f0000+0x9000] ; bpp
mov [0xFBF1],al
movzx eax,word [0x2f0000+0x900A] ; X max
sub eax,1
mov [0xfe00],eax
movzx eax,word [0x2f0000+0x900C] ; Y max
sub eax,1
mov [0xfe04],eax
movzx eax,word [0x2f0000+0x9008] ; screen mode
mov [0xFE0C],eax
mov eax,[0x2f0000+0x9014] ; Vesa 1.2 bnk sw add
mov [0xE030],eax
mov [0xfe08],word 640*4 ; Bytes PerScanLine
cmp [0xFE0C],word 0x13 ; 320x200
je srmvl1
cmp [0xFE0C],word 0x12 ; VGA 640x480
je srmvl1
mov ax,[0x2f0000+0x9001] ; for other modes
mov [0xfe08],ax
srmvl1:
; GRAPHICS ADDRESSES
mov eax,0x100000*8 ; LFB address
cmp [0xfe0c],word 0x13
je no_d_lfb
cmp [0xfe0c],word 0x12
je no_d_lfb
cmp [0x2f0000+0x901e],byte 1
jne no_d_lfb
mov eax,[0x2f0000+0x9018]
no_d_lfb:
mov [0xfe80],eax
cmp [0xfe0c],word 0100000000000000b
jge setvesa20
cmp [0xfe0c],word 0x13
je v20ga32
mov [0xe020],dword Vesa12_putpixel24 ; Vesa 1.2
mov [0xe024],dword Vesa12_getpixel24
cmp [0xfbf1],byte 24
jz ga24
mov [0xe020],dword Vesa12_putpixel32
mov [0xe024],dword Vesa12_getpixel32
ga24:
jmp v20ga24
setvesa20:
mov [0xe020],dword Vesa20_putpixel24 ; Vesa 2.0
mov [0xe024],dword Vesa20_getpixel24
cmp [0xfbf1],byte 24
jz v20ga24
v20ga32:
mov [0xe020],dword Vesa20_putpixel32
mov [0xe024],dword Vesa20_getpixel32
v20ga24:
cmp [0xfe0c],word 0x12 ; 16 C VGA 640x480
jne no_mode_0x12
mov [0xe020],dword VGA_putpixel
mov [0xe024],dword Vesa20_getpixel32
no_mode_0x12:
mov eax,[0xfe80] ; set for gs
mov [graph_data_l+2],ax
shr eax,16
mov [graph_data_l+4],al
mov [graph_data_l+7],ah
; MEMORY MODEL
mov [0xfe84],dword 0x100000*18 ; apps mem base address
movzx ecx,byte [0x2f0000+0x9030]
dec ecx
mov eax,32*0x100000
shl eax,cl
mov [0xfe8c],eax ; memory for use
cmp eax,16*0x100000
jne no16mb
mov [0xfe84],dword 0x100000*10
no16mb:
; READ RAMDISK IMAGE FROM HD
cmp [boot_dev],byte 1
jne no_sys_on_hd
mov [fat32part],1 ; Partition
mov [hdbase],0x1f0 ; Controller base
mov [hdpos],1 ;
mov [hdid],0x0 ;
mov [0xfe10],dword 0 ; entries in hd cache
call set_FAT32_variables
mov esi,40
mov ecx,fat_base ; 0x100000
hdbootl1:
mov eax,hdsysimage
mov edi,12
mov ebx,18*2*5
mov edx,bootpath
pusha
call file_read
cmp eax,0 ; image not found
jne $
popa
add ecx,512*18*2*5
add esi,18*2*5
cmp esi,1474560/512+41-1
jb hdbootl1
no_sys_on_hd:
; CALCULATE FAT CHAIN FOR RAMDISK
call calculatefatchain
; LOAD FONTS I and II
mov [0x3000],dword 1
mov [0x3004],dword 1
mov [0x3010],dword 0x3020
mov eax,char
mov esi,12
mov ebx,0
mov ecx,26000
mov edx,0x37000
call fileread
mov eax,char2
mov esi,12
mov ebx,0
mov ecx,26000
mov edx,0x30000
call fileread
mov esi,boot_fonts
call boot_log
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
mov esi,boot_irqs
call boot_log
call rerouteirqs
mov esi,boot_tss
call boot_log
; BUILD SCHEDULER
call build_scheduler ; sys32.inc
; LOAD IDT
lidt [cs:idts]
; READ CPUID RESULT
mov esi,boot_cpuid
call boot_log
pushfd ; get current flags
pop eax
mov ecx,eax
xor eax,0x00200000 ; attempt to toggle ID bit
push eax
popfd
pushfd ; get new EFLAGS
pop eax
push ecx ; restore original flags
popfd
and eax,0x00200000 ; if we couldn't toggle ID,
and ecx,0x00200000 ; then this is i486
cmp eax,ecx
jz nopentium
; It's Pentium or later. Use CPUID
mov edi,cpuid_0
mov esi,0
cpuid_new_read:
mov eax,esi
cpuid
call cpuid_save
add edi,4*4
cmp esi,3
jge cpuid_done
cmp esi,[cpuid_0]
jge cpuid_done
inc esi
jmp cpuid_new_read
cpuid_save:
mov [edi+00],eax
mov [edi+04],ebx
mov [edi+8],ecx
mov [edi+12],edx
ret
cpuid_done:
nopentium:
; CR4 flags - enable fxsave / fxrstore
;
; finit
; mov eax,1
; cpuid
; test edx,1000000h
; jz fail_fpu
; mov eax,cr4
; or eax,200h ; Enable fxsave/fxstor
; mov cr4,eax
; fail_fpu:
; DETECT DEVICES
mov esi,boot_devices
call boot_log
call detect_devices
; TIMER SET TO 1/100 S
mov esi,boot_timer
call boot_log
mov al,0x34 ; set to 100Hz
out 0x43,al
mov al,0x9b ; lsb 1193180 / 1193
out 0x40,al
mov al,0x2e ; msb
out 0x40,al
; SET MOUSE
mov esi,boot_setmouse
call boot_log
call setmouse
; SET PRELIMINARY WINDOW STACK AND POSITIONS
mov esi,boot_windefs
call boot_log
call setwindowdefaults
; SET BACKGROUND DEFAULTS
mov esi,boot_bgr
call boot_log
call calculatebackground
; RESERVE SYSTEM IRQ'S JA PORT'S
mov esi,boot_resirqports
call boot_log
call reserve_irqs_ports
; SET PORTS FOR IRQ HANDLERS
mov esi,boot_setrports
call boot_log
call setirqreadports
; SET UP OS TASK
mov esi,boot_setostask
call boot_log
; name for OS/IDLE process
mov [0x80000+256+0],dword 'OS/I'
mov [0x80000+256+4],dword 'DLE '
; task list
mov [0x3004],dword 2 ; number of processes
mov [0x3000],dword 0 ; process count - start with os task
mov [0x3020+0xE],byte 1 ; on screen number
mov [0x3020+0x4],dword 1 ; process id number
; set default flags & stacks
mov [l.eflags],dword 0x11202 ; sti and resume
mov [l.ss0], os_data
mov [l.ss1], ring1_data
mov [l.ss2], ring2_data
mov [l.esp0], 0x52000
mov [l.esp1], 0x53000
mov [l.esp2], 0x54000
; osloop - TSS
mov eax,cr3
mov [l.cr3],eax
mov [l.eip],osloop
mov [l.esp],0x2ffff
mov [l.cs],os_code
mov [l.ss],os_data
mov [l.ds],os_data
mov [l.es],os_data
mov [l.fs],os_data
mov [l.gs],os_data
; move tss to tss_data+tss_step
mov esi,tss_sceleton
mov edi,tss_data+tss_step
mov ecx,120/4
cld
rep movsd
mov ax,tss0
ltr ax
; READ TSC / SECOND
mov esi,boot_tsc
call boot_log
call _rdtsc
mov ecx,eax
mov esi,250 ; wait 1/4 a second
call delay_ms
call _rdtsc
sub eax,ecx
shl eax,2
mov [0xf600],eax ; save tsc / sec
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -