QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 604|回复: 0

MenuetOS 启动代码解析 ZT

[复制链接]
发表于 2004-4-11 16:48:16 | 显示全部楼层 |阅读模式
作者: Star




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:进入保护模式
;1.检查是否为保护分页模式
;2.关闭所有中断
;3.打开20地址线
;4.加载全局描述表,启动保护模式和分页机制
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;1.检查是否为保护分页模式
; 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]
cmp al,1
je no_paging
or ecx, 0x80000000
no_paging:

;2.关闭所有中断
; Enabling 32 bit protected mode

sidt [csld_ints_h-0x10000] ;装载和保存IDTR寄存器

cli ; disable all irqs(关所有中断)
cld
mov al,0xFF ; mask all irqs(屏蔽所有的中断)
out 0xa1,al ;
out 0x21,al ;21H:中断屏蔽寄存器端口地址

;3.打开20地址线
l.5: in al, 0x64 ; Enable A20
test al, 2
jnz l.5
mov al, 0xD1
out 0x64, al

;4.加载全局描述表,启动保护模式和分页机制
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

;初始化段寄存器:ds=es=fs=gs=ss=os_data
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

;执行32代码
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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:显示字符
;esi:要显示的信息
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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

;按ESC键才跳出这里mtx???
.bll1: in al,0x60
cmp al,129
;jne .bll1
jne .bll2

.bll2: popa

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cpuser_id_0 dd 0,0,0,0
cpuser_id_1 dd 0,0,0,0
cpuser_id_2 dd 0,0,0,0
cpuser_id_3 dd 0,0,0,0

;firstapp db 'L','A','U','N','C','H','E','R',' ',' ',' '
;firstapp db 'C','P','U',' ',' ',' ',' ',' ',' ',' ',' '
firstapp db 'S','C','N',' ',' ',' ',' ',' ',' ',' ',' '
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'

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 32 BIT ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align 4

B32:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 1.清280000-0x800000内存为0
; CLEAR 0x280000-0x800000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
xor eax,eax
mov edi,0x280000
mov ecx,(0x100000*8-0x280000) / 4
cld
rep stosd


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 2.把内存0H-10000H复制到2F0000H-300000H并清零0H-10000H
; 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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 3.保存实模式参数到0x2f0000开始的内存地址
; [0xF604] = 1(PS/2或USB)、2(Com1)、3(Com2)
; [0xFBF1] = bpp: [es]=每点的位数
; [0xfe00] = X max: [es]=水平相素数
; [0xfe04] = [es]=垂直相素数
; [0xFE0C] = [es]=模式号
; [0xE030] = Vesa 1.2 bnk sw add:[es] = bnk
; [0xfe08] = Bytes PerScanLine:
; [0xfe08] = for other modes:[es]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
movzx eax,byte [0x2f0000+0x9010] ; mouse port: [es] = 1(PS/2或USB)、2(Com1)、3(Com2)
mov [0xF604],al
mov al,[0x2f0000+0x9000] ; bpp: [es]=每点的位数
mov [0xFBF1],al
movzx eax,word [0x2f0000+0x900A] ; X max: [es]=水平相素数
sub eax,1
mov [0xfe00],eax
movzx eax,word [0x2f0000+0x900C] ; Y max: [es]=垂直相素数
sub eax,1
mov [0xfe04],eax
movzx eax,word [0x2f0000+0x9008] ; screen mode: [es]=模式号
mov [0xFE0C],eax
mov eax,[0x2f0000+0x9014] ; Vesa 1.2 bnk sw add:[es] = bnk
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:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 4.VGA或VESA地址
; GRAPHICS ADDRESSES
; 1) 得到显存地址eax=VGA=800000H
; 2) 保存显存地址[0xfe80] = eax,根据[0xfe0c]模式号设置VGA或VESA中断处理程序
; 3) 设置显存选择数据段地址([0xfe80] = 显存地址)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;1) 得到显存地址eax=VGA=800000H
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]

;2) 保存显存地址[0xfe80] = eax,根据[0xfe0c]模式号设置VGA或VESA中断处理程序
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:

;3) 设置显存选择数据段地址([0xfe80] = 显存地址)
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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;5.设置内存
;两种方式
; 常规内存大小[0xfe84] = 1M 总内存:[0xfe8c] = 16M
; 常规内存大小[0xfe84] = 16M 总内存:[0xfe8c] = 16、32、64、128、256
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MEMORY MODEL

mov [0xfe84],dword 0x100000*16 ; apps mem base address
movzx ecx,byte [0x2f0000+0x9030] ;[es] = 1(16 Mb)、2(32 Mb)、3(64Mb)、4(128 Mb)、5(256 Mb)
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:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能: 从硬盘读磁盘影射文件msetup.exe
;描述: 当选择从硬盘加载磁盘影象时从C盘加载msetup.exe
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; READ RAMDISK IMAGE FROM HD

cmp [boot_dev],1 ;[es] = 1(floppy)、2(hd/msetup.exe (hdboot.txt))
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
mov ecx,41
hdbootl1:
mov eax,hdsysimage ;文件名
mov ebx,12 ;文件名长度
mov edx,1 ;读的块数
mov esi,0x90000 ;保存文件数据的内存位置
pusha
call read_hd_file
cmp eax,0 ; image not found
jne $
popa
mov eax,ecx
sub eax,41
shr eax,1
mov [eax+0x800000],byte 0xff
push ecx
mov edi,ecx
sub edi,41
shl edi,9
add edi,0x100000
mov esi,0x90000+1024
mov ecx,512/4
cld
rep movsd ; move 0x90000+1024 -> 0x100000+
pop ecx
add ecx,1
cmp ecx,1474560/512+41
jb hdbootl1

no_sys_on_hd:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:把文件分配表从[0x100000+512]移动到[0x280000] -> [0x280000+4100*4]
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CALCULATE FAT CHAIN FOR RAMDISK

call calculatefatchain

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:
; 1)加载字体1到内存的[0x4000]
; 2)加载字体2到内存的[0x30000]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; LOAD FONTS I and II

mov [0x3000],dword 1
mov [0x3004],dword 1
mov [0x3010],dword 0x3020

;读字体文件char.mt
mov eax,char ;文件名 char.mt
mov esi,12 ;文件名长度
mov ebx,0 ;ebx = 第一个要读块
mov ecx,26000 ;ecx = 读块的数量
mov edx,0x4000 ;保存读得数据的内存地址
call fileread

;读字体文件char2.mt
mov eax,char2
mov esi,12
mov ebx,0
mov ecx,26000
mov edx,0x30000
call fileread

mov esi,boot_fonts
call boot_log

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置中断优先级管理控制器
;调用:中断中断优先级管理控制器(8259A)设置函数:rerouteirqs
; 1) 把主片的IR0-IR7 影射到中断号 0x20-0x27
; 2) 把从片的IR8-IR15 影射到中断号 0x28-0x2f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f

mov esi,boot_irqs
call boot_log

;中断控制器(8259A)设置函数
call rerouteirqs

mov esi,boot_tss
call boot_log

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:构造所有调度
; 1.构造任务状态段全局描述符表
; 2.构造任务门全局描述符表
; 3.构造中断全局描述符表
; 4.构造陷入调用全局描述符表
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BUILD SCHEDULER

call build_scheduler ; sys32.inc

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:加载中断描述符
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LOAD IDT

lidt [cs]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:读CPUID号
;描述:把CUPID号保存到 cpuser_id_0、cpuser_id_1、cpuser_id_2、cpuser_id_3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; READ CPUID RESULT
;显示信息
mov esi,boot_cpuid
call boot_log

;得到32位的flags
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

;判断是否位pentium
cmp eax,ecx
jz nopentium

; It's Pentium or later. Use CPUID
mov edi,cpuser_id_0
mov esi,0

;读cpu id
cpuser_id_new_read:
mov eax,esi
cpuid

;保存cpu id到cpuser_id_0
call cpuser_id_save

;esi=3时转到cpuser_id_done
add edi,4*4
cmp esi,3
jge cpuser_id_done

;???
cmp esi,[cpuser_id_0]
jge cpuser_id_done
inc esi
jmp cpuser_id_new_read

;保存cpu id到cpuser_id_0
cpuser_id_save:
mov [edi+00],eax
mov [edi+04],ebx
mov [edi+8],ecx
mov [edi+12],edx
ret

cpuser_id_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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:定时器控制器(8253)设置
;
;设置核心系统的时钟周期为10ms,即100HZ,它是以后按照轮转法进行CPU调度时所依照的基准时钟周期。
;每10ms产生的时钟中断信号直接输入到第一块8259A的INT 0(即irq0)。初始化中断矢量表中从0x20起的17个中断矢量.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置鼠标读端口
; 1)ps/2或usb鼠标端口 0x60
; 2)com1鼠标端口 0x3f8
; 3)com2鼠标端口 0x2f8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SET MOUSE

mov esi,boot_setmouse
call boot_log
call setmouse

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置默认窗口
;[0xc000]-[0xc400] = window stack C000 no of windows - all in words
;[0xc400]-[0xc800] = window position in stack
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SET PRELIMINARY WINDOW STACK AND POSITIONS

mov esi,boot_windefs
call boot_log
call setwindowdefaults


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置默认背景
; 1)设置背景的x、y
; 2)设置背景的颜色
; 3)设置操作系统用的象素
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SET BACKGROUND DEFAULTS

mov esi,boot_bgr
call boot_log
call calculatebackground

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:预定端口的irq
;调用函数: reserve_irqs_ports
;1)设置irq_owner中的irq占用标识别: 1=占用 0=空闲
;2)保存鼠标参数内存地址为[0x2d0000]S/2或USB鼠标=0x00-0xff com1鼠标=0x3f0-0x3ff com2鼠标=0x2f0-0x2ff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; RESERVE SYSTEM IRQ'S JA PORT'S

mov esi,boot_resirqports
call boot_log
call reserve_irqs_ports


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置irq上的i/o端口(SET PORTS FOR IRQ HANDLERS)
; 1)irq12read = ps/2或usb鼠标端口 :0x60
; 2)irq4read = com1鼠标端口 :0x3f8
; 3)irq3read = com2鼠标端口 :0x2f8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SET PORTS FOR IRQ HANDLERS

mov esi,boot_setrports
call boot_log
call setirqreadports


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置内核任务
; 1) 进程数地址 = 0x3004 、进程数地址 = 0x3000 、屏幕号地址 = 0x3020+0xE 、进程ID地址 = 0x3020+0x4
; 2) 核心任务状态段地址:0x40000+128*1 - 0x40000+128*2
; 3) 核心进程地址:[0x80000]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SET UP OS TASK

;显示信息
mov esi,boot_setostask
call boot_log

;1)设置进程
; name for OS/IDLE process
mov [0x80000+256+0],dword 'OS/I'
mov [0x80000+256+4],dword 'DLE '

;2)设置任务链表
; 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

;3)设置内核任务
; set default flags & stacks
mov [l.eflags],dword 0x11202 ; sti and resume
mov [l.ss0], os_code ;0级堆栈段寄存器
mov [l.ss1], ring1_code
mov [l.ss2], ring2_code
mov [l.esp0], 0x52000 ;0级堆栈指针
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 ;es段寄存器
mov [l.fs],os_data ;fs段寄存器
mov [l.gs],os_data ;gs段寄存器

;4)移动内核任务状态段到0x40000+128*2
; move tss to 0x40000+128*2
mov esi,tss_sceleton
mov edi,0x40000+128*1
mov ecx,120/4
cld
rep movsd

;5)切换任务
mov ax,tss0
ltr ax ;装载TR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置
;0xf600 = tsc / sec
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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

;0xf600 = tsc / sec
call _rdtsc
sub eax,ecx
shl eax,2
mov [0xf600],eax ; save tsc / sec

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;set_variables:设置参数
; 鼠标缓冲区 = 0xfcff
; 键盘缓冲区 = 0xf400
; 按钮缓冲区 = 0xf500
; 鼠标x/y = 0xfb0a
; Minazzi = [SB16_Statu]
; 背景标题 = 0x400000-12
; 按钮链表地址 = [0xfe88]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SET VARIABLES

call set_variables

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置vga调色版
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能: 加载默认的皮肤
;描述 1)皮肤文件: raw文件
; 2)[778000H] = 皮肤文件
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LOAD DEFAULT SKIN

call load_default_skin

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置mtrr
;???
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MTRR'S

call enable_mtrr

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:加载第一个应用程序,菜单程序LAUNCHER
;???
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LOAD FIRST APPLICATION

mov [0x3000],dword 1 ;当前进程任务号
mov [0x3004],dword 1 ;总的进程任务数

mov eax,firstapp

call start_application_fl

mov [0x3004],dword 2 ;总的进程任务数
mov [0x3000],dword 0 ;当前进程任务号

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:设置多任务标志
; [0xe000] = 1 :支持多任务
; [0xe000] = 0 :不支持多任务
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; START MULTITASKING

mov esi,boot_tasking
call boot_log

mov [0xe000],byte 1 ; multitasking enabled


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:启动中断
; 1.打开所有中断
; 2.启动所有中断
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UNMASK ALL IRQ'S

mov esi,boot_allirqs
call boot_log

;打开所有中断
mov al,0
out 0xA1,al
out 0x21,al

;启动所有中断
sti
jmp $ ; wait here for timer to take control(等待时间中断控制)

; Fly
您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 13:42 , Processed in 0.145516 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表