home *** CD-ROM | disk | FTP | other *** search
- TESTX = 0
- LOADLIN_VERSION equ '1.6'
-
- ; >>> this is file LOADLIN.ASM
- ;============================================================================
- ; LOADLIN v1.6 (C) 1994..1996 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
- ;
- ;============================================================================
- ;
- ; NOTE:
- ;
- ; This program could not have been written as quickly without
- ; the information found in the source code of F.Coutant's BOOTLIN
- ;
- ; This program contains some modified source code from
- ; my protected mode extender (LDOSX (C) 1991..1994 H.Lermen),
- ; which was written as a fast multitasking alternative
- ; to DJ.Delorie's extender (it runs DJ-GCC compiled binaries under DOS).
- ;
- ; I was too lazy to reprogram the subroutines completely, so,
- ; if You wonder what nonsense they are doing, keep in mind that they
- ; were written for an other purpose.
- ;
- ;============================================================================
- ;
- ; Contributions and bug fixes for 1.5:
- ;
- ;
- ; Javier Achirica <javier@autom.uva.es>
- ;
- ; invented the switch-out-of-setup method (Javier's method),
- ; which makes the BIOSINTV and REALBIOS method superfluous on nearly
- ; all machines. The trick is: let setup run in V86 and intercept
- ; just before going to protected mode.
- ; (Thank you Javier for this very good work).
- ;
- ; Contributions for 1.6:
- ;
- ; Werner Almesberger <almesber@lrc.epfl.ch>
- ;
- ; Werner and me cooperated in realizing high loading of the kernel
- ; and preloading the RAMdisk.
- ; The changes needed in setup.S for both, LILO and LOADLIN,
- ; are a common work of us.
- ; Also the needed kernel patches are the fruits of a very fertile
- ; cooperation. The changes to LILO-1.8 as well as to LOADLIN-1.6
- ; have been developed 'synchroniously' in order to let the whole
- ; Linux community participate on the new boot features.
- ;
- ;============================================================================
-
- name load_linux
- .386
- locals
- jumps
-
- REALBIOS_FILE equ 'C:\REALBIOS.INT'
-
- SIGNATURE = 'SrdH' ; "HdrS"
-
- space4k = 1000h
- space2k = 800h
- space1k = 400h
-
- our_stacksize = space2k
-
- kernel_start_ equ 01000h ; here the kernel must go
- kernel_end equ 09000h
- standard_setup_sects equ 4 ; number of setup sectors, older kernels
- maximum_setup_sects equ (32-1) ; max number of setup sectors for newer kernels
- High_Seg_ equ kernel_end ; here first 512 + 4*512 + n*512 bytes of image must go
- High_Addr_ equ (High_Seg_*16)
-
- setup_intercept_int equ 7fh
-
-
- debug_stop macro marker
- mov ax,0b800h
- mov ds,ax
- mov byte ptr ds:[1],70h
- mov byte ptr ds:[0],marker
- jmp short $
- endm
-
- align_ macro start,val
- org (((($-start)+(val-1))/val)*val)
- endm
-
-
- psp_seg segment at 0 use16
-
- ; -------------PSP Program Segment Prefix----------------------
- org 2h
- PSP_memend_frame dw ?
- org 2ch
- PSP_envir_frame dw ?
- org 80h
- PSP_DTA db ? (100h-80h) dup(?)
- ; -------------------------------------------------------------
- psp_seg ends
-
- code segment para use16
- assume cs:code,ds:psp_seg,es:code
- code_org0 label byte
-
- ; ---------------------------------------------------------------------
- ; Bootsector (512 bytes)
- ; within this BEFORE start of setup:
- ; (may be set by "LOADLIN")
- bootsec label byte
- org 20h
- CL_MAGIC dw ? ;0020 commandline magic number (=0xA33F)
- CL_OFFSET dw ? ;0022 commandline offset
- ; Address of commandline is calculated:
- ; 0x90000 + contents of CL_OFFSET
- ; The command line is parsed by "init/main.c"
- ; Value of NAME=XXXX are put into the environement
- ; and can then be interpreted by the drivers
- ; and /etc/rc. The variabel "root=xxxx" is
- ; interpreted by main directly, "single" is
- ; interpreted by init or simpleinit.
- org 1F1h
- setup_sects db ? ; no. of sectors
- ro_flag dw ? ; =0: root file system should be mounted read-write
- ;<>0: root file system should be mounted readonly
- ; (this will be overwritten by the kernel commandline
- ; options "ro" / "rw")
- ; --------------------------------
- ; within this AFTER setup has run:
- org 0
- curr_curs dw ? ;0000 saved cursor position
- ext_mem_size dw ? ;0002 extended memory size in Kb (from int 0x15)
- org 80h
- hd0_disk_par label byte ;080 hd0-disk-parameter from intvector 0x41
- hd1_disk_par label byte ;090 hd1-disk-parameter from intvector 0x46
-
- ; --------------------------------
- ; within this as loaded from "zImage"
- org 01F4h
- kernel_size dw ? ; size of kernel-part in the image-file
- ; (in 16 byte units, rounded up)
- swap_dev dw ? ; swap device
-
- ram_disk dw ? ;01F8 size of ram-disk (in 1Kb units ) or ZERO
- ; if ram_disk is nonZERO then the kernel
- ; (driver/block/ramdisk.c: rd_load() )
- ; will try to load the contents for the ram-disk
- ; from the "root_dev" which MUST then have the
- ; floppyMAJOR.
- ; The file-system on that floppy must be MINIX
- ; If rd_load() succeeds it sets the root_dev
- ; to the ramdisk for mounting it.
- ;
- ; LOADLIN parses the commandline for the string
- ; "ramdisk=nnn" where nnn is the value for "ram_disk"
- ; after the kernel images has been loaded by LOADLIN
- ; it asks for inserting the floppy.
- ; (NOTE: You may have LOADLIN in A: and root_dev in B:
- ; or vice versa).
-
- vga_mode dw ? ;01FA VGA-Mode
- ; -3 = ask
- ; -2 = Extended VGA
- ; -1 = Normal VGA
- ; 0 = as "0" was pressed
- ; n = as "n" was pressed
- ;
- ; LOADLIN parses the commandline for the string
- ; "vga=nnn" where nnn is the value for "vga_mode"
- ; it also excepts:
- ; "vga=ask","vga=normal",'vga=extended"
-
- root_dev dw ? ;01FC Root Device (high=Major, low=minor)
- ;(this can be overwritten by the kernel commandline
- ; option "root=XXXX")
- bootmagic dw ? ;01FE Bootsector magic (0AA55h)
-
- ; -------------------------------------------------------------------
- ; this area will be used to pass params
- ; from LOADLINX to LOADLIN, if the params file name is @@loadlinx@@ switch
- ;
- ; NOTE: '@@loadlinx@@' or '@@loadliXXXX'
- ; must NOT be used,
- ; if starting LOADLIN without LOADLINX or ULOADLIN
- org 0200h
- params_from_loadlinX label byte
-
-
- ; -------------------------------------------------------------------
- org 0200h
- setup_prog label byte
- ; the setup-program itself
- ; must be started at 9020h:0 !!!
- ; =======
- jmp short start_of_setup
- ; the setup header
- ; (if you have applied the setup.S patch,
- ; or later, if we have it in the standard kernel)
- setup_header_sign dd ?
- setup_header_version dw ?
- setup_realmode_switch dd ?
- start_sys_seg dw ?
- kernel_version dw ?
- ; end of v1.5-header
- ; NOTE: above part of header is compatible
- ; with loadlin-1.5 (header v1.5),
- ; must not change it
-
- type_of_loader db 0 ; = 0, old one (LILO, Loadlin,
- ; Bootlin, SYSLX, bootsect...)
- ; else it is set by the loader:
- ; 0xTV: T=0 for LILO
- ; T=1 for Loadlin
- ; T=2 for bootsect-loader
- ; V = version
- loadflags db 0 ; unused bits =0
- ; (reserved for future development)
- LOADED_HIGH = 1 ; bit within loadflags,
- ; if set, then the kernel is loaded high
- CAN_USE_HEAP = 80h ; if set, the loader also has set heap_end_ptr
- ; to tell how much space behind setup.S
- ; can be used for heap purposes.
- ; Only the loader knows what is free!
- setup_move_size dw 8000h ; size to move, when we (setup) are not
- ; loaded at 0x90000. We will move ourselves
- ; to 0x90000 then just before jumping into
- ; the kernel. However, only the loader
- ; know how much of data behind us also needs
- ; to be loaded.
- code32_start dd 1000h ; here loaders can put a different
- ; start address for 32-bit code.
- ; 0x1000 = default for zImage
- ; 0x100000 = default for big kernel
- ramdisk_image dd 0 ; address of loaded ramdisk image
- ; Here the loader (or kernel generator) puts
- ; the 32-bit address were it loaded the image.
- ; This only will be interpreted by the kernel.
- ramdisk_size dd 0 ; it's size in bytes
- bootsect_kludge dd 0 ; pointing to boot_sect_helper
- heap_end_ptr dw 0 ; pointing to end of setup loacal heap.
- ; Space from here (exclusive) down to
- ; end of setup code can be used by setup
- ; for loacal heap purposes.
- ; ---- end of v2.0 setup-header --------------------
-
- start_of_setup:
- org setup_prog
- db maximum_setup_sects*512 dup(?)
- ; -------------------------------------------------------------
- ; the following layout is private to LOADLIN.EXE :
-
- align_ code_org0,4096
- end_of_setup_buffer label byte
-
- pagedir dd 2 dup(0) ; must be aligned to 4 K
- ; NOTE: we have only 1 (one) pagetable, so we
- ; need only 1 pagedir entry
- ; All current known CPUs (386,486,PENTIUM)
- ; tolerate the garbage behind this,
- ; as long as there is no access > 4MB.
- ; So we may overlap the pagedir with
- ; our code
-
- ; ----------------------------v
- ; the following are the params we have to pass to 32-bit adjustemt code
- pageadjlist_ptr dd (High_Seg_*16) + (pageadjlist-code_org0)
- real_32_startup dd 1000h
- ; ----------------------------^
- ; -------------------------------------------------------------
- align_ code_org0,16
- ; org 02010h
- startup_32:
- ; here we insert the GCC compiled 32-bit code part
- ; it will be our point to start Linux
- ; it's current address is 0x94010
- ; CHECKIT------^^^^^^^ !!!
- IF 1
- INCLUDE PGADJUST.ASM
- ELSE
- INCLUDE PGADJTES.ASM
- ENDIF
- ; -------------------------------------------------------------
-
-
- PSP_frame dw 0 ; our psp
- fhandle dw 0 ; file handle of imagefile
- kernel_start dw 0 ; place were the kernel must at time of
- ; start of setup
- free_mem_start dw 0 ; frame of free memory, starting at the begin of LOADLIN.EXE
- kernel_load_frame dw 0 ; where to load the image
-
- ; The following (High_Seg,High_Addr)
- ; will be set to lower values, if we have setup v2.0
- ; _and_ if 9000 is occupied (W95+DRVSPACE)
- High_Seg dw kernel_end ; here first 512 + 4*512 + n*512 bytes of image must go
- ;spaeter, damit syntaxfehler enstehen: High_Addr dd (High_Seg_*16)
-
- ; ----------------------------v
- ; the following values are cleared on each call to "parscommandline"
- ; (see "clear_to_default")
- parse_switches label byte
- new_setup_size dw 0
- new_vga_mode dw 0
- new_ram_disk dw 0
- cl_pointer dw 0 ; while parsing: aux pointer to command_line
- got_vga_mode db 0
- got_ram_disk db 0
- option_v db 0
- option_t db 0
- option_t_forced db 0
- option_realbios db 0
- option_rx db 0
- option_ja db 0
- option_clone db 0
- option_oldxd db 0
- option_n db 0
- option_nodiskprompt db 0
- option_force db 0
- option_initrd db 0
- option_noheap db 0
- intv_size dw 0
- option_wait dw 0
- option_dskreset db 0
- wrong_realbios db 0
- have_to_force_realmode db 0 ; 0 = is in realmode
- ; 1 = is in V86, have to reenter realmode before
- ; kernel goes to protected mode
- ;
- have_to_intercept_setup db 0; 0 = old method, no interception
- ; 1 = intercept boot/setup.S (Javier's method)
- ; of older kernels just before going to
- ; protected mode.
- ; 2 = same as 1, but intercepting newer kernels
- ; with the setup.dif patch applied.
- ;
-
- debug_file_handle dw 0 ; set to file handle if option -d is set
- logo_out db 0
- kernelversion dd 0 ; binary kernel version, decoded from
- ; the version string as follows:
- ; "1.2.3 (root@...) #4" becomes 01020304h
- ; if string is only 1.2.3 ---> #0 is assumed
- token_count db 0
- end_of_physmem dd 0
- parse_switches_end label byte
- ; ----------------------------^
-
- can_exit_to_dos db 0
- have_VCPI db 0
- have_big_kernel db 0
- have_relocated_setup db 0
- cannot_load_because_of_windows db 0
- print_dots db 0
- cpu_check_status dw 0
- setup_version dw 0 ; =0, if old setup
- ; else contents of setup_header_version
-
-
- ;--------------------higmem stuff -----v
- xms_entry dd 0
- xms_avail dw 0
- xms_handle dw 0
- xms_phys_addr dd 0
-
- pblock struc
- taddr DD ? ; linear address where the block of pages
- ; must be moved to
- tstart DW ? ; index within sources of first entry
- tcount DW ? ; number of entries for taddr in sources
- pblock ends
-
- pages_list struc
- ncount DD ? ; number of entries in 'sources'
- number_of_blocks DD ? ; number of valid blocks-items
- auxbuf DD ? ; address of 4096 bytes auxiliary buffer
- blocks pblock 4 dup(?)
- sources DD 1024 dup (?) ; list of addresses where the block of pages
- ; currently _is_ located
- pages_list ends
-
-
-
- need_mapped_put_buffer db 0
- do_mapped_put_buffer db 0 ; 1, if need high load over pagemap
-
- load_buffer_size dd 0
- heap_ptr dd 0
- heap_end dd 0
- high_heap_ptr dd 0
- heap_max_pages dd 0
-
- move_anywhere dw move_simple ; this routine gets called
- ; when needing to move buffers
-
- high_mem_access db 0 ; = 0, if nothing available
- USING_VCPI = 1
- USING_INT15 = 2
- USING_XMS = 3
-
-
- ;-----------------------------^
- ;NOTE: all uninitialized data has been moved to end of modul
- ; since version 1.4
-
- ; -------------------------------------------------------------
-
-
- _DEALLOCATE_PAGES = 45h;
- _GET_VERSION = 46h;
- _ALLOCATE_RAW_PAGES = 5A01H
- EMM_int = 67h;
-
-
-
- descript struc
- limit dw ?
- base0 dw ?
- base16 db ?
- typbyte db ?
- limit16 db ?
- base24 db ?
- descript ends
-
-
- Gdescript struc
- gateoffs0 dw ?
- gateselector dw ?
- gatenotused db ?
- gatetyppbyte db ?
- gateoffs16 dw ?
- Gdescript ends
-
-
- ; definition of COMMON decriptor types (bit0..4 of descript.typbyte )
- ; (bit 4 of descript.typbyte =0)
- data_d = 10000b ; data segment descriptor
- writable = 00010b ; =1 if write acces allowed to data segment
- expand_down = 00100b ; =1 limit counts down from base
- code_d = 11000b ; code segment
- readable = 00010b ; =1 if code also can be read (cannot be ovwritten)
- conforming = 00100b ; =1 code can be accesses and executed
- ; regardless of it's privilege level
-
- ; definition of SYSTEM decriptor types (bit0..4 of descript.typbyte )
- ; (bit 4 of descript.typbyte =0)
- TSS286_avail_d = 01h
- LDT_d = 02h
- TSS286_busy_d = 03h
- call_gate_d = 04h
- task_gate_d = 05h
- INT286_gate_d = 06h
- TRAP286_gate_d = 07h
- TSS386_avail_d = 09h
- TSS386_busy_d = 0bh
- call386_gate_d = 0ch
- INT386_gate_d = 0eh
- TRAP386_gate_d = 0fh
-
- ; definition of privilege levels (bit5..6 of descript.typbyte )
- p0 = 0 ;┐
- p1 = 1*32 ;├ super visor levels
- p2 = 2*32 ;┘
- puser = 3*32
-
-
- ;definition of granularity ( bits7..8 in descript.limit16 )
- gran_byte = 0
- gran_page = 10000000b ; 4k granularity
- ; for data_selectors:
- data_USE16 = 0
- gran_big = 01000000b ; big segment
- data_USE32 = gran_big ; use 32-bit stack pointer ESP instead of SP
- ; Intel says: relevant only together with expand_down for data_d
- ; But that is WRONG :
- ; BIG segment must be set also if the descriptor is greater 64K
- ; and is used to load SS !
- ; (because SP cannot access behind 64K)
- ;
- ; for code_selectors:
- code_USE32 = 01000000b ; default operand size 32 bit (for code segments)
- code_USE16 = 00000000b ; default operand size 16 bit (for code segments)
-
-
- ; segment present bit (bit7 of descript.typbyte )
- is_present =128
- not_present =0
-
- descriptor macro name,typ,plevel,present,limit,gran,base
- name descript <limit and 0ffffh,base and 0ffffh,low (base shr 16),typ or plevel or present,(limit shr 16) or gran,high (base shr 16)>
- endm
-
-
- ;GDT Global Descriptor Table -------------------------v
- align_ code_org0,16
- gdtnull descript <?> ;0000 never accessable
- gdtvcpi_code descript <?> ;0008
- gdtvcpi2 descript <?> ;0010
- gdtvcpi3 descript <?> ;0018
- descriptor gdt_core,(data_d+writable),p0,is_present,0fffffh,(gran_page+data_USE32),0
- descriptor gdt_code,(code_d+readable),p0,is_present,0ffffh,(gran_byte+code_USE16),High_Addr_
- descriptor gdt_data,(data_d+writable),p0,is_present,0ffffh,(gran_byte+data_USE16),High_Addr_
- descriptor gdt_ldt,LDT_d,p0,is_present,7,gran_byte,(High_Addr_+(ldtnull-code_org0))
- descriptor gdt_tss,TSS286_avail_d,p0,is_present,0ffh,gran_byte,(High_Addr_+(our_tss-code_org0))
- gdtlast descript <?> ; dummy for addressing
-
- g_vcpi_code equ (gdtvcpi_code-gdtnull)
- g_core equ (gdt_core-gdtnull)
- g_code equ (gdt_code-gdtnull)
- g_data equ (gdt_data-gdtnull)
- g_ldt equ (gdt_ldt-gdtnull)
- g_tss equ (gdt_tss-gdtnull)
- ;GDT Global Descriptor Table -------------------------^
-
-
- ;LDT Local Descriptor Table -------------------------v
- ldtnull descript <?> ;0000 never accessable
- ldtlast descript <?> ; dummy for addressing
- ;LDT Local Descriptor Table -------------------------^
-
- ; align_ SYSTEMDATA_,1024
- ;IDT Interrupt Descriptor Table -------------------------v
- idtnull descript 32 dup (<0>)
- idtlast descript <?> ; dummy for addressing
- ;IDT Interrupt Descriptor Table -------------------------^
-
- our_tss dd 128 dup (?) ; our TSS Task State Segment
-
-
- ;params for switching TO protected mode -------------------------v
- ;NOTE: this Data MUST be in LOW_MEM (below 1 Mbyte),
- ; data referenced by this structure
- ; CAN be in memory above 1 Mbyte
- ; On switching to protected mode the server
- ; first loads CR3 (paging base) from "our_CR3".
- ;
- ; value of CR3 to be loaded by server
- our_CR3 dd (High_Addr_+(pagedir-code_org0))
- ; linear address in first Mbyte pointing to
- ; value of GDTR ("our_GDTR") to be loaded by server
- our_GDTRptr dd (High_Addr_+(our_GDTR-code_org0))
- ; linear address in first Mbyte pointing to
- ; value of IDTR ("our_IDTR") to be loaded by server
- our_IDTRptr dd (High_Addr_+(our_IDTR-code_org0))
- ; value of LDTR to be loaded by server
- our_LDTR dw g_ldt
- ; value of TR to be loaded by server
- our_TR dw g_tss
- ; Fword, pointer to code to be started by server
- protected_mode_target DD ?
- DW g_code
- ; belongs to above
- our_GDTR dw (gdtlast-gdtnull)-1 ;limit (byte gran)
- ;linear (not physical) base address of "gdtnull"
- laddr_GDT dd (High_Addr_+(gdtnull-code_org0))
- dw ? ; (just for align "laddr_IDT" to Dword)
- our_IDTR dw (idtlast-idtnull)-1 ;limit (byte gran)
- ;linear (not physical) base address of "Idtnull"
- laddr_IDT dd (High_Addr_+(idtnull-code_org0))
- ;-------------------------------------------------------------------^
-
- server_vcpi_entry df 0 ; this is the address we must call instead of INT67
- ; when in protected mode
- pagedir_template dd (High_Addr_+(page0-code_org0)+3)
-
-
-
- ;=============================================================================
-
-
- DOS_WRITE_STRING = 009h ; Display a '$' terminated string
- DOS_BUFFERED_INPUT = 00Ah ; Read text and store it in a buffer
- DOS_OPEN_FILE = 03Dh ; Open an existing file
- DOS_CREATE_FILE = 03Ch ; create a new file
- DOS_CLOSE_FILE = 03Eh ; Close a file
- DOS_READ_FROM_HANDLE = 03Fh ; Read from DOS file handle
- DOS_WRITE_TO_HANDLE = 040h ; write to DOS file handle
- DOS_TERMINATE_EXE = 04Ch ; Terminate program
-
- DosCall macro function_code
- mov ah,function_code
- int 21h
- endm
- DosInt macro
- int 21h
- endm
-
-
-
- push_ macro r1,r2,r3,r4,r5,r6,r7,r8,rx
- irp parm,<&r1,&r2,&r3,&r4,&r5,&r6,&r7,&r8,&rx>
- ifndef parm
- exitm
- endif
- push parm
- endm
- endm
- pop_ macro r1,r2,r3,r4,r5,r6,r7,r8
- irp parm,<&r8,&r7,&r6,&r5,&r4,&r3,&r2,&r1>
- ifdef parm
- pop parm
- endif
- endm
- endm
-
- pushAD_struc macro prefix
- irp parm,<edi,esi,ebp,esp,ebx,edx,ecx,eax>
- prefix&&parm dd ?
- endm
- endm
-
- pushA_struc macro prefix
- irp parm,<di,si,bp,sp,bx,dx,cx,ax>
- prefix&&parm dw ?
- endm
- endm
-
-
- cpu_86 equ 0
- cpu_286 equ 2
- cpu_386V86 equ 3 ; is >=386, but in virtual 86 mode
- cpu_386GE equ 4 ; >=386
- cpu_386GE_real_paging equ 5
- cpu_type dw 0
-
- cpu_check proc near
- pushf
- cmp option_force,0
- jnz is_force_386GE
- xor ax,ax ;0000 to ax
- push ax
- popf ; try to put that in flags
- pushf
- pop ax ; look at what really went into flags
- and ah,0f0h ; mask off high flag bits
- cmp ah,0f0h
- je is_8086
- mov ax,0f000h
- push ax ; try to set the high bits
- popf
- pushf
- pop ax ; look at actual flags
- and ah,0f0h
- je is_80286
- ; is x86, x >= 3
- ; check for V86 or real-paging -mode
- mov ah,040h ; try to clear IOPL
- push ax
- popf
- pushf
- pop ax
- and ah,030h
- jne is_v86
- cmp option_clone,0
- jnz @@clone
- .386p
- mov eax,cr0 ; normally this would cause a GP(0)-exception
- ; (i386 Programmers Reference Guide, INTEL 1987)
- ; if in V86-mode, but most EMMXXXX drivers
- ; seem to intercept this exception and allow
- ; reading the CR0.
- .386
- or eax,eax
- jz is_v86 ; not a valid CR0, reserved bits are allways set
- ; (this may be not true on a 486 clone such as
- ; the 486DLC, so if you have trouble with
- ; interpreting real mode as V86 use the -clone switch
- ;
- test al,01h ; test PE -bit
- jz is_greater_equal_80386
- is_v86:
- mov ax,cpu_386V86
- cpu_check_exit:
- mov cpu_type,ax
- popf
- ret
- is_8086:
- mov ax,cpu_86
- jmp cpu_check_exit
- is_80286:
- mov ax,cpu_286
- jmp cpu_check_exit
- is_greater_equal_80386:
- test eax,eax ; test PG - bit
- js is_386_real_pageing
- mov ax,cpu_386GE
- jmp cpu_check_exit
- is_force_386GE:
- mov ax,cpu_386GE
- jmp cpu_check_exit
- is_386_real_pageing:
- mov ax,cpu_386GE_real_paging
- jmp cpu_check_exit
-
- @@clone: ; on some 486 clones we have problems with CR0,
- ; so we are looking for EMM, and then
- ; we assume to be in V86, if we have EMM.
- push ds
- xor ax,ax
- mov ds,ax
- mov ds,word ptr ds:[emm_int*4+2]
- mov ax,cpu_386V86
- cmp dword ptr ds:[10+4],'0XXX'
- jne @@cl1
- cmp dword ptr ds:[10],'QMME'
- je @@clex
- cmp dword ptr ds:[10],'XMME'
- je @@clex
- @@cl1:
- mov ax,cpu_386GE
- @@clex:
- pop ds
- jmp cpu_check_exit
-
- cpu_check endp
-
- ;=============================================================================
-
-
- start:
- .8086 ; we are not sure here if on a 368 CPU
- mov cs:PSP_frame,es
- mov ax,cs ; switch the to our stack
- mov ss,ax
- lea sp,stack_top
- mov ds,ax
- mov es,ax
- call clear_uninitialized_data
- mov ds,cs:PSP_frame
- cld
- lea si,PSP_DTA+1
- lea di,comline+1
- mov cl,PSP_DTA
- xor ch,ch
- jcxz start__2
- start__: ; skip leading blanks
- cmp byte ptr [si],' '
- jne start__2
- inc si
- loop start__
- start__2:
- mov comline-1,ch
- mov comline,cl
- inc cx ; get the CR too
- rep movsb ; get the commandline out of psp
-
- push cs
- pop ds
- assume ds:code
- ; from now on we have CS=DS=ES=SS
-
- ; make sure that size byte is correct
- ; ( some DOS versions set only CR .. sometimes )
- lea di,comline+1
- mov al,13
- call strlen
- cmp al,comline
- jnb start_0
- mov comline,al
- start_0:
- mov bx,word ptr comline-1
- xchg bh,bl
- mov comline[bx+1],0 ; replace CR by ZERO
-
- mov logo_out,0
- mov print_dots,0
-
- mov kernel_start,kernel_start_ ; real kernel_start
- mov free_mem_start,cs ;save CS as later freemem
-
- ; now check if (on error) we can exit do DOS
- lea bx,comspec_tx
- call get_env_variable ; we expect COMSPEC= in the environement
- mov al,byte ptr es:[di]
- mov can_exit_to_dos,al
- ; check if we are running under windows
- lea bx,windows_tx
- call get_env_variable ; we expect WINDIR= in the environement
- mov al,byte ptr es:[di]
- mov cannot_load_because_of_windows,al
- push ds
- pop es
-
-
- lea ax,modul_end+15
- shr ax,4
- mov bx,ax
- add ax,High_Seg
- mov es,PSP_frame
- IF 1
- sub ax,es:PSP_memend_frame
- ELSE ;TEST (to simulate an occupied 90000 segment )
- ; sub ax,09400h
- sub ax,05400h
- ENDIF
- jb start_3
- ; we have the 9000 page occupied by some program
- ; and we try to move down the setup code below that
- ; if we later detect an older setup-version,
- ; we must give up, jumping to "err_uppermem".
- neg ax
- add High_Seg,ax
- and High_Seg,0ff00h ; allign on next lower page boundary
- ; (need this for the pagetables)
- call relocate_setup_code
- start_3:
-
- push ds
- pop es ; restore es
-
- mov ax,free_mem_start
- cmp ax,kernel_start
- jnb start_9
- mov ax,kernel_start
- start_9:
- mov kernel_load_frame,ax
-
- mov token_count,-1
- ; check if we are on the right CPU
- mov cpu_check_status,0
- mov option_clone,1 ; avoid reading CR0 before parsing -clone
- call cpu_check
- lea dx,err_wrong_cpu_tx
- cmp ax,cpu_386V86
- jb err_print ; has no 386 or greater at all
-
- .386 ; now we are sure beeing on a 386(and greater) CPU
- cmp can_exit_to_dos,0
- jnz m2
- lea di,comline+1 ; as DOS (stupidly) converts all from
- ; CONFIG.SYS to UPPERCASE, we do TOLOWER
- call tolower
- m2:
- call parscommandline
- call cpu_check ; do it once more, because of option_clone
-
- mov cpu_check_status,2
- call get_default_bios_intvectors
- cmp ax,cpu_386GE
- jb m2_1
- test intv_size,0fffch
- jnz start_continue ; has $BIOSINTV or REALBIOS.INT
- cmp option_t_forced,0
- jnz start_continue
- mov have_to_intercept_setup,1
- jmp start_continue
- m2_1:
- mov cpu_check_status,4
- ; have 386, but are in V86-mode
- call check_VCPI_present
- jz err_wrong_cpu ; has no VCPI-server
- mov have_vcpi,1
- mov cpu_check_status,6
- call check_low_mem_mapping
- jz err_wrong_cpu ; has no identical phys/log mapping
- mov have_to_force_realmode,1
- test intv_size,0fffch
- jnz plain_switch ; has $BIOSINTV or REALBIOS.INT
- ; has no $BIOSINTV driver loaded
- ; but will try to start Linux anyway
- cmp option_t_forced,0
- jnz plain_switch
- mov word ptr cs:intv_buf+(4*15h+2),0
- mov have_to_intercept_setup,1
- plain_switch:
- mov cpu_check_status,8
-
-
- start_continue:
- cmp token_count,0
- jg m3
- jz start_continue_1
- cmp comline,0 ; have we an emtpy string ?
- jnz m3
- start_continue_1:
- mov need_mapped_put_buffer,1 ; | we are doing this to
- call build_buffer_heap ; | get the avail mem for printing
- lea dx,empty_tx
- jmp err_print
-
- ; have file-name at minimum
- ; trying to open it
- m3:
- mov ax,DOS_OPEN_FILE shl 8
- lea dx,image_name
- DosInt
- jnc fileopened
- m4:
- lea dx,err_file_notfound_tx
- m4_:
- call print
- lea dx,enter_commandline_tx
- call print
- call readstring
- cmp comline,0 ; have we an emtpy string ?
- jnz m2
- lea dx,abort_tx
- call print
- jmp err_exit
-
- fileopened:
- mov fhandle,ax
- IFNDEF DEBUG
- ;---------------------------------------
- mov ax,High_Seg ; move us high
- mov es,ax
- push cs
- pop ds
- xor si,si
- xor di,di
- lea cx,modul_end+3
- shr cx,2
- rep movsd
- push es
- pop ds
- ; we have move ourself up
- ; must now change cs
- push ds
- lea ax,back_from_low
- push ax
- retf
- back_from_low:
- mov ax,ds ; switch the stack to top
- mov ss,ax
- lea sp,stack_top
- ENDIF
- ; from now on we have CS=DS=ES=SS=setup_memory
- ;-------------------------------------------
- cmp have_to_force_realmode,0
- je back_from_low_continue
- ; we have to do this once more
- ; because some VCPI-servers rely on an unmovable page0
- call get_VCPI_interface
-
- back_from_low_continue:
- ; first look if it is really an image
- mov bx,fhandle
- mov ecx,512
- mov di,cs
- movzx edi,di
- shl edi,4
- call read_handle ; read the bootsector
- jnc have_bootsect
- fileopened_wrong:
- DosCall DOS_CLOSE_FILE
- lea dx,err_wrong_file_tx
- jmp m4_
- err_wrong_setup:
- DosCall DOS_CLOSE_FILE
- lea dx,err_wrong_setup_tx
- jmp m4_
- err_setup_too_long:
- DosCall DOS_CLOSE_FILE
- lea dx,err_setup_too_long_tx
- jmp m4_
-
- have_bootsect:
- cmp ax,cx
- jne fileopened_wrong
- cmp bootmagic,0AA55h
- jne fileopened_wrong
- ; ok, now get the setup part
- mov di,cs
- lea bx,setup_prog
- shr bx,4
- add di,bx
- mov bx,fhandle
- xor ecx,ecx
- mov ch,setup_sects
- shl cx,1
- jnz new_bootsect
- mov ch,2*standard_setup_sects
- new_bootsect:
- cmp cx,maximum_setup_sects*512
- ja err_setup_too_long
- mov new_setup_size,cx
- movzx edi,di
- shl edi,4
- call read_handle ; read setup
- jc fileopened_wrong
- cmp ax,cx
- jne fileopened_wrong
- call get_setup_version
- cmp setup_version,0201h ; do we have to set setup heap ?
- jb new_bootsect_3 ; no
- cmp option_noheap,0 ; yes, but is it disabled ?
- jnz new_bootsect_3 ; yes
- or loadflags,CAN_USE_HEAP ;no
- mov heap_end_ptr,(end_of_setup_buffer-setup_prog)
- new_bootsect_3:
-
- ; if we have setup-code not at 9000
- ; we have to check for setup-version >= 2.0
- cmp High_seg,High_seg_
- je have_setup_3 ; no need for version 2.0
- cmp word ptr setup_version,0200h
- jb err_uppermem ; we can't continue
- ; ok, we set the correct move size
- lea ax,modul_end
- mov setup_move_size,ax
- have_setup_3:
- mov ax,High_Seg
- sub ax,kernel_load_frame
- movzx eax,ax
- shl eax,4
- mov load_buffer_size,eax
-
- ; if we have setup > 2.0, we set our loader version
- cmp setup_version,0200h
- jb have_setup_4
-
- ;@@@@@@@@@@@@@@@@@@@@@
- ; well here the new tricky loadling stuff is prepared
-
- mov type_of_loader,10h ; our loader type + version
- ; we tell setup not to start the kernel,
- ; but our special 32-bit page-adjust-routine
- mov cs:code32_start,(High_Seg_*16) + (startup_32-code_org0)
- ; we tell 'read_handle' to use mapped move
- mov cs:need_mapped_put_buffer,1
- ; we build the two heaps, low and high
- ; for this we need to align the low to page boundary
- ; align the kernel_load_frame to page boundary
- mov ax,kernel_load_frame
- add ax,0ffh
- mov al,0
- mov kernel_load_frame,ax
- mov ax,High_Seg
- sub ax,kernel_load_frame
- movzx eax,ax
- shl eax,4
- mov load_buffer_size,eax
- call build_buffer_heap
-
- mov edi,01000h ;the address the image must go
- mov cs:real_32_startup,edi ; were the kernel gets started
- ; we now determin what kind of zImage we have
- test cs:loadflags,LOADED_HIGH
- jz must_start_low
- mov have_big_kernel,1
- mov edi,0100000h ;the address the image must go
- mov cs:real_32_startup,edi ; were the kernel gets started
- must_start_low:
- ; even if the image starts low,
- ; we use the 'high load' routines,
- ; so we force this bit in loadflags
- or cs:loadflags,LOADED_HIGH
- ; NOTE: needing EDI from above for open_new_mapped_block
- call open_new_mapped_block ; open the first block
- ;@@@@@@@@@@@@@@@@@@@@@
-
- have_setup_4:
- cmp have_to_intercept_setup,0
- jz dont_patch
- cmp dword ptr ds:setup_header_sign,SIGNATURE
- jnz not_signed
- mov have_to_intercept_setup,2
- mov word ptr ds:setup_realmode_switch,offset real_switch
- mov ax,High_Seg
- mov word ptr ds:setup_realmode_switch+2,ax
- mov ax,kernel_load_frame
- mov word ptr ds:start_sys_seg,ax
- jmp dont_patch
- not_signed:
- xor di,di
- mov cx,new_setup_size
- mov al,0FAh ; cli
- cld
- keep_searching:
- repnz scasb
- jcxz err_wrong_setup
- cmp dword ptr [di],70E680B0h ; mov al,80h
- ; out 70h,al
- jnz keep_searching
- mov byte ptr [di-1],0CDh ; int op code
- mov byte ptr [di],setup_intercept_int ; int number
- mov word ptr [di+1],4444h ; inc sp adjust stack
- ; inc sp (discard flags)
- mov byte ptr [di+3],90h ; nop
- dont_patch:
- ; we convert the kernel version string
- ; to a binary number
- xor eax,eax
- cmp have_to_intercept_setup,2
- jne dont_patch_
- call get_kernel_version
- dont_patch_:
- mov kernelversion,eax
- call handle_kernel_specifics
- ; ok, now check the size of the kernel
- movzx eax,kernel_size
- shl eax,4
- cmp eax,load_buffer_size
- jb have_space
- lea dx,err_kernel_to_big_tx
- cmp option_t,0
- je err_print
-
- have_space:
-
- ; now we update the params
- cmp command_line,0
- jz no_comline
- mov CL_MAGIC,0A33Fh
- lea ax,command_line
- mov CL_OFFSET,ax
- mov si,cl_pointer
- mov byte ptr [si-1],0 ;delete the last blank
-
-
- no_comline:
- ; check for ramdisk
- cmp got_ram_disk,0
- jz no_change_on_ramdisk
- mov ax,new_ram_disk
- mov ram_disk,ax
- no_change_on_ramdisk:
- ; check for vga
- cmp got_vga_mode,0
- jz no_change_on_vga
- mov ax,new_vga_mode
- mov vga_mode,ax
-
- no_change_on_vga:
-
- cmp cannot_load_because_of_windows,0
- jz no_windows
- call force_error_verbose
- no_windows:
-
- ; check for -v option
- cmp option_v,0
- jz no_option_v
- ; option -v (verbose) is set
- ; print some information
- call print_verbose
-
- no_option_v:
- ; check for -t option
- cmp option_t,0
- jz no_option_t
- DosCall DOS_CLOSE_FILE
- lea dx,option_t_terminate_tx
- cmp option_t_forced,0
- jz no_option_t_forced
- lea dx,option_t_forced_tx
- no_option_t_forced:
- call print
- jmp err_exit
-
- no_option_t:
- ; start of critical section
- ; =========================
- call close_debug_file
-
- ; now loading the kernel
- mov bx,fhandle
- movzx ecx,kernel_size
- shl ecx,4
- mov di,kernel_load_frame
- movzx edi,di
- shl edi,4
- mov print_dots,2
- call read_handle ; read the kernel
- call print_crlf
- mov print_dots,0
- call print_crlf
- jc err_io
- add eax,15
- and al,0f0h
- cmp eax,ecx
- jnz fileopened_wrong
- ; ok, all is read into memory
- DosCall DOS_CLOSE_FILE
-
- cmp ram_disk,0 ; have we a ramdisk
- jz no_ram_disk
- cmp option_nodiskprompt,0;
- jnz no_ram_disk
- ;we must prompt for insertion of floppy
- lea dx,insert_floppy_tx
- call print
- call readstring ; just to wait for prompt
- no_ram_disk:
- ; now we try to load the initrd ramdisk-image
- call load_initrd
- ; now we clean up all entries in the page adjust list
- call final_page_adjust_list_handling
- ; that's it
-
- ; here we handle -wait and -dskreset
- ; These option are to avoid outstanding disk-IRQs
- ; happen, when Linux tries to detect the hardware.
- ; In most cases we will not need this.
- call wait_and_reset_dsk
-
- cli
- ___go:
- cmp have_to_intercept_setup,1
- ja ___go_switch
- je ___go_skip_move
- call move_kernel_down
- ___go_skip_move:
- cmp have_to_intercept_setup,1
- jne ___go_switch
- xor ax,ax
- mov ds,ax
- mov word ptr ds:[4*setup_intercept_int],offset real_switch
- mov word ptr ds:[4*setup_intercept_int+2],cs
- ___go_switch:
- mov ax,cs:High_Seg
- mov ds,ax
- mov es,ax
-
- cmp have_to_intercept_setup,0
- ja ___go_continue
- call switch_to_protected_mode_and_return_in_386realmode
-
- ___go_continue:
- call restore_bios_default_vectors
- lea bx,setup_prog
- shr bx,4
- mov ax,High_Seg
- add ax,bx
- lea sp,setup_stack_top ; separate stack during
- ; setup and real_switch
- push ax
- push 0
-
- retf ; and now it's the job of setup
- ; but NOTE:
- ; on have_to_force_realmode >0 setup calls real_switch
-
- setup_own_stack df 0
-
-
- real_switch proc far
- ; NOTE: we have to preserve ALL registers !
- ; to avoid conflicts with future kernels
- cli
- push_ ds,es,fs,gs
- pushad
- mov al,80h
- out [70h],al
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov word ptr setup_own_stack+4,ss
- mov dword ptr setup_own_stack,esp
- ; Ok,ok, today setup has our stack (no need to switch)
- mov ss,ax ; ... but we want to be sure for the future,
- lea sp,stack_top ; so we switch to our stack
- cmp have_to_intercept_setup,2 ; have we to move the kernel down ?
- je @@3 ; no, setup will do it (knows the location of the image)
- ; yes, we have patched in the intercept code,
- ; so the kernel expects the kernel at 10000h
- call move_kernel_down
- @@3:
- call switch_to_protected_mode_and_return_in_386realmode
- lss esp,cs:setup_own_stack ; restore setup's stack
- popad
- pop_ ds,es,fs,gs
- retf
- real_switch endp
-
- ;=============================================================================
-
-
- move_kernel_down proc near
- ; is the kernel at its right place ?
- cli
- mov ax,kernel_start
- cmp kernel_load_frame,ax
- je short @@ex ; yes
- ; no, must move it down
- push_ ds,es
- cld
- mgran = 08000h
- mov bp,mgran shr 4
- mov ax,kernel_size
- mov bx,kernel_start
- mov dx,kernel_load_frame
- @@loop:
- mov cx,mgran shr 2
- mov ds,dx
- mov es,bx
- xor si,si
- xor di,di
- rep movsd
- add bx,bp
- add dx,bp
- sub ax,bp
- cmp ax,bp
- ja @@loop
- mov cx,ax
- shl cx,2
- mov ds,dx
- mov es,bx
- xor si,si
- xor di,di
- rep movsd
-
- pop_ ds,es
- mov ax,kernel_start
- mov kernel_load_frame,ax
- @@ex:
- ret
- move_kernel_down endp
-
-
- err_wrong_cpu:
- lea dx,err_cpu_v86_tx
- err_print:
- cmp token_count,0
- jz err_print_1
- jg err_print_2
- cmp word ptr comline-1,0 ; have we an command line
- jnz err_print_2 ; yes
- ; no, print help and status
- err_print_1:
- push dx
- lea dx,usage_tx
- call print
- pop dx
- err_print_2:
- call print
- cmp cpu_type,cpu_386V86
- jb err_exit
- call print_verbose_stat
- jmp err_exit
- err_io:
- lea dx,err_io_tx
- call print
- jmp err_exit
-
- err_uppermem:
- lea dx,err_uppermem_tx
- call print
- err_exit:
- cmp cs:can_exit_to_dos,0
- jz idle
- mov al,1
- exit_to_dos:
- call free_extended_memory
- call close_debug_file
- DosCall DOS_TERMINATE_EXE
- idle:
- lea dx,err_in_config_sys_tx
- call print
- call close_debug_file
- idle_:
- sti
- jmp idle_
-
- real_print proc near
- ; input: DX = offset of string within CODE
- .8086
- push ds
- push cs
- pop ds
- push_ bx,cx,si
- mov si,dx
- cld
- xor ax,ax
- @@loop:
- lodsb
- test ax,ax
- jz @@ok
- cmp al,'$'
- jnz @@loop
- @@ok:
- dec si
- sub si,dx
- jz @@null
- mov cx,si
- mov bx,1
- DosCall DOS_WRITE_TO_HANDLE
- cmp debug_file_handle,0
- jz @@ex
- mov bx,debug_file_handle
- DosCall DOS_WRITE_TO_HANDLE
- @@null:
- @@ex:
- pop_ bx,cx,si
- pop ds
- ret
- .386
- real_print endp
-
- print proc near
- cmp cs:logo_out,0
- jnz @@ex
- mov cs:logo_out,1
- push_ ax,dx
- lea dx,logo_tx
- call real_print
- pop_ ax,dx
- @@ex:
- call real_print
- ret
- print endp
-
-
- print_crlf proc near
- pushf
- push ax
- push dx
- lea dx,@@crlf
- call print
- pop dx
- pop ax
- popf
- ret
- @@crlf db 13,10,'$'
- print_crlf endp
-
- print_dot proc near
- pushf
- cmp cs:print_dots,1
- jb @@ex
- push ax
- push dx
- lea dx,@@dot_tx
- je @@1
- lea dx,@@start_tx
- dec cs:print_dots
- cmp cs:print_dots,1
- jbe @@1
- lea dx,@@start_tx_2
- dec cs:print_dots
- @@1:
- call print
- pop dx
- pop ax
- @@ex:
- popf
- ret
- @@start_tx_2 db 13,10,'Now reading INITRD:'
- @@start_tx db 13,10,'LOADING'
- @@dot_tx db '.$'
- print_dot endp
-
-
- granularity = 01000h
-
- read_handle proc near
- ; input:
- ; BX= handle
- ; ECX= count
- ; EDI= linear destination address
- ; output:
- ; CARRY =1 , then read-error
- ; EAX= number of bytes transferred (even on CARRY=1)
- ;
- push ds
- push esi
- push dx
- push ecx
- push cs
- pop ds ; target seg = IO_buffer
- lea dx,aligned_auxbuff ; target off = IO_buffer
- mov esi,ecx
- mov ecx,granularity
- jmp @@start
- @@next:
- DosCall DOS_READ_FROM_HANDLE
- call print_dot
- jc @@err
- call put_buffer
- cmp ax,cx
- jne @@eof
- sub esi,ecx
- add edi,granularity
- @@start:
- cmp esi,ecx
- ja @@next
- mov cx,si
- DosCall DOS_READ_FROM_HANDLE
- call print_dot
- jc @@err
- call put_buffer
- @@eof:
- movzx eax,ax
- sub esi,eax
- pop ecx
- mov eax,ecx
- sub eax,esi
- clc
- @@ex:
- pop dx
- pop esi
- pop ds
- ret
- @@err:
- pop ecx
- mov eax,ecx
- sub eax,esi
- stc
- jmp @@ex
- read_handle endp
-
-
- clear_to_default proc near
- push_ ax,di,es
- call close_debug_file
- push cs
- pop es
- xor ax,ax
- mov cx,parse_switches_end-parse_switches
- lea di,parse_switches
- cld
- rep stosb
- pop_ ax,di,es
- ret
- clear_to_default endp
-
-
- ;=============================================================================
-
- INCLUDE LOADLINI.ASM
- INCLUDE LOADLINJ.ASM
- INCLUDE LOADLINM.ASM
-
- ;=============================================================================
-
- ; -------------------------------------------------------------
- clear_uninitialized_data proc near
- .8086 ; we need to have clean 8086 code,
- ; because we don't yet know on which machine we are
- push_ es,ax,cx,di
- xor ax,ax
- lea di,uninitialized_data_start
- mov cx,(uninitialized_data_stop-uninitialized_data_start)/2
- cld
- rep stosw
- call preset_pagedir_from_template
- les ax,@@aux
- mov word ptr pageadjlist.auxbuf,ax
- mov word ptr pageadjlist.auxbuf+2,es
- pop_ es,ax,cx,di
- ret
- .386
- @@aux dd ((High_Seg_*16) + (aligned_auxbuff-code_org0))
- clear_uninitialized_data endp
-
- preset_pagedir_from_template proc near
- mov ax,word ptr pagedir_template
- mov word ptr pagedir,ax
- mov ax,word ptr pagedir_template+2
- mov word ptr pagedir+2,ax
- ret
- preset_pagedir_from_template endp
-
- ;------------------------------------------------------------------------
- ; Here we expect the realy end of any _preset_ data in the .EXE.
- ; Below we have _uninitialized_ data, that will not appear in the binary.
- ; We put the LOADLIN >= 1.6 Magic and suffix-structure here:
- align dword
- dd 0 ; relative offset within file to previous suffix
- ; (e.g the size of the appended part)
- dd 0 ; flags, indicating what kind of appended
- ; file we have
- db 0 ; suffix level, 0= no further suffix
- db 'Loadlin-',LOADLIN_VERSION ; exactly 11 bytes !!!
- ;------------------------------------------------------------------------
-
-
- ; align dword ; NOTE: this is align from above !
- ; if we realign it here, we may get the
- ; suffix above corrupted, because it then isn't
- ; the last part of the executable (.EXE)
- db space1k dup(?)
- setup_stack_top label byte
- db space1k dup(?)
- stack_top label byte
-
-
- uninitialized_data_start label byte
-
- db ? ; belongs to comline
- comline db 128 dup(?) ; copied from PSP_DTA
- db 2*1024-128 dup(?) ; extended commandline
- comline_end label byte
- image_name db 80 dup(?)
- aux_token db 80 dup(?)
- rdimage_name db 80 dup(?)
- command_line db space2k dup(?) ; kernel accepts maximum of 2Kb
-
-
- ; -------------------------------v
- ; this is for 32-bit code
- pageadjlist pages_list <?>
- ; -------------------------------^
-
- ; -------------------------------v
- ; this buffer is for the "default bios interruptvectors"
- ; as is set from the BIOS,
- ; Its contents are delivered by the BIOSINTV.SYS device driver
- ; (must be AT TOP of config.sys).
- ; Or from the REALBIOS.INT file.
- ; We need this after returning from V86-mode
- ; because NOTHING is valid any more but the ROM-BIOS
- ; (and LOADLIN of cause)
- ;
- intv_buf dd 128 dup(?) ; intvector 0:0
- dd 128 dup(?)
- bios_data db 256 dup(?) ; BIOS-data 40:0
- dummy_dos_data db (256-4-16-2) dup(?) ; (DOS-data 50:0, not valid at boot tome
- real_bios_int15 dw ? ; result of int15 at time of realbios
- real_bios_magic dw ? ; must be 0a5a5h for post alpha-release
- reset_jmpop db ? ; TOP BIOS FFFF:0
- reset_entry dd ?
- biosdate db 9 dup(?)
- machineid db ?
- db ?
- masterIMR db ? ; port 21
- slaveIMR db ? ; port A1
- bios_scratch db 1024 dup(?) ; scratch 9FC0:0
- realbios_end label byte
- ; -------------------------------^
-
- ; -------------------------------v
- align_ code_org0,4096
- aligned_auxbuff dd 1024 dup(?) ; must be aligned to 4 K
- page0 dd 1024 dup(?) ; must be aligned to 4 K
- ; -------------------------------^
-
-
- uninitialized_data_stop label byte
- ; -------------------------------------------------------------
-
-
- modul_end:
-
- code ends
-
- end start