⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stuixldr.asm

📁 一个朋友写的操作系统源码
💻 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 + -