wok-next diff gpxe/stuff/patches/prefix.u @ rev 20661

Unification of the patch system
author Aleksej Bobylev <al.bobylev@gmail.com>
date Thu May 10 21:12:00 2018 +0300 (2018-05-10)
parents gpxe/stuff/prefix.u@0ebb1ed44fed
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gpxe/stuff/patches/prefix.u	Thu May 10 21:12:00 2018 +0300
     1.3 @@ -0,0 +1,429 @@
     1.4 +--- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
     1.5 ++++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
     1.6 +@@ -3,6 +3,7 @@
     1.7 + 
     1.8 + 	Authors: Gary Byers (gb@thinguin.org)
     1.9 + 		 Marty Connor (mdc@thinguin.org)
    1.10 ++		 Pascal Bellard (pascal.bellard@slitaz.org)
    1.11 + 
    1.12 + 	This software may be used and distributed according to the terms
    1.13 + 	of the GNU Public License (GPL), incorporated herein by reference.
    1.14 +@@ -50,40 +51,351 @@
    1.15 + 	.arch i386
    1.16 + 	.org	0
    1.17 + 	.section ".prefix", "ax", @progbits
    1.18 +-/* 
    1.19 +-	This is a minimal boot sector.	If anyone tries to execute it (e.g., if
    1.20 +-	a .lilo file is dd'ed to a floppy), print an error message. 
    1.21 +-*/
    1.22 + 
    1.23 +-bootsector: 
    1.24 +-	jmp	$BOOTSEG, $1f	/* reload cs:ip to match relocation addr */
    1.25 +-1:
    1.26 +-	movw	$0x2000, %di		/*  0x2000 is arbitrary value >= length
    1.27 +-					    of bootsect + room for stack */
    1.28 ++	call	here
    1.29 ++here:
    1.30 ++	pop	%ax
    1.31 ++	cmpw	$0x103, %ax		/* COM entry point is cs:0x100 */
    1.32 ++	jne	bootsector
    1.33 ++
    1.34 ++/* We need a real mode stack that won't be stomped on by Etherboot
    1.35 ++   which starts at 0x20000. Choose something that's sufficiently high,
    1.36 ++   but not in DOC territory. Note that we couldn't do this in a real
    1.37 ++   .com program since stack variables are in the same segment as the
    1.38 ++   code and data, but this isn't really a .com program, it just looks
    1.39 ++   like one to make DOS load it into memory. It still has the 64kB
    1.40 ++   limitation of .com files though. */
    1.41 ++#define STACK_SEG	0x7000
    1.42 ++#define STACK_SIZE	0x4000
    1.43 ++	/* Set up temporary stack */ 
    1.44 ++	movw	$STACK_SEG, %ax
    1.45 ++	movw	%ax, %ss
    1.46 ++	movw	$STACK_SIZE, %sp
    1.47 ++
    1.48 ++	/* Calculate segment address of image start */
    1.49 ++	pushw	%cs
    1.50 ++	popw	%ax
    1.51 ++	addw	$(0x100/16), %ax	/* Adjust cs */
    1.52 ++	pushw	%ax
    1.53 ++	jmp	go_setup_code
    1.54 ++
    1.55 ++bootsector:
    1.56 ++	jmp	$BOOTSEG, $go		/* reload cs:ip to match relocation addr */
    1.57 ++go: 
    1.58 ++	movw	$0x2000-12, %di		/* 0x2000 is arbitrary value >= length */
    1.59 ++					/* of bootsect + room for stack + 12 for */
    1.60 ++					/* saved disk parm block */
    1.61 + 
    1.62 + 	movw	$BOOTSEG, %ax
    1.63 + 	movw	%ax,%ds
    1.64 + 	movw	%ax,%es
    1.65 +-
    1.66 +-	cli
    1.67 +-	movw	%ax, %ss		/* put stack at BOOTSEG:0x2000. */
    1.68 ++	movw	%ax,%ss			/* put stack at initial position */
    1.69 + 	movw	%di,%sp
    1.70 +-	sti
    1.71 + 
    1.72 +-	movw	$why_end-why, %cx
    1.73 +-	movw	$why, %si
    1.74 ++/* Many BIOS's default disk parameter tables will not recognize multi-sector
    1.75 ++ * reads beyond the maximum sector number specified in the default diskette
    1.76 ++ * parameter tables - this may mean 7 sectors in some cases.
    1.77 ++ *
    1.78 ++ * Since single sector reads are slow and out of the question, we must take care
    1.79 ++ * of this by creating new parameter tables (for the first disk) in RAM.  We
    1.80 ++ * will set the maximum sector count to 36 - the most we will encounter on an
    1.81 ++ * ED 2.88.  High doesn't hurt.	Low does.
    1.82 ++ *
    1.83 ++ * Segments are as follows: ds=es=ss=cs - BOOTSEG
    1.84 ++ */
    1.85 ++
    1.86 ++	xorw	%cx,%cx
    1.87 ++	movw	%cx,%es			/* access segment 0 */
    1.88 ++	movw	$0x78, %bx		/* 0:bx is parameter table address */
    1.89 ++	pushw	%ds			/* save ds */
    1.90 ++/* 0:bx is parameter table address */
    1.91 ++	ldsw	%es:(%bx),%si		/* loads ds and si */
    1.92 ++
    1.93 ++	movw	%ax,%es			/* ax is BOOTSECT (loaded above) */
    1.94 ++	movb	$6, %cl			/* copy 12 bytes */
    1.95 ++	cld
    1.96 ++	pushw	%di			/* keep a copy for later */
    1.97 ++	rep
    1.98 ++	movsw				/* ds:si is source, es:di is dest */
    1.99 ++	popw	%di
   1.100 ++
   1.101 ++	movb	$36,%es:4(%di)
   1.102 ++
   1.103 ++	movw	%cx,%ds			/* access segment 0 */
   1.104 ++	xchgw	%di,(%bx)
   1.105 ++	movw	%es,%si
   1.106 ++	xchgw	%si,2(%bx)
   1.107 ++	popw	%ds			/* restore ds */
   1.108 ++	movw	%di, dpoff		/* save old parameters */
   1.109 ++	movw	%si, dpseg		/* to restore just before finishing */
   1.110 ++	pushw	%ds
   1.111 ++	popw	%es			/* reload es */
   1.112 ++
   1.113 ++/* Note that es is already set up.  Also cx is 0 from rep movsw above. */
   1.114 ++
   1.115 ++	xorb	%ah,%ah			/* reset FDC */
   1.116 ++	xorb	%dl,%dl
   1.117 ++	int	$0x13
   1.118 ++
   1.119 ++/* Get disk drive parameters, specifically number of sectors/track.
   1.120 ++ *
   1.121 ++ * It seems that there is no BIOS call to get the number of sectors.  Guess
   1.122 ++ * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
   1.123 ++ * 15 if sector 15 can be read.	Otherwise guess 9.
   1.124 ++ */
   1.125 + 
   1.126 +-	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.127 +-	movb	$0x0e, %ah		/* write char, tty mode */
   1.128 +-prloop: 
   1.129 ++	movw	$disksizes, %si		/* table of sizes to try */
   1.130 ++
   1.131 ++probe_loop: 
   1.132 + 	lodsb
   1.133 ++	orb	%al, %al
   1.134 ++	je	got_sectors		/* if all else fails, try 9 */
   1.135 ++	cbtw				/* extend to word */
   1.136 ++	movw	%ax, sectors
   1.137 ++	xchgw	%cx,%ax			/* cx = track and sector */
   1.138 ++	xorw	%dx,%dx			/* drive 0, head 0 */
   1.139 ++	movw	$0x0200, %bx		/* address after boot sector */
   1.140 ++					/*   (512 bytes from origin, es = cs) */
   1.141 ++	movw	$0x0201, %ax		/* service 2, 1 sector */
   1.142 ++	int	$0x13
   1.143 ++	jc	probe_loop		/* try next value */
   1.144 ++
   1.145 ++got_sectors: 
   1.146 ++	movw	$msg1end-msg1, %cx
   1.147 ++	movw	$msg1, %si
   1.148 ++	call	print_str
   1.149 ++
   1.150 ++/* ok, we've written the Loading... message, now we want to load the system */
   1.151 ++
   1.152 ++	movw	$SYSSEG, %ax
   1.153 ++	movw	%ax,%es			/* segment of SYSSEG<<4 */
   1.154 ++	pushw	%es
   1.155 ++	call	read_it
   1.156 ++
   1.157 ++/* This turns off the floppy drive motor, so that we enter the kernel in a
   1.158 ++ * known state, and don't have to worry about it later.
   1.159 ++ */
   1.160 ++	movw	$0x3f2, %dx
   1.161 ++	xorb	%al,%al
   1.162 ++	outb	%al,%dx
   1.163 ++
   1.164 ++	call	print_nl
   1.165 ++	pop	%es			/* = SYSSEG */
   1.166 ++sigok: 
   1.167 ++
   1.168 ++/* Restore original disk parameters */
   1.169 ++	movw	$0x78, %bx
   1.170 ++	movw	dpoff, %di
   1.171 ++	movw	dpseg, %si
   1.172 ++	xorw	%ax,%ax
   1.173 ++	movw	%ax,%ds
   1.174 ++	movw	%di,(%bx)
   1.175 ++	movw	%si,2(%bx)
   1.176 ++
   1.177 ++	/* Everything now loaded.  %es = SYSSEG, so %es:0000 points to
   1.178 ++	 * start of loaded image.
   1.179 ++	 */
   1.180 ++
   1.181 ++	/* Jump to loaded copy */
   1.182 ++	ljmp	$SYSSEG, $run_etherboot
   1.183 ++
   1.184 ++endseg:	.word SYSSEG + _load_size_pgh
   1.185 ++	.section ".zinfo.fixup", "a"	/* Compressor fixup information */
   1.186 ++	.ascii	"SUBW"
   1.187 ++	.long	endseg
   1.188 ++	.long	16
   1.189 ++	.long	0
   1.190 ++	.previous
   1.191 ++	
   1.192 ++/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
   1.193 ++ * boundaries are crossed. We try to load it as fast as possible, loading whole
   1.194 ++ * tracks whenever we can.
   1.195 ++ *
   1.196 ++ * in:	es - starting address segment (normally SYSSEG)
   1.197 ++ */
   1.198 ++read_it: 
   1.199 ++	movw	$0,sread		/* read whole image incl boot sector */
   1.200 ++	movw	%es,%ax
   1.201 ++	testw	$0x0fff, %ax
   1.202 ++die:	jne	die			/* es must be at 64kB boundary */
   1.203 ++	xorw	%bx,%bx			/* bx is starting address within segment */
   1.204 ++rp_read: 
   1.205 ++	movw	%es,%ax
   1.206 ++	movw	%bx,%dx
   1.207 ++	movb	$4, %cl
   1.208 ++	shrw	%cl,%dx			/* bx is always divisible by 16 */
   1.209 ++	addw	%dx,%ax
   1.210 ++	cmpw	syssize, %ax		/* have we loaded all yet? */
   1.211 ++	jb	ok1_read
   1.212 ++	ret
   1.213 ++ok1_read: 
   1.214 ++	movw	sectors, %ax
   1.215 ++	subw	sread, %ax
   1.216 ++	movw	%ax,%cx
   1.217 ++	shlw	$9, %cx			/* 80186 opcode */
   1.218 ++	addw	%bx,%cx
   1.219 ++	jnc	ok2_read
   1.220 ++	je	ok2_read
   1.221 ++	xorw	%ax,%ax
   1.222 ++	subw	%bx,%ax
   1.223 ++	shrw	$9, %ax			/* 80186 opcode */
   1.224 ++ok2_read: 
   1.225 ++	call	read_track
   1.226 ++	movw	%ax,%cx
   1.227 ++	addw	sread, %ax
   1.228 ++	cmpw	sectors, %ax
   1.229 ++	jne	ok3_read
   1.230 ++	movw	$1, %ax
   1.231 ++	subw	head, %ax
   1.232 ++	jne	ok4_read
   1.233 ++	incw	track
   1.234 ++ok4_read: 
   1.235 ++	movw	%ax, head
   1.236 ++	xorw	%ax,%ax
   1.237 ++ok3_read: 
   1.238 ++	movw	%ax, sread
   1.239 ++	shlw	$9, %cx			/* 80186 opcode */
   1.240 ++	addw	%cx,%bx
   1.241 ++	jnc	rp_read
   1.242 ++	movw	%es,%ax
   1.243 ++	addb	$0x10, %ah
   1.244 ++	movw	%ax,%es
   1.245 ++	xorw	%bx,%bx
   1.246 ++	jmp	rp_read
   1.247 ++
   1.248 ++read_track: 
   1.249 ++	pusha				/* 80186 opcode */
   1.250 ++	pushw	%ax
   1.251 ++	pushw	%bx
   1.252 ++	pushw	%bp			/* just in case the BIOS is buggy */
   1.253 ++	movb	$0x2e, %al		/* 0x2e = . */
   1.254 ++	call	print_char
   1.255 ++	popw	%bp
   1.256 ++	popw	%bx
   1.257 ++	popw	%ax
   1.258 ++
   1.259 ++	movw	sread, %cx
   1.260 ++	incw	%cx
   1.261 ++	movb	track, %ch
   1.262 ++	movw	$0x0100, %dx
   1.263 ++	andb	head, %dh
   1.264 ++	movb	$2, %ah
   1.265 ++
   1.266 ++	pushw	%dx			/* save for error dump */
   1.267 ++	pushw	%cx
   1.268 ++	pushw	%bx
   1.269 ++	pushw	%ax
   1.270 ++
   1.271 ++	int	$0x13
   1.272 ++	jc	bad_rt
   1.273 ++	addw	$8, %sp
   1.274 ++	popa				/* 80186 opcode */
   1.275 ++	ret
   1.276 ++
   1.277 ++bad_rt: pushw	%ax			/* save error code */
   1.278 ++	call	print_all		/* ah = error, al = read */
   1.279 ++
   1.280 ++	xorb	%ah,%ah
   1.281 ++	xorb	%dl,%dl
   1.282 ++	int	$0x13
   1.283 ++
   1.284 ++	addw	$10, %sp
   1.285 ++	popa				/* 80186 opcode */
   1.286 ++	jmp	read_track
   1.287 ++
   1.288 ++/* print_all is for debugging purposes.	It will print out all of the registers.
   1.289 ++ * The assumption is that this is called from a routine, with a stack frame like
   1.290 ++ *	dx
   1.291 ++ *	cx
   1.292 ++ *	bx
   1.293 ++ *	ax
   1.294 ++ *	error
   1.295 ++ *	ret <- sp
   1.296 ++ */
   1.297 ++
   1.298 ++print_all: 
   1.299 ++	call	print_nl		/* nl for readability */
   1.300 ++					/* print_nl update ah and bx */
   1.301 ++	movw	$5, %cx			/* error code + 4 registers */
   1.302 ++	movw	%sp,%bp
   1.303 ++
   1.304 ++print_loop: 
   1.305 ++	pushw	%cx			/* save count left */
   1.306 ++
   1.307 ++	cmpb	$5, %cl
   1.308 ++	jae	no_reg			/* see if register name is needed */
   1.309 ++
   1.310 ++	movb	$0x5+0x41-1, %al
   1.311 ++	subb	%cl,%al
   1.312 ++	int	$0x10
   1.313 ++
   1.314 ++	movb	$0x58, %al		/* 'X' */
   1.315 + 	int	$0x10
   1.316 ++
   1.317 ++	movb	$0x3A, %al		/* ':' */
   1.318 ++	int	$0x10
   1.319 ++
   1.320 ++no_reg: 
   1.321 ++	addw	$2, %bp			/* next register */
   1.322 ++	call	print_hex		/* print it */
   1.323 ++	movb	$0x20, %al		/* print a space */
   1.324 ++	int	$0x10
   1.325 ++	popw	%cx
   1.326 ++	loop	print_loop
   1.327 ++					/* nl for readability */
   1.328 ++print_nl: 
   1.329 ++	movb	$0xd, %al		/* CR */
   1.330 ++	call	print_char
   1.331 ++	movb	$0xa, %al		/* LF */
   1.332 ++	jmp	print_char
   1.333 ++
   1.334 ++
   1.335 ++print_str: 
   1.336 ++prloop: 
   1.337 ++	lodsb
   1.338 ++	call	print_char
   1.339 + 	loop	prloop
   1.340 +-freeze: jmp	freeze
   1.341 ++	ret
   1.342 + 
   1.343 +-why:	.ascii	"This image cannot be loaded from a floppy disk.\r\n"
   1.344 +-why_end: 
   1.345 ++/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
   1.346 + 
   1.347 ++print_hex: 
   1.348 ++	movw	(%bp),%dx		/* load word into dx */
   1.349 ++	movb	$4, %cl
   1.350 ++	call	print_2digits
   1.351 ++print_2digits: 
   1.352 ++	call	print_digit
   1.353 ++/* fall through */
   1.354 ++print_digit: 
   1.355 ++	rol	%cl,%dx			/* rotate to use lowest 4 bits */
   1.356 ++	movb	$0x0f, %al		/* mask for nybble */
   1.357 ++	andb	%dl,%al
   1.358 ++	addb	$0x90, %al		/* convert al to ascii hex */
   1.359 ++	daa				/* (four instructions) */
   1.360 ++	adcb	$0x40, %al
   1.361 ++	daa
   1.362 ++print_char:
   1.363 ++	movb	$0x0e, %ah		/* write char, tty mode */
   1.364 ++	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.365 ++	int	$0x10
   1.366 ++	ret
   1.367 ++
   1.368 ++sread:	.word 0				/* sectors read of current track */
   1.369 ++head:	.word 0				/* current head */
   1.370 ++track:	.word 0				/* current track */
   1.371 ++
   1.372 ++sectors: 
   1.373 ++	.word 0
   1.374 ++
   1.375 ++dpseg:	.word 0
   1.376 ++dpoff:	.word 0
   1.377 ++
   1.378 ++disksizes: 
   1.379 ++	.byte 36,18,15,9,0
   1.380 ++
   1.381 ++msg1: 
   1.382 ++	.ascii "Loading ROM image"
   1.383 ++msg1end: 
   1.384 + 
   1.385 + 	.org	497
   1.386 + setup_sects: 
   1.387 +@@ -106,13 +418,6 @@
   1.388 + 
   1.389 + 	.org	512
   1.390 + 
   1.391 +-	.section ".zinfo.fixup", "a"	/* Compressor fixup information */
   1.392 +-	.ascii	"SUBW"
   1.393 +-	.long	syssize
   1.394 +-	.long	16
   1.395 +-	.long	0
   1.396 +-	.previous
   1.397 +-	
   1.398 + /*
   1.399 + 	We're now at the beginning of the second sector of the image -
   1.400 + 	where the setup code goes.
   1.401 +@@ -123,14 +428,18 @@
   1.402 + 	executing the Etherboot image that's loaded at SYSSEG:0 and
   1.403 + 	whose entry point is SYSSEG:0.
   1.404 + */
   1.405 +-setup_code:
   1.406 ++setup_code: 
   1.407 ++	pushw	$(SYSSEG-(PREFIXSIZE/16))
   1.408 + 	/* Etherboot expects to be contiguous in memory once loaded.
   1.409 + 	 * LILO doesn't do this, but since we don't need any
   1.410 + 	 * information that's left in the prefix, it doesn't matter:
   1.411 + 	 * we just have to ensure that %cs:0000 is where the start of
   1.412 + 	 * the Etherboot image *would* be.
   1.413 + 	 */
   1.414 +-	ljmp	$(SYSSEG-(PREFIXSIZE/16)), $run_etherboot
   1.415 ++go_setup_code: 
   1.416 ++	pushw	$run_etherboot
   1.417 ++	/* Calculated lcall to _start with %cs:0000 = image start */
   1.418 ++	lret
   1.419 + 
   1.420 + 
   1.421 + 	.org	PREFIXSIZE
   1.422 +@@ -140,6 +449,10 @@
   1.423 + run_etherboot:
   1.424 + 	call	install
   1.425 + 
   1.426 ++	/* Set up real-mode stack */
   1.427 ++	movw	%bx, %ss
   1.428 ++	movw	$_estack16, %sp
   1.429 ++
   1.430 + 	/* Jump to .text16 segment */
   1.431 + 	pushw	%ax
   1.432 + 	pushw	$1f