📄 kernel.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; MenuetOS Copyright 2000-2002 Ville Mikael 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
;;
;; PROGRAMMING:
;;
;; Ville Mikael Turjanmaa, villemt@itu.jyu.fi
;; - 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.30+
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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 0x10000
jmp start_of_code
version db 'MENUET 0.74 Beta',13,10,13,10,0
dd endofcode-0x10000
db 'Boot00'
include "PREBOOT.INC"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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_code equ 2+ring2_code_l-gdts
ring1_code equ 1+ring1_code_l-gdts
max_processes equ 100
; 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 byte $+2
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
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:
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
cmp [0x2f0000+0x901d],byte 2
jne .bll2
cmp esi,boot_tasking
jne .bll2
.bll1: 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 'LAUNCHER '
char db 'CHAR MT '
char2 db 'CHAR2 MT '
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 32 BIT ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
B32:
; CLEAR 0x280000-0x800000
xor eax,eax
mov edi,0x280000
mov ecx,(0x100000*8-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*16 ; apps mem base address
movzx ecx,byte [0x2f0000+0x9030]
dec ecx
mov eax,16*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],1
jne no_sys_on_hd
mov [fat32part],1 ; Partition
mov [hdbase],0x1f0 ; Controller base
mov [hdpos],1 ;
mov [0xfe10],dword 0 ; entries in hd cache
mov [0x800000+1474560/1024],dword 0xffffffff
xor ecx,ecx
inc ecx
hdbootl1:
mov eax,hdsysimage
mov ebx,12
xor edx,edx
inc edx
mov esi,0x90000
pusha
call read_hd_file
test eax,eax ; image not found
jne $
popa
mov eax,ecx
dec eax
shr eax,1
mov [eax+0x800000],byte 0xff
push ecx
mov edi,ecx
dec edi
shl edi,9
add edi,0x100000
mov esi,0x90000+1024
mov ecx,512/4
cld
rep movsd ; move 0x90000+1024 -> 0x100000+
pop ecx
inc ecx
cmp ecx,1474560/512+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,0x4000
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_code
mov [l.ss1], ring1_code
mov [l.ss2], ring2_code
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 0x40000+128*2
mov esi,tss_sceleton
mov edi,0x40000+128*1
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
; SET VARIABLES
call set_variables
; PALETTE FOR 320x200 and 640x480 16 col
cmp [0xfe0c],word 0x12
jne no_pal_vga
mov esi,boot_pal_vga
call boot_log
call paletteVGA
no_pal_vga:
cmp [0xfe0c],word 0x13
jne no_pal_ega
mov esi,boot_pal_ega
call boot_log
call palette320x200
no_pal_ega:
; LOAD DEFAULT SKIN
call load_default_skin
; MTRR'S
call enable_mtrr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -