home *** CD-ROM | disk | FTP | other *** search
- ; >>> this is file LOADLINI.ASM
- ;============================================================================
- ; LOADLIN v1.5 (C) 1994 Hans Lermen (lermen@elserv.ffm.fgan.de)
- ;
- ; This program is free software; you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation; either version 2 of the License, or
- ; (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program; if not, write to the Free Software
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ;
- ;----------------------------------------------------------------------------
- ; Comments and bug reports are welcome and may be sent to:
- ; E-Mail: lermen@elserv.ffm.fgan.de
- ; SnailMail: Hans Lermen
- ; Am Muehlenweg 38
- ; D53424 REMAGEN-Unkelbach
- ; GERMANY
- ;
- ;============================================================================
-
-
- parscommandline proc near
- call clear_to_default
- mov cx,word ptr comline-1
- xchg ch,cl
- jcxz @@ex_carry
- mov si,cx
- mov comline[si+1],0
- mov image_name,0
- mov command_line,0
- mov cl_pointer,offset command_line
- lea si,comline+1
- lea di,image_name
- cld
- call get_token ; get the zImage-file name
- jz @@ex_carry
- ; got zImage-name
- ; try to get params
- cmp image_name,'@'
- jne @@1
- call read_comline_from_file
- jmp parscommandline
- @@1:
- lea di,image_name
- call tolower
- jmp @@next_token
-
- @@token_table label byte
- db 'ramdisk',0
- db 'vga',0
- db 'mem',0
- db 'root',0
- db 'ro',0
- db 'rw',0
- db 'no387',0
- db 'single',0
- db 'auto',0
- db '-v',0
- db '-t',0
- db '-d',0
- db '-rb',0
- db '-rx',0
- db '-ja',0
- db '-clone',0
- db '-oldxd',0
- db 'debug',0
- db 'no-hlt',0
- db 'reserve',0
- db 'hd',0
- db 'bmouse',0
- db 'max_scsi_luns',0
- db 'xd',0
- db '-n',0
- db 0
-
-
- @@jmp_table dw @@ramdisk
- dw @@vga
- dw @@tolower ; mem
- dw @@root
- dw @@ro
- dw @@rw
- dw @@tolower ; no387
- dw @@tolower ; single
- dw @@tolower ; auto
- dw @@option_v
- dw @@option_t
- dw @@option_d
- dw @@option_realbios
- dw @@option_rx
- dw @@option_ja
- dw @@option_clone
- dw @@option_oldxd
- dw @@tolower ; debug
- dw @@tolower ; no-hlt
- dw @@tolower ; reserve=
- dw @@tolower ; hd=
- dw @@tolower ; bmouse=
- dw @@tolower ; max_scsi_luns=
- dw @@tolower ; xd=
- dw @@option_n
-
- @@next_token:
- lea di,aux_token
- call get_token
- jz @@ex0
- lea di,aux_token
- lea bx,@@token_table
- call check_token
- js @@not_my_token
- jmp @@jmp_table[bx]
-
- @@ramdisk: ; have ramdisk param
- mov got_ram_disk,1
- mov new_ram_disk,1440
- jz @@next_token
- xchg si,di
- call value_of
- cmp word ptr [si],'on' ; disable diskchange prompt ?
- jne @@ramdisk_1
- mov option_nodiskprompt,1
- @@ramdisk_1:
- xchg si,di
- mov new_ram_disk,ax
- jmp @@next_token
-
- @@token_table_vga label byte
- db 'normal',0
- db 'extended',0
- db 'ask',0
- db 0
-
- @@vga: ; have vga - param
- mov got_vga_mode,1
- mov new_vga_mode,-1 ; default = NORMAL
- jz @@next_token
- mov bx,di
- cmp byte ptr [bx],'-'
- jne @@vga_1
- inc bx
- @@vga_1:
- cmp byte ptr [bx],'0'
- jb @@check_vga_sym
- cmp byte ptr [bx],'9'
- jna @@check_vga_num
- @@check_vga_sym:
- ; DI already pointing to value
- lea bx,@@token_table_vga
- call check_token
- js @@next_token
- shr bx,1
- not bx
- mov new_vga_mode,bx
- jmp @@next_token
- @@check_vga_num:
- xchg si,di
- call value_of
- xchg si,di
- mov new_vga_mode,ax
- jmp @@next_token
-
- @@ro: ; mount root readonly
- mov got_ro_flag,1
- mov new_ro_flag,1
- jmp @@next_token
- @@rw: ; mount root readwrite
- mov got_ro_flag,1
- mov new_ro_flag,0
- jmp @@next_token
-
- @@option_t:
- mov option_t,1 ; forces also option -v
- @@option_v:
- mov option_v,1
- jmp @@next_token
-
- @@option_d:
- lea di,aux_token ; get output file name
- call get_token
- jz @@option_t ; no file name
- push_ bx,cx,dx
- xor cx,cx
- lea dx,aux_token
- DosCall DOS_CREATE_FILE
- pop_ bx,cx,dx
- jc @@option_t
- mov debug_file_handle,ax
- jmp @@option_t
-
- @@option_realbios:
- mov option_realbios,1
- jmp @@next_token
- @@option_rx:
- mov option_rx,1
- jmp @@next_token
- @@option_ja:
- mov option_ja,1
- jmp @@next_token
- @@option_clone:
- mov option_clone,1
- jmp @@next_token
- @@option_oldxd:
- mov byte ptr @@num_table_root_xd+1,0ch
- mov byte ptr @@num_table_root_xd+2+1,0ch
- mov option_oldxd,1
- jmp @@next_token
- @@option_n:
- mov option_n,1
- jmp @@next_token
-
-
- @@token_table_root label byte
- db 'fd',0
- db 'hda',0,'hdb',0
- db 'sda',0,'sdb',0,'sdc',0,'sdd',0,'sde',0
- db 'xda',0,'xdb',0
- db 0
- @@num_table_root label word
- dw 0200h
- dw 0300h,0340h
- dw 0800h,0810h,0820h,0830h,0840h
- @@num_table_root_xd:
- dw 0D00h,0D40h
-
- @@root:
- jz @@not_my_token
- push di
- lea di,aux_token
- call tolower
- pop di
- cmp dword ptr [di],'ved/'
- je @@root_d
- cmp word ptr [di],'x0'
- je @@root_1
- sub di,2 ; force hex decoding
- mov word ptr [di],'x0'
- @@root_1:
- xchg si,di
- call value_of
- xchg si,di
- mov got_root_dev,1
- mov new_root_dev,ax
- jmp @@root_next_token
- @@root_d:
- add di,5
- push di
- push dword ptr [di]
- mov di,sp
- mov byte ptr [esp+3],0
- cmp word ptr [esp],'df'
- jne @@root_d_1
- mov byte ptr [esp+2],0
- @@root_d_1:
- lea bx,@@token_table_root
- call check_token
- lea esp,[esp+4]
- pop di
- js @@not_my_token
- mov ax,@@num_table_root[bx]
- mov got_root_dev,1
- mov new_root_dev,ax
- or bx,bx ; is it the floppy
- jne @@root_d_h ; no
- cmp byte ptr [di+2],'1'
- jne @@root_next_token
- inc new_root_dev
- jmp @@root_next_token
- @@root_d_h:
- add di,3
- cmp byte ptr [di],0
- je @@root_next_token
- cmp byte ptr [di],'0'
- jne @@root_d_h_1
- cmp byte ptr [di+1],'x'
- je @@root_d_h_2
- @@root_d_h_0:
- dec di
- mov word ptr [di],'x0'
- @@root_d_h_2:
- xchg si,di
- call value_of
- xchg si,di
- add new_root_dev,ax
- jmp @@root_next_token
- @@root_d_h_1:
- jb @@not_my_token
- cmp byte ptr [di],'a'
- jb @@root_d_h_2
- cmp byte ptr [di],'f'
- ja @@not_my_token
- dec di
- jmp @@root_d_h_0
-
- @@root_next_token:
- cmp option_n,0
- jnz @@not_my_token
- jmp @@next_token
-
-
- @@not_my_token:
- push si
- lea si,aux_token
- call @@append_to_commandline
- pop si
- jmp @@next_token
- @@tolower:
- lea di,aux_token
- call tolower
- jmp @@not_my_token
-
-
-
- @@ex0:
- lea si,@@boot_tx
- call @@append_to_commandline
- dec cl_pointer
- lea si,image_name
- cld
- mov di,si
- @@ex1:
- lodsb
- test al,al
- jz @@ex3
- cmp al,':'
- je @@ex2
- cmp al,'\'
- je @@ex2
- cmp al,'/'
- jne @@ex1
- @@ex2:
- mov di,si
- jmp @@ex1
- @@ex3:
- mov si,di
- call @@append_to_commandline
- @@ex:
- clc
- ret
- @@ex_carry:
- stc
- ret
-
- @@append_to_commandline:
- mov di,cl_pointer
- @@append_to_1:
- lodsb
- stosb
- test al,al
- jnz @@append_to_1
- mov byte ptr [di-1],' '
- mov byte ptr [di],al
- mov cl_pointer,di
- ret
-
- @@boot_tx db 'BOOT_IMAGE=',0
-
- parscommandline endp
-
-
- handle_kernel_specifics proc near
- cmp kernelversion,0
- jz @@ex
- cmp option_oldxd,0
- jne @@ex
- cmp word ptr kernelversion+2,0101h ; 1.1.x () #x
- jnb @@ex
- cmp got_root_dev,0
- jz @@ex
- cmp byte ptr new_root_dev+1,0dh
- jne @@ex
- mov byte ptr new_root_dev+1,0ch
- @@ex:
- ret
- handle_kernel_specifics endp
-
- get_token proc near
- push di
- @@skip_loop:
- lodsb
- cmp al,' '
- je @@skip_loop
- jmp @@ok
- @@loop:
- lodsb
- cmp al,' '
- jne @@ok
- xor al,al
- @@ok:
- stosb
- test al,al
- jne @@loop
- dec si
- pop di
- test byte ptr es:[di],255
- ret
- get_token endp
-
-
- readstring proc near
- push dx
- mov comline-1,255-2
- lea dx,comline-1
- DosCall DOS_BUFFERED_INPUT
- lea dx,newline_tx
- call print
- push bx
- movzx bx,comline
- mov comline[bx+1],0
- mov comline-1,0
- pop bx
- pop dx
- ret
- readstring endp
-
-
- tolower proc near
- ; input:
- ; DS:DI= address to ASCIIZ-string
- cld
- xchg si,di
- @@loop:
- lodsb
- or al,al
- jz @@ex
- cmp al,'A' ; tolower !
- jb @@loop
- cmp al,'Z'
- ja @@loop
- add byte ptr [si-1],'a'-'A'
- jmp @@loop
- @@ex:
- xchg si,di
- ret
- tolower endp
-
- name_compare proc near
- ; input:
- ; DS:DI= address to ASCIIZ-string (name1)
- ; (a "=" marks end of string also)
- ; CS:BX= address to ASCIIZ-string (name2)
- ; CX= max number of character to compare
- ; compare is done by ignoring upper/lower-case
- ; Output:
- ; AX= 0 if not equal else equal
- ; DI= as changed by lodsb, pointing behind terminator (0 or '=')
- ; all other register preserved
- cld
- push bx
- xchg si,di
- sub bx,si
- @@m3:
- lodsb
- cmp al,'=' ; may be name in environement
- jne short @@32
- xor al,al
- jmp short @@m35
- @@32:
- cmp al,'A' ; tolower !
- jb short @@m35
- cmp al,'Z'
- ja short @@m35
- add al,'a'-'A'
- @@m35:
- mov ah,al
- mov al,byte ptr cs:[si+bx-1]
- cmp al,'A' ; tolower !
- jb short @@m36
- cmp al,'Z'
- ja short @@m36
- add al,'a'-'A'
- @@m36:
- or al,al
- jz short @@ex_
- or ah,ah
- jz short @@exfalse
- cmp ah,al
- jne @@exfalse
- loop @@m3
- @@extrue:
- mov ax,1
- @@ex:
- xchg si,di
- pop bx
- or ax,ax
- ret
- @@ex_:
- or ax,ax
- jz @@extrue
- @@exfalse:
- xor ax,ax ; not equal
- jmp @@ex
- name_compare endp
-
-
- get_env_variable proc near
- ; Input
- ; CS:BX= Pointer to string (ASCIIZ) of desired env-variable
- ; Output:
- ; ES:DI= pointer to string (ASCIIZ) of variable contents (without "=")
- ; or ZERO-string if not found
- ; All other registers preserved
- push ds
- push ax
- push si
- mov ds,PSP_frame
- mov ds,ds:PSP_envir_frame
- xor si,si
-
- mov al,byte ptr [si]
- @@m1:
- mov cx,80
- or al,al
- mov di,si
- jz @@ex
- call name_compare
- jnz @@found ; string is equal, found the variable
- cld
- @@m2: ; skip to next string
- lodsb
- or al,al
- jnz @@m2
- mov al,byte ptr [si]
- jmp @@m1
- @@found:
- @@ex:
- push ds
- pop es
- pop si
- pop ax
- pop ds
- ret
- get_env_variable endp
-
-
-
-
- value_of proc near
- ; Input:
- ; DS:SI= pointer to string (ASCIIZ), which contains number to be converted
- ; (i.e.: 1234, 0xa00, ... ), all non-digit-characters (0..9,a..f,A..F)
- ; are "delimiters" and mark the end of the string
- ; Output:
- ; EAX= converted number
- ; SI= pointing at the first byte behind the delimiter
- cmp byte ptr [si],'-'
- pushf
- jnz @@m0
- inc si
- @@m0:
- push_ ebx,ecx,edx,edi,esi
- mov ebx,10
- xor edx,edx
- xor edi,edi
- inc edi
- cld
- lodsb
- call @@check_white
- jc @@ex
- jne @@m1
- lodsb
- or al,20h ; convert to lowercase
- cmp al,'x'
- jne @@m1
- mov ebx,16
- lodsb
- @@m1:
- call @@check_white
- jb @@ex
- xor ecx,ecx
- @@m2:
- inc ecx
- lodsb
- call @@check_white
- jnc @@m2
- std
- mov [esp],esi ;advance pointer
- dec si
- dec si
- @@m3:
- lodsb
- or al,20h ; convert to lowercase
- cmp al,'9'
- jna short @@m4
- add al,9
- @@m4:
- and al,0fh
- movzx eax,al
- imul eax,edi
- imul edi,ebx
- add edx,eax
- loop @@m3
- @@ex:
- mov eax,edx
- pop_ ebx,ecx,edx,edi,esi
- popf
- jnz @@ex_
- neg eax
- @@ex_:
- ret
-
- @@check_white:
- mov ah,'f'
- cmp bl,16
- je short @@7
- mov ah,'9'
- @@7:
- or al,20h
- cmp al,'0'
- jb short @@9
- cmp al,ah
- ja short @@9
- cmp al,'9'
- jbe short @@8
- cmp al,'a'
- jae short @@8
- @@9:
- mov al,' '
- @@8:
- cmp al,'0'
- ret
-
- value_of endp
-
-
- check_VCPI_present proc near
- pushad
- push es
- push ds
- lea esp,[esp-4] ; local space
- @@stack struc
- @@handle dw ?
- dw ?
- @@ds dw ?
- @@es dw ?
- pushad_struc @@
- @@stack ends
- xor eax,eax ; check EMM_interrupt present
- mov [esp].@@eax,eax
- mov es,ax
- mov es,word ptr es:[emm_int*4+2]
- cmp Dword ptr es:[10+4],'0XXX'
- jne @@ex
- cmp dword ptr es:[10],'XMME'
- je @@ok
- cmp dword ptr es:[10],'QMME' ; this also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
- jne @@ex
- @@ok:
- mov ax,4000h ; check emm menager status
- int emm_int
- or ah,ah
- jnz @@ex
- mov ax,_GET_VERSION*256 ; get version
- int emm_int
- cmp ax,40h ; version must be greater 4.0
- jb @@ex
-
- mov ax,_ALLOCATE_RAW_PAGES
- mov bx,4
- int emm_int
- cmp ah,0
- jnz @@ex
- mov word ptr [esp].@@handle,dx ; save handle
- mov ax,0DE00h ; check for VCPI present
- int emm_int
- cmp ah,0
- jne short @@notok
- mov byte ptr [esp].@@eax,1
- @@notok:
- mov dx,word ptr [esp].@@handle
- mov ax,_DEALLOCATE_PAGES*256
- int emm_int
- @@ex:
- lea esp,[esp+4] ; discar local space
- pop ds
- pop es
- popad
- or ax,ax
- ret
- check_VCPI_present endp
-
- get_VCPI_interface proc near
- push cs ;* buffer for server GDT entries
- push offset gdtvcpi_code ;*
- push cs ;* buffer for server page0
- push offset page0 ;*
- call get_protected_mode_interface
- ret
- get_VCPI_interface endp
-
-
- check_low_mem_mapping proc near
- call get_VCPI_interface
- xor edx,edx
- lea si,page0
- cld
- mov cx,(640/4)
- @@loop:
- lodsd
- and ax,0f000h
- cmp eax,edx
- jne @@ex_false
- add edx,1000h
- loop @@loop
- mov ax,1
- @@ex:
- or ax,ax
- ret
- @@ex_false:
- xor ax,ax
- jmp @@ex
- check_low_mem_mapping endp
-
-
- get_protected_mode_interface proc near
- ARG server_pagebuffer:dword,server_selectors:dword = returnpop
- push bp
- mov bp,sp
- push si
- push di
- push ds
- push es
-
- ; convert pagebuffer to linear address
- movzx eax,word ptr server_pagebuffer+2
- movzx ebx,word ptr server_pagebuffer
- shl eax,4
- add eax,ebx
- shr eax,4 ; make real mode address
-
- ;XXXXXXXXXX
- push ds
- mov es,ax ; ES = frame of server_pagebuf
- xor di,di ; ES:DI = >buffer for page0-table<
- lds si,server_selectors ; DS:DI = >3 GDT entries for VCPI
- ; calling VCPI server
- mov ax,0DE01h
- int emm_int
- pop ds
-
- IF 0 ; do not need this here
- ; save VCPI server entry for protected mode
- mov dword ptr server_vcpi_entry,ebx
- ; set the VCPI-Code selector
- mov word ptr server_vcpi_entry+4,g_vcpi_code
- ENDIF
- ;XXXXXXXXXXX
-
-
-
- pop es
- pop ds
- pop di
- pop si
- pop bp
- ret returnpop
- get_protected_mode_interface endp
-
-
- try_biosintv proc near
- pushad
- mov ax,DOS_OPEN_FILE shl 8
- lea dx,@@fname
- DosInt
- jc @@ex_false
- mov bx,ax
- mov ax,4402h
- mov cx,size intv_buf
- lea dx,intv_buf
- DosInt
- pushf
- push ax
- DosCall DOS_CLOSE_FILE
- pop ax
- popf
- jc @@ex_false
- mov intv_size,ax
- mov ax,1
- @@ex:
- or ax,ax
- popad
- ret
- @@ex_false:
- xor ax,ax
- jmp @@ex
- @@fname db '$BIOSINT',0
- try_biosintv endp
-
- try_realbios proc near
- pushad
- mov ax,DOS_OPEN_FILE shl 8
- lea dx,@@fname_realbios
- DosInt
- jc @@ex_false
- mov bx,ax
- lea dx,intv_buf
- mov cx,realbios_end-intv_buf
- DosCall DOS_READ_FROM_HANDLE
- pushf
- push ax
- DosCall DOS_CLOSE_FILE
- pop ax
- popf
- jc @@ex_false
- cmp ax,realbios_end-intv_buf
- jne @@ex_false
- mov intv_size,ax
- cmp cs:option_rx,1
- je @@ex_true
- ; we now check the BIOS-revision to be sure
- ; that we have the right file
- push es
- mov ax,0ffffh
- mov es,ax
- mov eax,dword ptr es:[biosdate-reset_jmpop]
- cmp eax,dword ptr cs:biosdate
- jne @@ex_wrong_bios
- mov eax,dword ptr es:[(biosdate-reset_jmpop)+4]
- cmp eax,dword ptr cs:biosdate+4
- jne @@ex_wrong_bios
- ; we check the real_bios_magic
- cmp cs:real_bios_magic,0a5a5h
- jne @@ex_wrong_bios
- @@ex_true:
- mov ax,1
- pop es
- @@ex:
- or ax,ax
- popad
- ret
- @@ex_false:
- mov intv_size,0
- xor ax,ax
- jmp @@ex
- @@ex_wrong_bios:
- pop es
- mov wrong_realbios,1
- call force_error_verbose
- jmp @@ex_false
-
- @@fname_realbios db REALBIOS_FILE,0
- try_realbios endp
-
- get_default_bios_intvectors proc near
- cmp option_ja,0
- jnz @@first_javier
- cmp option_realbios,0
- jnz @@first_realbios
- call try_biosintv
- jnz @@ex
- call try_realbios
- @@ex:
- ret
- @@first_realbios:
- call try_realbios
- jnz @@ex
- call try_biosintv
- jmp @@ex
- @@first_javier:
- mov intv_size,0
- jmp @@ex
- get_default_bios_intvectors endp
-
-
- pmode_return_esp dd ? ; used to return from real-mode-switch
- real_IDTR dw 03ffh ;needed to load real intvector after switch
- dd 0
-
- pmode_task proc near
- ; We come here in protected mode via VCPI-CALL
- ; have only to set up all things to switch back to 386-realmode
- ;
- ; We follow the INTEL recomended procedure to do this
- ; (80386 Programmer's Reference Manual, Chapter 14.5)
- ;
- .386p
- CLI ; just to be sure
-
- ; 1. We know, that paging is enabled,
- ; that linear addresses have identical mapping
- ; so we can clear the PG bit
-
- mov eax,CR0
- and eax,07fffffffh
- mov CR0,eax ; paging is off
- xor eax,eax
- mov CR3,eax ; clear out paging cache
-
- ; 2. We must transfer control to segment with 64K limit
- ; we ARE on such a segment, no need to do it here
-
- ; 3. Load segment registers SS,DS,ES,FS,GS with a selector
- ; that points to a descriptor containing the the values:
- ; limit 64k = 0FFFFh
- ; byte granularity
- ; Expand up
- ; writable
- ; present
- ;
- ; We have that descriptor, its our gdt_data.
- mov ax,g_data
- mov ss,ax
- mov ds,ax
- mov es,ax
- mov fs,ax
- mov gs,ax
-
- ; 4. Disable Interrrupts
- ; ( we did that above )
- ; 5. Clear the PE bit in CR0
- mov eax,CR0
- and al,0feh
- mov CR0,eax ; we are go back to realmode
-
- ; 6. Flush the instruction queue and load CS with approritate value
- ;jmp far ptr @@here
- db 0EAh
- dw @@here,High_Seg
- @@here label far
-
- ; 7. Use LIDT instruction to load the base and limits of the
- ; real-mode interrupt vector table
- lidt fword ptr cs:real_IDTR
-
- .386
- ; 8. Enable interrupts (we are doing this later)
- ; 9. Load segment register
- mov ax,High_Seg
- mov ss,ax
- mov ds,ax
- mov es,ax
- mov fs,ax
- mov gs,ax
- mov esp,pmode_return_esp
- ; now we are in "real" real-mode
-
- call restore_bios_default_vectors
- @@ex:
- popad
- ret
- pmode_task endp
-
- iodelay macro
- jmp short $+2
- jmp short $+2
- endm
-
- get_mem_from_CMOS proc near
- pushf
- cli
- push bx
- mov al,18h
- out [070h],al
- dec al
- mov bl,al
- iodelay
- in al,[071h]
- mov ah,al
- mov al,bl
- iodelay
- out [070h],al
- iodelay
- in al,[071h] ; extended mem read from CMOS
- pop bx
- popf
- ret
- get_mem_from_CMOS endp
-
-
-
- restore_bios_default_vectors proc near
- push_ es,ds,ax,cx,si,di
- xor di,di
- mov es,di
- cmp cs:have_to_intercept_setup,0
- jz @@p2
- ; No REALBIOS or device driver
- cmp word ptr cs:intv_buf+(4*15h+2),0
- jne @@ex ; Only once
- mov eax,dword ptr es:[4*15h]
- mov dword ptr cs:intv_buf+(4*15h),eax
- call get_mem_from_CMOS
- mov cs:real_bios_int15,ax
- jmp @@p1
- @@p2:
- mov cx,cs:intv_size
- shr cx,2
- jcxz @@ex
- ; we now reset the intvector to bios-defaults
- push cs
- pop ds
- cmp cx,(size intv_buf)/4 ; have we REALBIOS
- jna @@1 ; no
- ; yes
- ; restoring BIOSdata also
- mov cx,(dummy_dos_data-intv_buf)/4
- @@1:
- lea si,intv_buf
- cld
- rep movsd
- cmp cs:intv_size,(size intv_buf) ; have we REALBIOS
- jna @@8 ; no
- ; yes, restoring BIOSscratch also
- mov di,09FC0h
- mov es,di
- xor di,di
- lea si,bios_scratch
- mov cx,(size bios_scratch)/4
- rep movsd
- ; now reprogram the PICs (8259A)
- ; (may be redirected by VCPI-client)
- mov al,11h ; enter programming mode
- out [20h],al ; master
- iodelay
- out [0A0h],al ; slave
- iodelay
- mov al,8 ; IRQ0..7 --> INT8..F
- out [21h],al ; master
- iodelay
- mov al,70h ; IRQ8..F --> INT70..77
- out [0A1h],al ; slave
- iodelay
- mov al,4 ; master bit
- out [21h],al ; master
- iodelay
- mov al,2 ; slave bit
- out [0A1h],al ; slave
- iodelay
- mov al,1 ; 8086 mode
- out [21h],al ; master
- iodelay
- out [0A1h],al ; slave
- iodelay
- mov al,cs:slaveIMR
- out [0A1h],al ; slave
- iodelay
- mov al,cs:masterIMR
- out [21h],al ; master
-
- @@p1: ; we hook on the INT15
- xor ax,ax
- mov es,ax
- mov word ptr es:[4*15h],offset our_int15
- mov word ptr es:[4*15h+2],cs
- ; now we must reinit the video controler
- ; to the values just set in the BIOS-data
- ; we do it by calling the appropriate INT 10h
- mov ax,3003h ; al = color mode
- and ah,byte ptr cs:bios_data+10h ; get EQUIPPEMENT-flags
- cmp ah,30h
- jne @@6
- mov al,7 ; al = mono mode
- @@6:
- xor ah,ah
- INT 10h
- @@8:
- push ds
- pop es
- @@ex:
- mov cs:intv_size,0 ; avoid second call
- pop_ es,ds,ax,cx,si,di
- ret
- restore_bios_default_vectors endp
-
-
- our_int15 proc near
- ; interrupt 15 hook, in case of realbios
- cmp ah,88h
- je @@we_do_it
- jmp dword ptr cs:intv_buf+(4*15H)
- @@we_do_it:
- mov ax,cs:real_bios_int15
- ;;;test mov ax,0c00h*4
- iret
- our_int15 endp
-
-
-
- switch_to_protected_mode_and_return_in_386realmode proc near
- ; NOTE: must have called "prepare_for_protected_mode" before this !
- ;
- ; returns with interrpts disabled
- ; all registers preserved, all segment registers = "High_Seg"
- cmp cs:have_to_force_realmode,0
- jnz @@goon
- ret
- @@goon:
- mov cs:have_to_force_realmode,0
- pushad
- mov pmode_return_esp,esp
- lea ax,pmode_task
- movzx eax,ax
- mov dword ptr protected_mode_target,eax
- mov word ptr protected_mode_target+4,g_code
- mov esi,High_Seg
- shl esi,4
- lea si,our_CR3[si]
- CLI
- mov ax,0DE0Ch
- int emm_int ; jumps to protected mode
- ; does NOT return here
- ; "pmode_task" does return directly to our caller
- switch_to_protected_mode_and_return_in_386realmode endp
-
-
- ; input:
- ; ES:DI pointer to string
- ; AL = terminating character
- ; output:
- ; AX= length of string, not counting terminating character
- ; all other registers preserved
- strlen proc near
- .8086
- push_ di,cx
- xor cx,cx
- dec cx
- cld
- repne scasb
- mov ax,di
- dec ax
- pop_ di,cx
- sub ax,di
- .386
- ret
- strlen endp
-
-
- get_kernel_version proc near
- ; Input:
- ; DS=CS
- ; Output:
- ; EAX= converted verion number as:
- ; 1.2.3 (root:pipapo) #4 ... ---> EAX= 01020304h
- ; 1.2.3 ---> EAX= 01020300h
- ; all other registers preserved
- xor eax,eax
- cmp have_to_intercept_setup,2
- jne @@ex
- cmp setup_header_version,0105h
- jb @@ex
- cmp kernel_version,0
- jz @@ex
- push_ esi,edx
- mov si,kernel_version
- lea si,setup_prog[si]
- call value_of
- mov edx,eax
- call value_of
- ror eax,8
- shld edx,eax,8
- call value_of
- ror eax,8
- shld edx,eax,8
- xor eax,eax
- cmp byte ptr [si-1],0 ; end of string ?
- je @@ex_
- cld
- @@loop:
- lodsb
- test ax,ax
- jz @@ex_
- cmp al,'#'
- jne @@loop
- call value_of
- ror eax,8
- @@ex_:
- shld edx,eax,8
- mov eax,edx
- pop_ esi,edx
- @@ex:
- ret
- get_kernel_version endp
-
- writechar proc near
- push_ eax,edx
- push eax
- mov byte ptr [esp+1],'$'
- mov dx,sp
- call print
- add sp,4
- pop_ eax,edx
- ret
- writechar endp
-
-
- writestring proc near
- cld
- @@1:
- lodsb
- test al,al
- jz @@ex
- call writechar
- loop @@1
- @@ex:
- ret
- writestring endp
-
- writehexdigit proc near
- push eax
- and al,0fh
- add al,'0'
- cmp al,'9'
- jna @@m1
- add al,'A'-('9'+1)
- @@m1:
- call writechar
- pop eax
- ret
- writehexdigit endp
-
- writehexbyte proc near
- push eax
- ror eax,4
- call writehexdigit
- rol eax,4
- call writehexdigit
- pop eax
- ret
- writehexbyte endp
-
-
- writehexword proc near
- push eax
- ror eax,8
- call writehexbyte
- rol eax,8
- call writehexbyte
- pop eax
- ret
- writehexword endp
-
-
- force_error_verbose proc near
- mov option_v,1
- mov option_t,1
- mov option_t_forced,1
- ret
- force_error_verbose endp
-
- print_verbose proc near
- pushad
- push_ ds,es
-
- @@print macro tx
- lea dx,tx
- call print
- endm
- @@cr macro
- call print_crlf
- endm
- @@prints macro tx,count
- mov cx,count
- lea si,tx
- call writestring
- endm
- @@hexw macro v
- mov ax,v
- call writehexword
- endm
-
- @@print @@t1
- @@prints image_name,<size image_name>
- cmp have_to_intercept_setup,2
- jne @@m1
- cmp setup_header_version,0105h
- jb @@m1
- cmp kernel_version,0
- jz @@1
- @@print @@t1_
- mov dx,kernel_version
- add dx,offset setup_prog
- call print
- @@m1:
- @@print @@t2
- @@hexw kernel_size
- @@print @@t2_
- @@hexw new_setup_size
- @@print @@t3
- @@hexw ram_disk
- @@print @@t4
- @@hexw root_dev
- lea dx,@@trw
- cmp ro_flag,0
- jz @@2
- lea dx,@@tro
- @@2:
- call print
- @@print @@v1
- @@hexw vga_mode
- @@print @@c1
- lea di,command_line
- xor ax,ax
- call strlen
- push ax
- call writehexword
- @@print @@c2
- pop cx
- @@prints command_line,cx
- @@cr
-
- @@verbose_stat:
-
- @@print @@t21
- mov ax,High_Seg
- sub ax,kernel_load_frame
- call writehexword
- @@print @@t21_
- mov ax,maximum_setup_sects*512
- call writehexword
- @@print @@t22
- mov ah,88h
- cmp intv_size,15h*4
- jnb @@sim_int15
- cmp have_to_intercept_setup,0
- jz @@sim_int15_1
- call get_mem_from_CMOS
- jmp @@1
- ; we take int 15 as is, result may be wrong
- ; but Linux takes this as memory
- @@sim_int15_1:
- int 15h
- jmp @@1
- @@sim_int15:
- cmp wrong_realbios,0
- jne @@sim_int15_1
- cmp cs:real_bios_magic,0a5a5h ; have we a saved value
- jne @@sim_int15_2 ; no
- mov ax,cs:real_bios_int15 ; yes
- jmp @@1
- @@sim_int15_2:
- ; we take int 15 routine as saved by BIOSINTV
- ; hopefully this gets better result
- pushf
- cli
- push cs
- push offset @@1
- push dword ptr intv_buf+(15h*4)
- retf
- @@1:
- shr ax,2
- add ax,100h
- call writehexword
-
-
- @@print @@t5
- lea dx,@@real_
- cmp cpu_type,cpu_386GE
- je @@3
- lea dx,@@real_p
- ja @@3
- lea dx,@@v86
- @@3:
- call print
- cmp wrong_realbios,0
- je @@3__
- @@print @@t6_
- lea dx,@@t6__
- jmp @@3_1
- @@3__:
- lea dx,@@t6
- cmp intv_size,(size intv_buf) ; have we REALBIOS
- jna @@3_
- lea dx,@@t6_
- @@3_:
- call print
- lea dx,@@no
- cmp intv_size,0
- jz @@3_1
- lea dx,@@yes
- @@3_1:
- call print
- @@print @@t7
- lea dx,@@no
- cmp have_to_intercept_setup,1
- jb @@3_2
- lea dx,@@setup_
- je @@3_2
- lea dx,@@setup
- @@3_2:
- call print
-
- @@print @@s
- mov bx,cpu_check_status
- mov dx,@@stable[bx]
- call print
- @@print @@cc1
- lea di,comline+1
- xor ax,ax
- call strlen
- push ax
- call writehexword
- @@print @@cc2
- pop cx
- @@prints comline+1,cx
- @@print @@started
- lea dx,@@rundos
- cmp can_exit_to_dos,0
- jnz @@4_1
- lea dx,@@runshell
- @@4_1:
- call print
-
- cmp cannot_load_because_of_windows,0
- jz @@5
- @@print @@sw
- @@5:
- cmp cpu_type,cpu_386GE_real_paging
- jne @@6
- @@print @@w1
- @@6:
-
-
- mov ax,High_Seg
- sub ax,kernel_load_frame
- cmp kernel_size,ax
- jb @@7
- @@print @@w2
- @@7:
- cmp new_setup_size,maximum_setup_sects*512
- jna @@8
- @@print @@w3
- @@8:
-
- pop_ ds,es
- popad
- ret
-
- @@t1 db 13,10,'Your current LINUX kernel boot configuration is:'
- db 13,10,' image file: $'
- @@t1_ db 13,10,' kernel version $'
- @@t2 db 13,10,' kernel size: 0x$'
- @@t2_ db '0 setup size: 0x$'
- @@t3 db 13,10,' ram disk size: 0x$'
- @@t4 db 13,10,' root device: 0x$'
- @@tro db ' read only$'
- @@trw db ' read/write$'
- @@v1 db 13,10,' VGA mode: 0x$'
- @@c1 db 13,10,' command line size 0x$'
- @@c2 db 13,10,' command line:'
- db 13,10,' $'
- @@t21 db 13,10,'Your current DOS/CPU configuration is:'
- db 13,10,' load buffer size: 0x$'
- @@t21_ db '0 setup buffer size: 0x$'
- @@t22 db 13,10,' total memory: 0x$'
- @@t5 db '000',13,10,' CPU is in $'
- @@t6 db 13,10,' BIOSINTV.SYS: $'
- @@t6_ db 13,10,' REALBIOS: $'
- @@t6__ db 'YES, but ROM-BIOS-DATE differs, must rerun REALBIOS.EXE$'
- @@t7 db 13,10,' SetupIntercept: $'
- @@yes db 'YES$'
- @@no db 'NO$'
- @@v86 db 'V86 mode$'
- @@real_ db 'REAL mode$'
- @@real_p db 'undocumented REAL PAGING mode, trying any way$'
- @@setup_ db 'YES, patching setup code$'
- @@setup db 'YES, legal intercept$'
- @@s db 13,10,' stat$'
- @@s8 db '4: VCPI_present, physmap=logmap, all OK for switch to realmode$'
- @@s6 db '3: VCPI_present, but physmap != logmap (check aborted)$'
- @@s4 db '2: cpu_V86, but no VCPI available (check aborted)$'
- @@s2 db '1: cpu in real 386 mode, no need to backswitch$'
- @@s0 db '0: cpu < 386$'
- @@stable dw @@s0,@@s2,@@s4,@@s6,@@s8
- @@cc1 db 13,10,' input params size 0x$'
- @@cc2 db 13,10,' input params:'
- db 13,10,' $'
- @@started db 13,10,' LOADLIN started from $'
- @@rundos db 'DOS-prompt',13,10,'$'
- @@runshell db 'CONFIG.SYS (shell= ...)',13,10,'$'
- @@sw db ' You are running under MS-WINDOWS',13,10,'$'
- @@w1 db 'WARNING:',13,10
- db ' Your CPU is in realmode, but PAGING is enabled !',13,10
- db ' This is possible, but neither documented nor supported by INTEL.',13,10
- db " May be your motherboard's BIOS is mapping shadow ram this way,",13,10
- db ' or you are using one of those old and strange EMM managers,',13,10
- db ' but probably this is an indication of a not exactly compatible',13,10
- db ' 486 clone. If you are not using one of the older EMM-managers',13,10
- db ' you better should use the -clone switch to work around.',13,10,'$'
- @@w2 db 'WARNING: Not enough free memory below 90000h (load buffer size)$',13,10
- @@w3 db 'WARNING: The setup buffer of LOADLIN is too small (must recompile)$',13,10
-
- print_verbose_stat:
- pushad
- push_ ds,es
- jmp @@verbose_stat
- print_verbose endp
-
-
- close_debug_file proc near
- cmp debug_file_handle,0
- jz @@ex
- push_ ax,bx
- mov bx,debug_file_handle
- DosCall DOS_CLOSE_FILE
- mov debug_file_handle,0
- pop_ ax,bx
- @@ex:
- ret
- close_debug_file endp
-
-
- ;=============================================================================
- logo_tx label byte
- IF 0
- INCLUDE LOADLINA.ASM
- ENDIF
- db 'LOADLIN v1.5 (C) 1994 Hans Lermen (lermen@elserv.ffm.fgan.de)',13,10,'$'
- comspec_tx db 'comspec',0
- windows_tx db 'windir',0
- err_uppermem_tx db 'Not enough free memory between 90000h and 9ffffh,',13,10
- db 'may be you have some zombie programs, try to reboot.',13,10
- db "If this doesn't help, try to find out what driver occupies this space."
- newline_tx db 13,10,'$'
- enter_commandline_tx db 'Please enter name of kernel image file followed by optional ',13,10
- db 'command line parameters for Linux (e.g. root=XXXX)',13,10
- db 'or @file ( file = param file ) or "empty string" to abort:',13,10,'$'
- abort_tx db 'LOADLIN aborted by user',13,10,'$'
- err_file_notfound_tx db 'Image file not found,',13,10,'$'
- enter_file_tx db 'enter file name of Image:',13,10,'$'
- err_wrong_file_tx db 'not an Image file,',13,10,'$'
- err_wrong_setup_tx db 'Your current configuration needs interception of "setup.S,"',13,10
- db 'but the setup-code in your Image file is *very* old (or wrong)',13,10
- db 'Please use BIOSINTV/REALBIOS or try an other Image file',13,10,'$'
- err_setup_too_long_tx db 'Ooops..., size of "setup.S" has become too long for LOADLIN,',13,10
- db 'please E-mail this condition to lermen@elserv.ffm.fgan.de !',13,10,'$'
- err_kernel_to_big_tx db 'not enough memory below 90000h to load kernel',13,10,'$'
- err_io_tx db 'IO Error during load',13,10,'$'
- insert_floppy_tx db 'Insert floppy disk for loading into RAMDISK',13,10,'$'
- err_cpu_v86_tx db 13,10,'CPU is in V86-mode (may be WINDOWS, EMM386, QEMM, 386MAX, ...)',13,10
- db 'You need pure 386/486 real mode or a VCPI server to boot Linux',13,10
- db 'VCPI is supported by most EMS drivers (if EMS is enabled),',13,10
- db 'but never under MS-WINDOWS (MICROSOFT doesn''t like P0 for users)',13,10
- db 'If loading via VCPI you also MUST have:',13,10
- db ' 1. An interceptable setup-code (Javiers method, see MANUAL.TXT)',13,10
- db ' or DEVICE=BIOSINTV.SYS as the very first command in CONFIG.SYS',13,10
- db ' or create a ',REALBIOS_FILE,' file using the REALBIOS.EXE utility.',13,10
- db ' 2. Identical Physical-to-Virtual mapping for the first 640 Kbytes',13,10,'$'
- err_wrong_cpu_tx db 'You need a 386 CPU at minimum, but you haven''t !',13,10,'$'
- err_comfile_tx db 'error on reading command line response file',13,10,'$'
- option_t_terminate_tx db 13,10,'Option -t set, Linux not loaded',13,10,'$'
- option_t_forced_tx db 13,10,'ERROR detected, Linux not loaded',13,10,'$'
- err_in_config_sys_tx db 13,10,'LOADLIN holding in idle loop (You must reboot)',13,10,'$'
- ;-----------------------------------------------------------------------------
- usage_tx db 13,10
- db 'USAGE:',13,10
- db ' LOADLIN @params',13,10
- db ' LOADLIN [zimage_file] [options] [boot_params]',13,10
- db ' without any params, LOADLIN displays this help message.',13,10
- db ' @params:',13,10
- db ' params is a DOS file containing all other options',13,10
- db ' zimage_file:',13,10
- db ' DOS file name of compressed Linux kernel image',13,10
- db ' options:',13,10
- db ' -v verbose, show information on params and configuration',13,10
- db ' -t test mode, do all but starting Linux, also sets -v',13,10
- db ' -d file debug mode, same as -t, but duplicates output to "file"',13,10
- db ' -rb search for REALBIOS before BIOSINTV',13,10
- db ' -rx don''t check REALBIOS'' ROM-date',13,10
- db " -ja use Javier's method, disable BIOSINTV and REALBIOS.",13,10
- db " -clone ( Please read MANUAL.TXT before using this switch! )",13,10
- db " -oldxd use old /dev/xda,xdb numbering 0xC00,0xC40",13,10
- db " (newer kernels have 0xD00,0xD40)",13,10
- db " -n no translation for root=/dev/...",13,10
- db ' boot_params:',13,10
- db ' root=xxx filesystem to be mounted by Linux as "/"',13,10
- db ' xxx = hex number (e.g. root=201 for /dev/fd1)',13,10
- db ' = /dev/mmmn (e.g. root=/dev/hda2)',13,10
- db ' mmm = fd,hda,hdb,sda,sdb...',13,10
- db ' n = 1..10.. decimal',13,10
- db ' n = 01..0a.. or 0x1..0xa.. or a..f hexnumber',13,10
- db ' ro mount "/" readonly',13,10
- db ' rw mount "/" read/write',13,10
- db ' ramdisk=x install ramdisk of size x Kbytes. If also root=/dev/fdx,',13,10
- db ' then LOADLIN prompts for a floppy (copied into ramdisk)',13,10
- db ' vga=xxx vga mode (e.g. -3..0.., ask, normal, extended)',13,10
- db ' (for more boot params see file PARAMS.DOC)',13,10
- empty_tx db '$'
-
-