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 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
/* chain.S - LILO boot chainer */
/* Copyright 1992-1998 Werner Almesberger. See file COPYING for details. */
#define LILO_ASM
#include "lilo.h"
.text
.globl _main
.org 0
_main: jmp start
.org 6
.ascii "LILO"
.word STAGE_CHAIN
.word VERSION
offset: .word 0
drive: .byte 0
.byte 0 ! head, always zero
hint: .word drvmap ! pointer to drive map
ptable: .blkw 0x20 ! partition table to preload
start: cli ! set SS:SP to 0:7C00
xor ax,ax
mov ss,ax
mov ax,#0x7c00
mov sp,ax
sti
mov ax,#SETUPSEG ! move boot sector to default location
mov ds,ax
xor ax,ax
mov es,ax
mov cx,#256
mtmp = SETUPSECS-1 ! broken math ...
mov si,#mtmp*512
mov di,#BOOTSEG*16
rep
movsw
#ifdef DOS_D
dos4: seg es
mov byte ptr BOOTSEG*16+0x24,#0x81
#endif
mov cx,#0x20 ! move partition table
mov si,#ptable
mov di,#PART_TABLE
rep
movsw
! mess with the partition table
#if defined(LCF_REWRITE_TABLE) || defined(LCF_READONLY)
mov si,#prtmap ! get partition table change rules
prtclp: lodsw ! bios == 0 indicates end
or al,al
jz pmend ! at end -> quit
cmp al,cache ! already in cache ?
je incache ! yes -> no loading required
push ax ! save table data
call flush ! flush the cache
pop ax
push ax
mov cache,al ! remember drive in cache
cmp al,drive ! boot drive ?
jne noc ! no -> load into scratch area
xor ax,ax ! load at 0000:0600
mov bx,#PARTS_LOAD
jmp loadit
noc: mov ax,ds
mov bx,#PARTS_SCR ! scratch area
loadit: mov es,ax ! set up pointers and remember them
mov ces,ax
mov cbx,bx
mov ax,#0x201 ! load partition table, one sector
mov dx,cache ! drive from cache (DH = 0)
mov cx,#1
int 0x13 ! load it
jc wrfail ! error -> abort
pop ax ! get BIOS and offset
incache:les bx,cbx ! load pointer
add bx,#PART_TABLE_OFFSET ! move to partition table
add bl,ah ! offset is always in [0x1be,0x1fd]
lodsw ! see what we need to do
seg es ! match ?
cmp byte ptr (bx),al
jne nocng ! no -> do not change
seg es ! change
mov byte ptr (bx),ah
mov byte ptr dirty,#1 ! mark as dirty
nocng: br prtclp ! next one
flush: test byte ptr dirty,#1 ! dirty ?
jz noflush ! no -> do not write
mov ax,#0x301 ! write one sector
mov dx,cache ! get the drive
or dl,dl ! nothing cached ?
jz noflush ! no -> do not flush
les bx,cbx ! reload pointer
int 0x13 ! write ...
jc wrfail ! argl
noflush:ret
pmend: call flush ! flush table
br nopp ! and proceed
wrfail: mov si,#failmsg ! complain
call say
mov ax,#FIRSTSEG ! try to restart LILO
jmpi #GO,FIRSTSEG
cache: .byte 0 ! drive, 0 means not cached
.byte 0 ! head, always 0
cbx: .blkw 1
ces: .blkw 1
dirty: .byte 0
#endif
nopp:
mov ax,drvmap ! need to install mapper ?
or ax,ax
jz noimap ! no -> go on
call swap13
noimap:
mov si,offset ! DS:SI and ES:SI point to the partition
add si,#PART_TABLE
mov dx,drive ! initialize DX (drive and head)
xor ax,ax ! set DS and ES to zero
#ifdef XXX
mov ax,ds
mov es,ax
mov si,#lilosig
mov bx,#cmd
mov dl,#0xfe
#else
mov ds,ax
mov es,ax
#endif
mov bp,#0 ! might help some boot problems
mov ax,#0xaa55 ! boot signature (just in case ...)
jmpi #BOOTSEG*16,0 ! start boot sector
#ifdef XXX
lilosig:.ascii "LILO"
cmd: .ascii "98"
.byte 0
#endif
#if defined(LCF_REWRITE_TABLE)
! Display a NUL-terminated string on the console
say: lodsb ! get byte
or al,al ! NUL ?
jz aret ! yes -> done
mov ah,#14 ! display, tty-style
xor bh,bh
int 0x10
jmp say ! next one
aret: ret ! done
failmsg:.ascii "Rewrite error."
.byte 13,10,0
#endif
swap13: seg es ! allocate 1 kB
dec word ptr [0x413]
int 0x12 ! get start segment
mov cl,#6
shl ax,cl
cli ! disable interrupts
xor bx,bx ! zero a few registers
mov di,bx
seg es ! change offset
xchg bx,[0x4c]
mov old13of,bx
mov bx,ax ! change segment
seg es
xchg bx,[0x4e]
mov old13sg,bx
mov es,ax ! move drive swapper
mov si,#new13
mov cx,#new13end-new13
rep
movsb
sti ! enable interrupts
ret ! done
new13: push ax ! save AX (contains function code in AH)
push bp ! need BP to mess with stack
mov bp,sp
! Stack layout:
!
! +8 INT flags
! +6 INT CS
! +4 INT IP
! +2 AX
! BP+0 BP
pushf ! push flags (to act like interrupt)
push si
mov si,#drvmap-new13
mapfl: seg cs ! get next entry
lodsw
or ax,ax ! at end ?
jz nomap ! yes -> do not map
cmp dl,al ! match ?
jne mapfl ! no -> continue
mov dl,ah ! map drive
nomap: pop si ! restore SI
mov 8(bp),ax ! overwrite old flags (to remember mapping)
mov ax,2(bp) ! restore AX
mov bp,(bp) ! restore BP
.byte 0x9a ! CALL FAR
old13of:.word 0
old13sg:.word 0
push bp ! save BP again
mov bp,sp
! New stack layout:
!
! +10 mapping (was flags)
! +8 INT CS
! +6 INT IP
! +4 AX
! +2 obsolete BP
! BP+0 BP
xchg ax,4(bp) ! save AX and get command
pushf ! fix driver number, if necessary
cmp ah,#8 ! do not fix
je done13
cmp ah,#0x15 ! do not fix
je done13
mov ax,10(bp) ! no mapping ?
or ax,ax
jz done13
mov dl,al ! fix mapping
done13: mov ax,4(bp) ! restore AX
pop 10(bp) ! restore flags
pop bp ! get BP
add sp,#4 ! fix SP
iret ! done
drvmap: .blkw DRVMAP_SIZE+1
new13end:
#if defined(LCF_REWRITE_TABLE)
prtmap: .blkw PRTMAP_SIZE*2+1 ! only first word of last entry is read
#endif
theend:
|