📄 stuixldr.asm
字号:
include const.inc
include comstruc.inc
dseg segment para public 'global'
bmpdata db 1024*10 dup (0) ; contain compressed info
pad dw 1023 ; can hold last byte and '|' maybe
palette db 1024 dup (0)
testmes db 'read to switch to protected mode ...',13,10,'$'
; Global varibles store here
; May be linked to other modual
public parambuf,paramnr,inodeblk,superblk
public configbuf,zonespace
public dirp,fn,dbuf,prom
superblk equ this byte ; superblk is used once, just multiplex
zonespace db 1024 dup (0) ; in floppy fs, block = zone
parambuf db '/etc/fstab$/stuix/kernel.bin$#'
db 64 dup (0)
paramnr dw 0 ; init to 0, only used for syntax checking
inodeblk db 1024 dup (0) ; block incore version
dirp dw 0 ; path character indicator
fn dw 0 ; files have been processed
dbuf db 14 dup (0) ; current pathname component
prom db '%d files have been converted!','$'
ipimage dw 0
csimage dw 0
configbuf db 1024 dup (0) ; holding /etc/fstab
a20mes db 'opening A20# address line ...',13,10,'$'
startup db 'ready to pass control to minix kernel ...',13,10,'$'
prfnum db '%d','$'
extrn newline:byte
dseg ends
overlap segment para common 'strucinfo'
; this is the only way to reference
; extern struct
inodeinfo minixinode <>
superinfo minixsuper <>
dent dirent <>
overlap ends
sseg segment stack
db 128 dup (0) ; make it big enough for kernel initialization
sseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
extrn printf:near
extrn panic:near
extrn printmenu:near
extrn pathinput:near
extrn lodmbr:near
extrn joinbuf:near
extrn chksynx:near
extrn eatpath:near
extrn getsuper:near
extrn getzone:near
extrn getinode:near
extrn clrmem:near
start:
jmp bootmanager
db 4096+16 dup (90h)
bootmanager:
push bp
mov bp,sp
sub sp,2
mov word ptr [bp-2],offset testmes
mov ax,dseg
mov ds,ax
mov es,ax
; file sytem self test
call getsuper ; init incore super structure slot
; if the fs magic number can't be found
; we have to stop here
; next we will try to analysis the parambuf
mov ax,1 ; get root inode
push ax
call getinode
pop ax
mov ax,1 ; read zone 1
push ax
call getzone
pop ax
; verify the attrib of root inode
push ds
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[inodeinfo.i_mode]
pop ds
assume ds:dseg ; restore segment
and ax,I_TYPE
cmp ax,I_DIRECTORY
je noproblem
mov ax,88h ; generate an unknow error
push ax
call panic
noproblem:
; display stuix logo
call dispbmp
call printmenu
; according to the value printmenu return
; we will branch to diffent subroutines
cmp ax,0
jne mbnext1
call lodmbr
; control will pass to hard disk mbr
mbnext1:
cmp ax,1
jne mbnext2
; clean the screen
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
mov al,0
mov ah,6
int 10h ; clean screen
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h ; home cursor
call clrmem
call eatpath
jmp finish
mbnext2:
; the last, ax must be 2
call pathinput
push ax
call joinbuf
pop cx
call chksynx ; almost verbose in this environment
; clean the screen
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
mov al,0
mov ah,6
int 10h ; clean screen
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h ; home cursor
call clrmem
call eatpath
finish:
; if fn < 2, it indicates there's some problem
; loading kernel or fstab, we can't move on
cmp word ptr [fn],2
je movon
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,13
push ax
call panic
movon:
mov ax,offset a20mes
push ax
call printf
pop cx
call enablea20
mov ax,[bp-2]
push ax
call printf
pop cx
call startstuix
hang:
jmp hang
;/============================================================================
;
; dispbmp
;
;============================================================================/
dispbmp proc near
push ds
push es
push bp
mov bp,sp
sub sp,2
; stack arranges like this
; [bp-2] : palette index
; first it should clear the screen in
; text mode and move the cursor to the
; the uper left conner
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
mov al,0
mov ah,6
int 10h
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h
; now we switch to graphice mode
mov ah,0 ; mode setting
mov al,13h ; 0x13 mode for 320*200
int 10h
; it is the opportunity to set palette
mov al,0 ; set palette register array index
mov dx,3c8h
out dx,al
mov word ptr [bp-2],0
bmw1loop:
cmp word ptr [bp-2],256*3
jae bmnext1
mov si,[bp-2]
mov al,palette[si]
mov dx,3c9h
out dx,al
inc word ptr [bp-2]
jmp bmw1loop
bmnext1:
; decompress data and load to video memory
call decompress
; delay 2 second to show boot menu
mov ax,36
push ax
call delay
pop cx
; switch back to text mode
mov ah,0
mov al,3
int 10h
mov sp,bp
pop bp
pop es
pop ds
ret
dispbmp endp
;/============================================================================
;
; decompress
;
;============================================================================/
decompress proc near
push ds
push es
push bp
mov bp,sp
sub sp,4
; stack arranges like this
; [bp-2] : compressed buf index
; [bp-4] : video memory index
mov ax,0a000h
mov es,ax
; initialize local variable
mov word ptr [bp-2],0
mov word ptr [bp-4],0
; search for a ~, if not found, move
; current pixel byte to video memory
; increase the video memory index and
; compressed buf index. if found, expand
; the original pixels to the video memory
; add the count to the video memory index
; and the compressed buf index, skip to
; next element
mov word ptr [bp-2],offset bmpdata
mov word ptr [bp-4],0
dpw1loop:
mov si,[bp-2]
cld
lodsb
inc word ptr [bp-2] ; we don't know what will happen
cmp al,7ch ; |
je depover
cmp al,7eh ; ~
jne dpnext1
; if this is a compressed element
add word ptr [bp-2],3 ; move to the next element
lodsw ; get compress count of element
mov cx,ax
mov di,[bp-4]
add word ptr [bp-4],cx
lodsb
repnz stosb ; expand to video memory
jmp dpw1loop
dpnext1:
mov di,[bp-4]
inc word ptr [bp-4]
stosb
jmp dpw1loop
depover:
; we have finish our job, just
; go back to dispbmp
mov sp,bp
pop bp
pop es
pop ds
ret
decompress endp
;/============================================================================
;
; enablea20
;
;============================================================================/
enablea20 proc near
push ds
push es
cli ; disable extral interrupt
kb_wait1:
in al,64h
test al,2 ; Keyboard input buffer full?
jnz kb_wait1 ; If so, wait
mov al,0D1h ; Tell keyboard that a command is coming
out 64h,al
kb_wait2:
in al,64h
test al,2 ; Keyboard input buffer full?
jnz kb_wait2 ; If so, wait
mov al,0dfh ; Enable or disable code
out 60h,al
kb_wait3:
in al,64h
test al,2 ; Keyboard input buffer full?
jnz kb_wait3 ; If so, wait
mov ax,25 ; 25 microsec delay for slow keyboard chip
waitport1:
out 0edh,al ; Write to an unused port (1us)
dec ax
jne waitport1
; the flowing code which have been commented
; maybe works happyly on any other machines
; but it can't work on author's Pentium II
; machine, probabely there's something wrong
; with the 8042 keyboard controller in the
; mainboard.
;kb_wait4:
; in al,64h
; test al,1
; jnz kb_wait4
; mov al,0d0h
; out 64h,al
;kb_wait5:
; in al,64h
; test al,2
; jnz kb_wait5
; wait for the controller to be ready
; with a byte of data
;datawait1:
; in al,64h
; test al,1
; jz datawait1
; in al,60h
; push ax
; xor ah,ah
; push ax
; mov ax,offset prfnum
; push ax
; call printf
; pop cx
; pop cx
; pop ax
; test if A20 enable
; test al,2
; jnz ea20suc
; mov ax,16
; push ax
; call panic
;ea20suc:
; we open the interrupt in order
; to start clock to allow delay
sti
pop es
pop ds
ret
enablea20 endp
;/============================================================================
;
; delay
;
;============================================================================/
delay proc near
push ds
push es
push bp
mov bp,sp
sub sp,8
; stack arranges like this
; [bp-2] : delay ticks
; [bp-4] : delay begin low 16bit
; [bp-6] : wakeup high 16bit
; [bp-8] : wakeup low 16bit
mov ax,8[bp]
mov [bp-2],ax
; get the low 16 bit of clock ticks
mov ax,40h ; clock ticks segment in BIOS
mov ds,ax
mov si,6ch ; low word offset in BIOS memory
mov ax,[si]
mov [bp-4],ax
add ax,[bp-2] ; calulate the wakeup time
mov [bp-8],ax
cmp ax,[bp-4]
jae dnext1
; wrap around detected, we have to store
; the high 16bit
mov si,6eh
mov ax,[si]
mov [bp-6],ax
inc word ptr [bp-6]
; assume it can't be second wrap around
; now wait for counter reaches that value
dw1loop:
mov si,6eh
mov ax,[si]
cmp ax,[bp-6]
je dnext2
jmp dw1loop
dnext2:
mov si,6ch
mov ax,[si]
cmp ax,[bp-8]
je dnext3
jmp dnext2
dnext3:
; time to go
mov sp,bp
pop bp
pop es
pop ds
ret
dnext1:
jmp dnext2
delay endp
;/============================================================================
;
; startstuix
;
;============================================================================/
startstuix proc near
; check the image of kernel we have just loaded
; we want to know if the format of kernel is just
; we want (magic #, executable, separate I&D), also
; we shall collect some information from kernel
; a.out header to help start stuix.
;
; You are not expected to understand this!
push cs
pop ax
inc ax ; start386 start at the next para
mov [csimage],ax
xor ax,ax
mov [ipimage],ax
push ds
push bp
mov bp,sp
sub sp,2
mov ax,2[bp]
mov [bp-2],ax ; can be used to address configbuf seg
mov ax,offset configbuf
push ax
mov ax,es_sym
mov ds,ax
mov si,di_sym
cld
lodsw
cmp ax,301h ; a.out magic #
jz hdrnext1
mov ax,17
push ax
call panic
hdrnext1:
lodsb
hdrnext2: ; this label has been obsoleted
; push ax
; xor ah,ah
; push ax
; mov ax,[bp-2]
; mov ds,ax
; mov ax,offset prfnum
; push ax
; call printf
; pop cx
; pop cx
; pop ax
test al,A_SEP
jnz hdrnext3
mov ax,19
push ax
call panic
hdrnext3:
; get the segment information
; use it to setup the protected
; mode execution environment
lodsb
xor ax,ax
lodsb
push ax ; hdrlen
lodsb ; skip cpu id
lodsw ; skip verion
lodsw
mov bx,ax
lodsw
push ax
push bx ; save a_text
lodsw
mov bx,ax
lodsw
push ax
push bx ; save a_data
lodsw
mov bx,ax
lodsw
push ax
push bx ; save a_bss
lodsw
mov bx,ax
lodsw
push ax
push bx ; save a_entry
lodsw
mov bx,ax
lodsw
push ax
push bx ; save a_total
; get cursor position need to resume
; display in protected mode
mov ah,3
mov bh,0
int 10h
push dx
; transfer control to start386.exe
; we must first restore data segment
mov ax,[bp-2]
mov ds,ax
; debug
mov ax,offset startup
push ax
call printf
pop cx
; give a latency to check the bootmanager message
mov ax,18
push ax
call delay
pop cx
mov si,offset ipimage
; memory indirect far jump machine code
db 0ffh
db 2ch
startstuix endp
cseg ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -