File: chain.S

package info (click to toggle)
lilo 1%3A22.2-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,780 kB
  • ctags: 2,725
  • sloc: asm: 8,355; ansic: 7,864; sh: 1,054; perl: 755; makefile: 365
file content (455 lines) | stat: -rw-r--r-- 8,659 bytes parent folder | download
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
;  chain.S  -  LILO boot chainer 
;
; Copyright 1992-1998 Werner Almesberger.
; Copyright 1999-2001 John Coffman.
; All rights reserved.
;
; Licensed under the terms contained in the file 'COPYING' in the 
; source directory.
;

#define REVERSE_DL 1

#if defined(LCF_SOLO_CHAIN) && !defined(DOS_D)

#ifndef DOS_D
#define DOS_D
#endif

#ifndef CHECK
#define CHECK
#endif

#endif		/* LCF_SOLO_CHAIN */

#define LILO_ASM
#include "lilo.h"

#if VERSION_MINOR >= 50
#define DEBUG
#endif

	.text

	.globl	_main
	.org	0

_main:	jmp	start

	
	.org	6

	.ascii	"LILO"
	.word	STAGE_CHAIN
	.word	VERSION

offset:	.word	0
drive:	.byte	0			! drive, 0x80, 0x81
	.byte	0			! head, always zero

hint:	.word	drvmap			! pointer to drive map

ptable:	.blkw	0x20			! partition table to preload

start:
	xor	ax,ax			! set SS:SP to 0:7C00
	mov	ss,ax
	mov	sp,#BOOTSEG*16		! #0x7C00
	mov	bp,sp			! address from BP
	push	cs
	pop	ds			! DS = SETUPSEG
	mov	es,ax
	mov	cx,#SECTOR_SIZE/2
mtmp = SETUPSECS-1			! broken math ...
	mov	si,#mtmp*SECTOR_SIZE
	mov	di,bp			! #0x7C00
	rep
	  movsw
#ifdef DOS_D
#ifdef CHECK
	mov	si,#BOOTSEG*16+0x24	; address of first byte to test

	cmp	byte (bp+0x15),#0xf8		; check media descriptor
	jne	ck_failed

	seg	es
	  lodsb
	cmp	al,#0x80		; check range of device codes
	jb	ck_failed
	cmp	al,#0x8f
	ja	ck_failed

	seg	es
	  lodsb
	or	al,al			; check hi-byte is empty
	jnz	ck_failed

	seg	es
	  lodsb
	cmp	al,#0x29		; I do not know what this byte means
	je	ck_okay
	cmp	al,#0x28		; HPFS marker
	jne	ck_failed

ck_okay:
	lea	si,(si+4)		; address of vol label & fs type
	mov	cx,#11			; volume label (11)
ck_next:
	seg	es
	  lodsb
	or	al,al
	js	ck_failed		; not alphabetic if >= 0x80
	jz	ck_loop			; NUL allowed for HPFS
	cmp	al,#0x20
	jb	ck_failed		; not alphabetic if < SPACE
ck_loop:
	loop	ck_next

	mov	cx,#8			; check Filesystem type
ck_fstype:
	seg	es
	  lodsb
	or	al,al			; not alphabetic if >= 0x80
	js	ck_failed
	cmp	al,#0x20		; not alphabetic if < SPACE
	jb	ck_failed
	loop	ck_fstype

#endif
dos4:
	call	revmap1

	mov	(bp+0x24),dx		! fill in 0x24 and 0x25
	mov	si,offset
#ifdef LCF_M386
	mov	edx,ptable+8(si)
	mov	(bp+0x1C),edx
#else
	mov	dx,ptable+8(si)
	seg	es
	  mov	BOOTSEG*16+0x1C,dx
	mov	dx,ptable+10(si)
	seg	es
	  mov     BOOTSEG*16+0x1E,dx
#endif

#ifdef DEBUG
	mov	si,#update
	jmp	ck_say   
ck_failed:
	mov	si,#no_update
ck_say:
	call	say
#else
ck_failed:
#endif

#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
#if 0
	cmp	al,drive		! boot drive ?
#else
	call	revmap1
	cmp	al,dl
#endif
	jne	noc			! no -> load into scratch area
	xor	ax,ax			! load at 0000:0600
	mov	bx,#PARTS_LOAD
	jmp	loadit

pmend:	call	flush			! flush table
	br	nopp			! and proceed

noc:	mov	ax,ds
	mov	bx,#PARTS_SCR		! scratch area	0000:0800
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
#ifdef DEBUG
	pusha
	mov	al,dl			! dump device code
	call	bout
	mov	si,#msg_load		! say loading
	call	say
	popa
#endif
	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
#ifdef DEBUG
	pusha
	mov	al,dl			! dump device code
	call	bout
	mov	si,#msg_write		! say writing
	call	say
	popa
#endif
	int	0x13			! write ...
	jc	wrfail			! argl
noflush:ret
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

; reverse drive mapping
;	uses AX, SI
;       may update DL
;
revmap1:  mov	dx,drive	; get drive/head pair
revmap:
	mov	si,#drvmap
rev0:	lodsw			; get to, from pair
	or	ax,ax		; test for end
	jz	rev9		; done
	cmp	ah,dl		; booting from "to"
	jne	rev0		; loop if not
	mov	dl,al		; substitute the "from"
rev9:	ret

nopp:
	mov	ax,drvmap		! need to install mapper ?
	or	ax,ax
	jz	noimap			! no -> go on
	call	swap13
noimap:

#if REVERSE_DL
	call	revmap1
#else
	mov	dx,drive		! initialize DX (drive and head)
#endif
	mov	si,offset		! DS:SI and ES:SI point to the partition
	add	si,#PART_TABLE
#ifdef XXX
	mov	ax,ds
	mov	es,ax
	mov	si,#lilosig
	mov	bx,#cmd
	mov	dl,#0xfe
#else
	xor	ax,ax			! set DS and ES to zero
	mov	ds,ax
	mov	es,ax
#endif
	mov	bx,#BOOTSEG*16
	
	mov	ss,ax			! on all processors since the 186
	mov	sp,bx			! these instructions are locked
	
#ifdef LCF_COHERENT
	mov	(si),dl			! yes, put it in the partition table
#endif
	mov	bp,si			! BP==SI flags hard disk boot
	push	ax
	push	bx
	retf


#ifdef XXX
lilosig:.ascii	"LILO"
cmd:	.ascii	"98"
	.byte	0
#endif

#if defined(LCF_REWRITE_TABLE) || defined(DEBUG)

! 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

#ifdef DEBUG
wout:	push	ax
	xchg	ah,al
	call	bout		! write hi-byte
	pop	ax
bout:	push	ax		! save byte
	shr	al,#4		! display upper nibble
	call	nout
	pop	ax
nout:	and	al,#0x0F	! lower nible only
	daa			! smaller conversion routine
	add	al,#0xF0
	adc	al,#0x40	! AL is hex char [0..9A..F]

	push	bx
	mov	ah,#14		! display, tty-style
	xor	bh,bh
	int	0x10
	pop	bx
	ret

msg_swap13:
	.ascii	"Install drive Swapper"
	.byte	13,10,0
msg_load:
	.ascii	" - PT loaded"
	.byte	13,10,0
msg_write:
	.ascii	" - PT written"
	.byte	13,10,0
no_update:
	.ascii	"NO "
update:
	.ascii	"24-25 update has occurred"
	.byte	13,10,0
#endif

swap13: 
#ifdef DEBUG
	mov	si,#msg_swap13
	call	say
#endif
	seg	es		! allocate 1 kB
	dec	word ptr [0x413]
	int	0x12		! get start segment
	shl	ax,#6		! we are running on a 386
	cli			! disable interrupts
	xor	bx,bx		! zero a few registers
	mov	di,bx
	seg	es		! change offset
	xchg	bx,[4*0x13]	! 0x4c
	mov	old13of,bx
	mov	bx,ax		! change segment
	seg	es
	xchg	bx,[4*0x13+2]	! 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
	jmp	new13a		! make space for signature

	.org	new13+6
	.ascii	"LILO"
	.word	STAGE_DRIVE_MAP
	.word	VERSION
	.word	drvmap-new13	! relative pointer to drive map

new13a:
	! 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
	mov	ax,(si) 	! do not depend on DIRECTION flag
	lea	si,(si+2)	! **
	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: