|
作者: 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 |
|