; =============================================================================
;
; Litos - Initialization, real mode
;
; =============================================================================
CODE_SECTION 16
%ifdef MINI
MINRAM EQU 512*1024 ; minimal RAM required (512 KB)
%else
MINRAM EQU 2*1024*1024 ; minimal RAM required (2 MB)
%endif
; ------------- Macro - short delay (roughly 1.5 microsecond)
; Alternatives of dummy ports:
; 80h: AT diagnostic port used by Linux for short delay
; 0ebh: dummy port used by some BIOSes for short delays
; 0edh: dummy port used by some BIOSes for short delays
%define SHORT_DELAY out 80h,al
BootSystemStack EQU Start ; boot system stack
; -----------------------------------------------------------------------------
; Initialization (jump here from LITOS.ASM)
; -----------------------------------------------------------------------------
; INPUT: DL = boot disk
; -----------------------------------------------------------------------------
; ------------- Init data segment and init stack (below start of kernel)
Start16: mov ax,cs ; AX <- CS
mov ds,ax ; DS <- CS
mov ss,ax ; SS <- CS (it disables interrupts)
mov sp,BootSystemStack ; SP <- init stack
; ------------- Store boot disk
mov [BootDisk],dl ; store boot disk
; ------------- Debug clear screen
%ifdef DEBUG
mov ah,0fh ; AH <- function code
call Int10 ; get initial videomode
and ax,7fh ; reset bit 7, AH <- function code 0
call Int10 ; clear screen
%endif
; ------------- Display intro message
mov si,BootMessage ; SI <- intro message
call BIOSDispText ; display intro message
; ------------- Check if CPU is at least 386
pushf ; push flags
pushf ; push flags
pop ax ; AX <- flags
mov cx,ax ; CX <- push original flags
xor ax,B14 ; change bit 14 (NT flag)
push ax ; push AX
popf ; flags <- AX
pushf ; push new flags
pop ax ; pop AX <- new flags
popf ; pop original flags
xor ax,cx ; test changed bits
and ax,B14 ; can bit 14 be changed?
jnz InitCPU_OK ; bit 14 can be changed
mov si,CPUMessage ; SI <- error message
InitError: call BIOSDispText ; display error message
InitHalt: hlt ; halt system
jmp short InitHalt ; system halted
; ------------- Get low memory (below 1 MB)
InitCPU_OK: int 12h ; get low memory
and ax,~((PAGE_SIZE-1)>>10) ; mask to page align
mov [LowMemory],ax ; low memory in KB
; ------------- Check low memory
mov si,MemMessage ; SI <- error message
mov edx,KernelEnd ; EDX <- end of kernel
shr edx,10 ; convert to KB
cmp ax,dx ; check memory end
InitError2: jb InitError ; error, insufficient memory
; ------------- Clear uninitialized data
mov edx,BSSStart-SYSTEM_ADDR ; EDX <- start of BSS
shr edx,4 ; EDX <- segment of BSS start
mov es,dx ; ES <- segment of BSS start
xor di,di ; DI <- 0, offset of BSS start
cld ; direction up
xor ax,ax ; AX <- 0
mov bx,(BSSEnd-BSSStart)/10000h+1 ; number of 64 KB parts
jmp short InitClear2
InitClear: mov cx,8000h ; CX <- 64 KB/2
rep stosw ; clear uninitialized data
add dx,1000h ; increase addres by 64 KB
mov es,dx ; ES <- new segment
InitClear2 dec bx ; number of 64 KB parts
jnz InitClear ; next 64 KB part
mov cx,((BSSEnd-BSSStart) & 0ffffh)/2 ; ECX <- data size/4
rep stosw ; clear rest of data
; ------------- Load BIOS equipment list
xor eax,eax ; EAX <- 0
int 11h ; load BIOS equipment list
mov [BIOSEquip],eax ; store BIOS equipment list
; ------------- Init keyboard (set maximal repeat rate)
mov ax,305h ; AX <- function code, set repeat rate
xor bx,bx ; BX <- 0 max. repeat rate
int 16h ; set repeat rate
; ------------- Load BIOS configuration
mov ah,0c0h ; AH <- function code
stc ; preset carry flag
int 15h ; get BIOS configuration
jc InitCfgErr ; error
push ds ; push DS
push ds ; push DS
push es ; push ES
pop ds ; DS <- table segment
pop es ; ES <- data segment
mov si,bx ; SI <- table
cld ; direction up
lodsw ; AX <- load length of table
cmp ax,byte 8 ; maximal length
jb InitCfg8 ; length is OK
mov ax,8 ; limit length
InitCfg8: xchg ax,cx ; CX <- length of table
mov di,BIOSCfg ; DI <- BIOS config table
rep movsb ; store talbe
pop ds ; pop DS
; ------------- Initialize graphics card (INIT\INIT_GRA.ASM)
InitCfgErr: call InitCard ; initialize graphics card
; ------------- Initialize hard drives (INIT\INIT_HD.ASM)
call InitHD ; initialize hard drives
; ------------- Initialize memory (INIT\INIT_MEM.ASM)
call InitMem ; initialize memory
; ------------- Check total memory
mov si,Mem2Message ; SI <- error message
cmp dword [TotalMemory],MINRAM ; minimum 2 MB (512 KB)
InitError3: jb short InitError2 ; error, insufficient memory
; ------------- Check if memory is big enough
; It requires:
; - kernel size
; - (4 bytes + aprox. 60 bytes) per 4 KB page, i.e. max/4k*64=max/64
; - 45 KB for character conversion tables
; - 16 KB for floppy disk DMA buffer
; - 1/2 of minimal memory as free
mov eax,[MemoryMax] ; EAX <- end of physical memory
shr eax,6 ; required memory for page tables
add eax,KernelEnd-SYSTEM_ADDR+46080+16384+MINRAM/2; reserve
cmp [TotalMemory],eax ; check available memory
jb InitError3 ; error, insufficient memory
; ------------- Initialize random generator
xor ax,ax ; AX <- 0
mov es,ax ; ES <- 0
mov ax,[es:46ch] ; AX <- timer LOW
add [RandSeed],ax ; random seed LOW
mov ax,[es:46ch+2] ; AX <- timer HIGH
adc [RandSeed+2],ax ; random seed HIGH
; ------------- Initialize advanced power management (INIT\INIT_APM.ASM)
call InitAPM ; init advanced power management
; ------------- Disable interrupts before entering protected mode
cli ; disable interrupts
mov al,B7+13 ; AL <- bit 7 + register R/O 13
out 70h,al ; disable NMI
; ------------- Enable A20 address line gate (INIT\INIT_A20.ASM)
call InitA20 ; enable A20 address line gate
; ------------- Disable all interrupts
mov al,0ffh ; AL <- interrupt mask
out 0a1h,al ; disable all interrupts
call ShortDelay ; short delay
mov al,~B2 ; AL <- int. mask except #2 controller
out 21h,al ; disable all interrupts
cli ; interrupts must be realy disabled
; ------------- Reset math coprocessor
mov al,0 ; AL <- 0
out 0f0h,al ; clear busy latch
call ShortDelay ; short delay
out 0f1h,al ; coprocessor reset
; ------------- Load boot interrupt descriptor table
lidt [BootIDT] ; load boot interrupt descriptor table
; ------------- Load boot global descriptor table
lgdt [BootGDT] ; load boot global descriptor table
; ------------- Switch on protected mode bit
mov eax,cr0 ; EAX <- CR0 control register
or al,1 ; set protected mode bit ON
mov cr0,eax ; set new CR0 control register
jmp short FlushInsPE; flush instruction queue
; ------------- Jump to protected mode (update CS reg., ->INIT\INIT_32.ASM)
FlushInsPE: jmp dword SYSTEM_CS:Start32-SYSTEM_ADDR
; -----------------------------------------------------------------------------
; Short delay (uses I/O port - less depends on CPU speed than "jump")
; -----------------------------------------------------------------------------
; Alternatives of dummy ports:
; 80h: AT diagnostic port used by Linux for short delay
; 0ebh: dummy port used by some BIOSes for short delays
; 0edh: dummy port used by some BIOSes for short delays
; -----------------------------------------------------------------------------
ShortDelay: SHORT_DELAY ; short delay (uses AT diagnostic port)
ret
; -----------------------------------------------------------------------------
; Data
; -----------------------------------------------------------------------------
DATA_SECTION
; ------------- Messages
BootMessage: db 13,10,'Litos v'
db VER_MAJOR + "0"
db '.'
db (VER_MINOR / 10) + "0",
db (VER_MINOR % 10) + "0"
%ifdef MINI
db ' MINI'
%endif
db ' loading...'
CRLFMessage: db 13,10,0
BootMessage2:
CPUMessage: db 'Error: Intel 386 or higher required!',0
MemMessage: db 'Error: Insufficient low memory to run system!',0
%ifdef MINI
Mem2Message: db 'Error: Minimal 512 KB of RAM required!',0
%else
Mem2Message: db 'Error: Minimal 2 MB of RAM required!',0
%endif
; ------------- Int 11h - BIOS equipment list
align 4, db 0
BIOSEquip: dd 0 ; BIOS equipment list
; B0: floppy installed (B6-B7 valid)
; B1: 80x87 coprocessor installed
; B2: PS/2 mouse installed
; B4-B5: initial video mode
; 0=EGA or VGA
; 1=40x25 color
; 2=80x25 color
; 3=80x25 mono
; B6-B7: number of floppies - 1
; B8: DMA support installed
; B9-B11: number of serial ports
; B12: game port installed
; B13: serial printed installed
; B14-B15: number of parallel ports
; B23: page tables set for Weitek
; B24: Weitek coprocessor present
; ------------- BIOS configuration
align 8, db 0
BIOSCfg:
BIOSCfgModel: db 0fch ; PC model
BIOSCfgSubModel:db 2 ; PC sub model
BIOSCfgRevision:db 0 ; BIOS revision
BIOSCfgFlags1: db 0 ; feature flags 1
; B0: system has dual bus MCA+ISA
; B1: MCA bus instead of ISA
; B2: extended BIOS area allocated
; B3: wait for ext. event supported
; B4: Int 15h/4Fh called upon Int 09h
; B5: Real-Time Clock installed
; B6: 2nd 8259 installed
; B7: DMA channel 3 used by HD BIOS
BIOSCfgFlags2: db 0 ; feature flags 2
; B1: data streaming supported
; B2: non-8042 keyboard controller
; B3: Int 15h/0C8h supported
; B4: Int 15h/0C7h supported
; B5: Int 15h/0C6h supported
; B6: Int 16h/09h supported
; B7: 32-bit DMA supported
BIOSCfgFlags3: db 0 ; feature flags 3
; B0: SCSI supported in IML
; B1: IML system (BIOS from disk)
; B2: information panel installed
; B3: SCSI supported on sys. board
; B4: POST supports ROM-RAM enable
BIOSCfgFlags4: db 0 ; feature flags 4
; B0: POSTEXT directly supported
; B1: 16M memory split supported
; B3-B5: ABIOS presence
; 1=not supported
; 2=supported in ROM
; 3=supported in RAM
; B6: system has EEPROM
BIOSCfgFlags5: db 0 ; feature flags 5
; B0: flash EPROM
; B1: system has enhanced mouse mode
; ------------- Boot interrupt descriptor table
align 4, db 0
dw 0 ; align
BootIDT: dw 0 ; IDT size limit
dd 0 ; IDT base address
; ------------- Boot global descriptor table (used as pattern for SystemGDITab)
align 8, db 0
BootGDTTab:
; --- 0: reserved by CPU
times GLDT_size db 0 ; GDT reserved by CPU
; --- 1: system 4GB code descriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B3+B4+B7 ; access (code, read, present, level 0)
db 0fh + B6+B7 ; limit 16-19, flags: 32-bit, 4 KB
db 0 ; base address (bits 24 to 31)
; --- 2: system 4GB data descriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B4+B7 ; access (data, write, present,level 0)
db 0fh + B6+B7 ; limit 16-19, flags: 32-bit, 4 KB
db 0 ; base address (bits 24 to 31)
; --- 3: user 4GB code descriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B3+B4+B5+B6+B7; access (code, read, present,level 3)
db 0fh + B6+B7 ; limit 16-19, flags: 32-bit, 4 KB
db 0 ; base address (bits 24 to 31)
; --- 4: user 4GB data descriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B4+B5+B6+B7 ; access (data, write, present,level 3)
db 0fh + B6+B7 ; limit 16-19, flags: 32-bit, 4 KB
db 0 ; base address (bits 24 to 31)
; --- 5: PNP 64K 32b code desriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B3+B4+B7 ; access (code, read, present, level 0)
db B6 ; limit 16-19, flags: 32-bit, 1 Byte
db 0 ; base address (bits 24 to 31)
; --- 6: PNP 64K 16b code desriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B3+B4+B7 ; access (code, read, present, level 0)
db 0 ; limit 16-19, flags: 16-bit, 1 Byte
db 0 ; base address (bits 24 to 31)
; --- 7: PNP 64K 16b data desriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B4+B7 ; access (data, write, present,level 0)
db 0 ; limit 16-19, flags: 16-bit, 1 Byte
db 0 ; base address (bits 24 to 31)
; --- 8: APM 64K 32b code desriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B3+B4+B7 ; access (code, read, present, level 0)
db B6 ; limit 16-19, flags: 32-bit, 1 Byte
db 0 ; base address (bits 24 to 31)
; --- 9: APM 64K 16b code desriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B3+B4+B7 ; access (code, read, present, level 0)
db 0 ; limit 16-19, flags: 16-bit, 1 Byte
db 0 ; base address (bits 24 to 31)
; --- 10: APM 64K 32b data desriptor
dw 0ffffh ; segment limit (bits 0 to 15)
dw 0 ; base address (bits 0 to 15)
db 0 ; base address (bits 16 to 23)
db B1+B4+B7 ; access (data, write, present,level 0)
db B6 ; limit 16-19, flags: 32-bit, 1 Byte
db 0 ; base address (bits 24 to 31)
BootGDTTabEnd:
; ------------- Boot global descriptor table
align 4, db 0
dw 0 ; align
BootGDT: dw BootGDTTabEnd-BootGDTTab-1 ; GDT size limit
dd BootGDTTab-SYSTEM_ADDR ; GDT base address
|