File: chain.S

package info (click to toggle)
lilo 21-4
  • links: PTS
  • area: main
  • in suites: slink
  • size: 812 kB
  • ctags: 895
  • sloc: ansic: 3,420; asm: 2,546; sh: 767; perl: 607; makefile: 193; cpp: 3
file content (255 lines) | stat: -rw-r--r-- 5,315 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
/* 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: