1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
/* first.S - LILO first stage boot loader */
/* Copyright 1992-1998 Werner Almesberger. See file COPYING for details. */
#define LILO_ASM
#include "lilo.h"
#ifndef LCF_NO1STDIAG
#define CYL_CHECK
#endif
.text
.globl _main
.org 0
_main: cli ! NT 4 blows up if this is missing
jmp start
.org 6
! Boot device parameters. They are set by the installer.
.ascii "LILO"
.word STAGE_FIRST
.word VERSION
timeout:.word 0 ! input timeout
delay: .word 0 ! boot delay
port: .byte 0 ! COM port (0 = unused, 1 = COM1, etc.)
sparam: .byte 0 ! serial port parameters (0 = unused)
tstamp: .long 0 ! timestamp
d1_cx: .word 0 ! first descriptor sector address
d1_dx: .word 0
d1_al: .byte 0 ! (unused)
d2_cx: .word 0 ! second descriptor sector address
d2_dx: .word 0
d2_al: .byte 0 ! (unused)
dc_cx: .word 0 ! default command-line sector address
dc_dx: .word 0
dc_al: .byte 0 ! (unused)
prompt: .byte 0 ! indicates whether to always enter prompt
! (also used as alignment byte)
ms_len: .word 0 ! initial greeting message
ms_cx: .word 0
ms_dx: .word 0
ms_al: .byte 0 ! (unused)
kt_cx: .word 0 ! keyboard translation table
kt_dx: .word 0
kt_al: .byte 0
d_addr: ! second stage sector addresses
.org CODE_START_1
ext_si: .word 0 ! external interface
ext_es: .word 0
ext_bx: .word 0
ext_dl: .byte 0
start: mov ax,#BOOTSEG ! set DS
mov ds,ax
mov ext_es,es ! copy possible external parameters
mov ext_si,si
mov ext_bx,bx
mov ext_dl,dl
mov ax,#FIRSTSEG ! beam us up ...
mov es,ax
mov cx,#256
sub si,si
sub di,di
cld
rep
movsw
jmpi go,FIRSTSEG
go: cli ! no interrupts
mov ds,ax ! AX is already set
mov es,ax ! (ES may be wrong when restarting)
mov sp,#STACK ! set the stack
mov ax,#STACKSEG
mov ss,ax
sti ! now it is safe
mov al,#0x0d ! gimme a CR ...
call display
mov al,#0x0a ! ... an LF ...
call display
mov al,#0x4c ! ... an 'L' ...
call display
lagain: mov si,#d_addr ! ready to load the second stage loader
mov bx,#SECOND
cld
sload: lodsw ! get CX
mov cx,ax
lodsw ! get DX
mov dx,ax
or ax,cx ! at EOF ?
jz done ! yes -> start it
inc si ! skip the length byte
call cread
jc error ! error -> start over again
add bx,#512 ! next sector
jmp sload
error:
#ifndef LCF_NO1STDIAG
push ax ! display a space
mov al,#32
call display
pop ax
mov al,ah ! display error code
call bout
#endif
xor ax,ax ! reset the FDC
mov dl,al
int 0x13
jmp lagain ! redo from start
done: mov al,#0x49 ! display an 'I'
call display
jmpi 0,SECONDSEG ! start the second stage loader
#ifndef LCF_NO1STDIAG
bout: push ax ! display one byte
shr al,#4
call nout
pop ax
nout: and al,#15 ! display one nibble
add al,#48
cmp al,#58
jb nokay
add al,#7
nokay: ! fall through
#endif
display:xor bh,bh ! display on screen
mov ah,#14
int 0x10
ret
linerr: pop dx ! discard stack contents
pop cx
pop bx
ret ! (carry is already set)
cread: test dl,#LINEAR_FLAG ! linear address ?
jz readsect ! no -> go on
and dl,#0xff-LINEAR_FLAG ! remove flag
!
! Translate the linear address into a sector/track/cylinder address
!
push bx ! BX is used as scratch
push cx ! LSW
push dx ! MSW with drive
mov ah,#8 ! get drive geometry (do not clobber ES:DI)
int 0x13
jc linerr ! error -> quit
mov al,dh ! AL <- #heads-1
pop dx ! get MSW
mov t_drive,dl ! save drive
mov dl,dh ! linear address (high) into DX
xor dh,dh
#ifdef CYL_CHECK
push cx ! compute #cyls-1
xchg ch,cl
rol ch,1
rol ch,1
and ch,#3
mov n_cyl,cx ! save #cyls-1
pop cx
#endif
and cx,#0x3f ! CX <- #secs
mul cl ! AX <- #secs/cyl
add ax,cx
xchg ax,bx
pop ax ! linear address (low) into AX
div bx ! DX <- cylinder, AX <- remaining secs
xchg ax,dx
div cl ! AL <- track, AH <- sector
inc ah
mov t_sector,ah
xchg ax,dx ! AX <- cylinder, DL <- track
mov dh,dl ! set up DX (head:drive)
mov dl,t_drive
#ifdef CYL_CHECK
cmp ax,n_cyl ! valid cylinder number ?
ja linerr3 ! no -> error
#endif
xchg ah,al ! build cylinder number
ror al,1
ror al,1
or al,t_sector
mov cx,ax
pop bx ! restore BX
readsect:
mov ax,#0x201 ! read one sector
int 0x13
ret ! quit, possibly with errors
#ifdef CYL_CHECK
linerr3:pop bx ! pop BX and linear address
xor ax,ax ! zero indicates internal error
stc ! error
ret
n_cyl: .word 0 ! temporary space
#endif
t_drive:.byte 0
t_sector:.byte 0
/* Here are at least 66 bytes of free space. This is reserved for the
partition table and the boot signature. */
theend:
|