wok rev 955

Add gPXE
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Jun 27 20:38:59 2008 +0000 (2008-06-27)
parents 0ae8330553fc
children 7ce662304f43
files gpxe/receipt gpxe/stuff/default_boot.u gpxe/stuff/prefix.u
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gpxe/receipt	Fri Jun 27 20:38:59 2008 +0000
     1.3 @@ -0,0 +1,27 @@
     1.4 +# SliTaz package receipt.
     1.5 +
     1.6 +PACKAGE="gpxe"
     1.7 +VERSION="0.9.3"
     1.8 +CATEGORY="system-tools"
     1.9 +SHORT_DESC="Ethernet bootloader."
    1.10 +MAINTAINER="pascal.bellard@slitaz.org"
    1.11 +TARBALL="$PACKAGE-$VERSION.tar.bz2"
    1.12 +WEB_SITE="http://www.etherboot.org/"
    1.13 +WGET_URL="http://kernel.org/pub/software/utils/boot/$PACKAGE/$TARBALL"
    1.14 +
    1.15 +# Rules to configure and make the package.
    1.16 +compile_rules()
    1.17 +{
    1.18 +	cd $src/src
    1.19 +	for i in prefix.u default_boot.u; do
    1.20 +		patch -p2 < ../../stuff/$i || return 1
    1.21 +	done
    1.22 +	make bin/gpxe.lkrn bin/undionly.kpxe
    1.23 +}
    1.24 +
    1.25 +# Rules to gen a SliTaz package suitable for Tazpkg.
    1.26 +genpkg_rules()
    1.27 +{
    1.28 +	mkdir -p $fs/usr/share/boot
    1.29 +	cp $src/src/bin/gpxe.lkrn $fs/usr/share/boot/gpxe
    1.30 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/gpxe/stuff/default_boot.u	Fri Jun 27 20:38:59 2008 +0000
     2.3 @@ -0,0 +1,12 @@
     2.4 +--- gpxe-0.9.3/src/usr/autoboot.c
     2.5 ++++ gpxe-0.9.3/src/usr/autoboot.c
     2.6 +@@ -150,2 +150,3 @@
     2.7 + 			find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
     2.8 ++default_boot:
     2.9 + 	if ( buf[0] ) {
    2.10 +@@ -164,3 +165,4 @@
    2.11 + 	printf ( "No filename or root path specified\n" );
    2.12 +-	return -ENOENT;
    2.13 ++	strcpy ( buf, "http://boot.slitaz.org/gpxe" );
    2.14 ++	goto default_boot;
    2.15 + }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gpxe/stuff/prefix.u	Fri Jun 27 20:38:59 2008 +0000
     3.3 @@ -0,0 +1,393 @@
     3.4 +--- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
     3.5 ++++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
     3.6 +@@ -50,40 +50,343 @@
     3.7 + 	.arch i386
     3.8 + 	.org	0
     3.9 + 	.section ".prefix", "ax", @progbits
    3.10 +-/* 
    3.11 +-	This is a minimal boot sector.	If anyone tries to execute it (e.g., if
    3.12 +-	a .lilo file is dd'ed to a floppy), print an error message. 
    3.13 +-*/
    3.14 + 
    3.15 +-bootsector: 
    3.16 +-	jmp	$BOOTSEG, $1f	/* reload cs:ip to match relocation addr */
    3.17 +-1:
    3.18 +-	movw	$0x2000, %di		/*  0x2000 is arbitrary value >= length
    3.19 +-					    of bootsect + room for stack */
    3.20 ++	call	here
    3.21 ++here:
    3.22 ++	pop	%ax
    3.23 ++	cmpw	$0x103, %ax		/* COM entry point is cs:0x100 */
    3.24 ++	jne	bootsector
    3.25 ++
    3.26 ++/* We need a real mode stack that won't be stomped on by Etherboot
    3.27 ++   which starts at 0x20000. Choose something that's sufficiently high,
    3.28 ++   but not in DOC territory. Note that we couldn't do this in a real
    3.29 ++   .com program since stack variables are in the same segment as the
    3.30 ++   code and data, but this isn't really a .com program, it just looks
    3.31 ++   like one to make DOS load it into memory. It still has the 64kB
    3.32 ++   limitation of .com files though. */
    3.33 ++#define STACK_SEG	0x7000
    3.34 ++#define STACK_SIZE	0x4000
    3.35 ++	/* Set up temporary stack */ 
    3.36 ++	movw	$STACK_SEG, %ax
    3.37 ++	movw	%ax, %ss
    3.38 ++	movw	$STACK_SIZE, %sp
    3.39 ++
    3.40 ++	/* Calculate segment address of image start */
    3.41 ++	pushw	%cs
    3.42 ++	popw	%ax
    3.43 ++	addw	$(0x100/16), %ax
    3.44 ++	jmp	go_setup_code
    3.45 ++
    3.46 ++bootsector:
    3.47 ++	jmp	$BOOTSEG, $go		/* reload cs:ip to match relocation addr */
    3.48 ++go: 
    3.49 ++	movw	$0x2000-12, %di		/* 0x2000 is arbitrary value >= length */
    3.50 ++					/* of bootsect + room for stack + 12 for */
    3.51 ++					/* saved disk parm block */
    3.52 + 
    3.53 + 	movw	$BOOTSEG, %ax
    3.54 + 	movw	%ax,%ds
    3.55 + 	movw	%ax,%es
    3.56 +-
    3.57 +-	cli
    3.58 +-	movw	%ax, %ss		/* put stack at BOOTSEG:0x2000. */
    3.59 ++	movw	%ax,%ss			/* put stack at initial position */
    3.60 + 	movw	%di,%sp
    3.61 +-	sti
    3.62 + 
    3.63 +-	movw	$why_end-why, %cx
    3.64 +-	movw	$why, %si
    3.65 ++/* Many BIOS's default disk parameter tables will not recognize multi-sector
    3.66 ++ * reads beyond the maximum sector number specified in the default diskette
    3.67 ++ * parameter tables - this may mean 7 sectors in some cases.
    3.68 ++ *
    3.69 ++ * Since single sector reads are slow and out of the question, we must take care
    3.70 ++ * of this by creating new parameter tables (for the first disk) in RAM.  We
    3.71 ++ * will set the maximum sector count to 36 - the most we will encounter on an
    3.72 ++ * ED 2.88.  High doesn't hurt.	Low does.
    3.73 ++ *
    3.74 ++ * Segments are as follows: ds=es=ss=cs - BOOTSEG
    3.75 ++ */
    3.76 + 
    3.77 +-	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
    3.78 +-	movb	$0x0e, %ah		/* write char, tty mode */
    3.79 +-prloop: 
    3.80 ++	xorw	%cx,%cx
    3.81 ++	movw	%cx,%es			/* access segment 0 */
    3.82 ++	movw	$0x78, %bx		/* 0:bx is parameter table address */
    3.83 ++	pushw	%ds			/* save ds */
    3.84 ++/* 0:bx is parameter table address */
    3.85 ++	ldsw	%es:(%bx),%si		/* loads ds and si */
    3.86 ++
    3.87 ++	movw	%ax,%es			/* ax is BOOTSECT (loaded above) */
    3.88 ++	movb	$6, %cl			/* copy 12 bytes */
    3.89 ++	cld
    3.90 ++	pushw	%di			/* keep a copy for later */
    3.91 ++	rep
    3.92 ++	movsw				/* ds:si is source, es:di is dest */
    3.93 ++	popw	%di
    3.94 ++
    3.95 ++	movb	$36,%es:4(%di)
    3.96 ++
    3.97 ++	movw	%cx,%ds			/* access segment 0 */
    3.98 ++	xchgw	%di,(%bx)
    3.99 ++	movw	%es,%si
   3.100 ++	xchgw	%si,2(%bx)
   3.101 ++	popw	%ds			/* restore ds */
   3.102 ++	movw	%di, dpoff		/* save old parameters */
   3.103 ++	movw	%si, dpseg		/* to restore just before finishing */
   3.104 ++	pushw	%ds
   3.105 ++	popw	%es			/* reload es */
   3.106 ++
   3.107 ++/* Note that es is already set up.  Also cx is 0 from rep movsw above. */
   3.108 ++
   3.109 ++	xorb	%ah,%ah			/* reset FDC */
   3.110 ++	xorb	%dl,%dl
   3.111 ++	int	$0x13
   3.112 ++
   3.113 ++/* Get disk drive parameters, specifically number of sectors/track.
   3.114 ++ *
   3.115 ++ * It seems that there is no BIOS call to get the number of sectors.  Guess
   3.116 ++ * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
   3.117 ++ * 15 if sector 15 can be read.	Otherwise guess 9.
   3.118 ++ */
   3.119 ++
   3.120 ++	movw	$disksizes, %si		/* table of sizes to try */
   3.121 ++
   3.122 ++probe_loop: 
   3.123 + 	lodsb
   3.124 ++	orb	%al, %al
   3.125 ++	je	got_sectors		/* if all else fails, try 9 */
   3.126 ++	cbtw				/* extend to word */
   3.127 ++	movw	%ax, sectors
   3.128 ++	xchgw	%cx,%ax			/* cx = track and sector */
   3.129 ++	xorw	%dx,%dx			/* drive 0, head 0 */
   3.130 ++	movw	$0x0200, %bx		/* address after boot sector */
   3.131 ++					/*   (512 bytes from origin, es = cs) */
   3.132 ++	movw	$0x0201, %ax		/* service 2, 1 sector */
   3.133 ++	int	$0x13
   3.134 ++	jc	probe_loop		/* try next value */
   3.135 ++
   3.136 ++got_sectors: 
   3.137 ++	movw	$msg1end-msg1, %cx
   3.138 ++	movw	$msg1, %si
   3.139 ++	call	print_str
   3.140 ++
   3.141 ++/* ok, we've written the Loading... message, now we want to load the system */
   3.142 ++
   3.143 ++	pushw	%es			/* = ds */
   3.144 ++	movw	$SYSSEG, %ax
   3.145 ++	movw	%ax,%es			/* segment of SYSSEG<<4 */
   3.146 ++	pushw	%es
   3.147 ++	call	read_it
   3.148 ++
   3.149 ++/* This turns off the floppy drive motor, so that we enter the kernel in a
   3.150 ++ * known state, and don't have to worry about it later.
   3.151 ++ */
   3.152 ++	movw	$0x3f2, %dx
   3.153 ++	xorb	%al,%al
   3.154 ++	outb	%al,%dx
   3.155 ++
   3.156 ++	call	print_nl
   3.157 ++	pop	%es			/* = SYSSEG */
   3.158 ++	pop	%es			/* balance push/pop es */
   3.159 ++sigok: 
   3.160 ++
   3.161 ++/* Restore original disk parameters */
   3.162 ++	movw	$0x78, %bx
   3.163 ++	movw	dpoff, %di
   3.164 ++	movw	dpseg, %si
   3.165 ++	xorw	%ax,%ax
   3.166 ++	movw	%ax,%ds
   3.167 ++	movw	%di,(%bx)
   3.168 ++	movw	%si,2(%bx)
   3.169 ++
   3.170 ++/* after that (everything loaded), we call to the .ROM file loaded. */
   3.171 ++
   3.172 ++	movw	$SYSSEG, %ax
   3.173 ++	jmp	go_setup_code
   3.174 ++
   3.175 ++/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
   3.176 ++ * boundaries are crossed. We try to load it as fast as possible, loading whole
   3.177 ++ * tracks whenever we can.
   3.178 ++ *
   3.179 ++ * in:	es - starting address segment (normally SYSSEG)
   3.180 ++ */
   3.181 ++read_it: 
   3.182 ++	movw	$0,sread		/* read whole image incl boot sector */
   3.183 ++	movw	%es,%ax
   3.184 ++	testw	$0x0fff, %ax
   3.185 ++die:	jne	die			/* es must be at 64kB boundary */
   3.186 ++	xorw	%bx,%bx			/* bx is starting address within segment */
   3.187 ++rp_read: 
   3.188 ++	movw	%es,%ax
   3.189 ++	movw	%bx,%dx
   3.190 ++	movb	$4, %cl
   3.191 ++	shrw	%cl,%dx			/* bx is always divisible by 16 */
   3.192 ++	addw	%dx,%ax
   3.193 ++.equ	SYSSIZE, _load_size_pgh - 32
   3.194 ++	cmpw	$SYSSEG+SYSSIZE, %ax	/* have we loaded all yet? */
   3.195 ++	jb	ok1_read
   3.196 ++	ret
   3.197 ++ok1_read: 
   3.198 ++	movw	sectors, %ax
   3.199 ++	subw	sread, %ax
   3.200 ++	movw	%ax,%cx
   3.201 ++	shlw	$9, %cx			/* 80186 opcode */
   3.202 ++	addw	%bx,%cx
   3.203 ++	jnc	ok2_read
   3.204 ++	je	ok2_read
   3.205 ++	xorw	%ax,%ax
   3.206 ++	subw	%bx,%ax
   3.207 ++	shrw	$9, %ax			/* 80186 opcode */
   3.208 ++ok2_read: 
   3.209 ++	call	read_track
   3.210 ++	movw	%ax,%cx
   3.211 ++	addw	sread, %ax
   3.212 ++	cmpw	sectors, %ax
   3.213 ++	jne	ok3_read
   3.214 ++	movw	$1, %ax
   3.215 ++	subw	head, %ax
   3.216 ++	jne	ok4_read
   3.217 ++	incw	track
   3.218 ++ok4_read: 
   3.219 ++	movw	%ax, head
   3.220 ++	xorw	%ax,%ax
   3.221 ++ok3_read: 
   3.222 ++	movw	%ax, sread
   3.223 ++	shlw	$9, %cx			/* 80186 opcode */
   3.224 ++	addw	%cx,%bx
   3.225 ++	jnc	rp_read
   3.226 ++	movw	%es,%ax
   3.227 ++	addb	$0x10, %ah
   3.228 ++	movw	%ax,%es
   3.229 ++	xorw	%bx,%bx
   3.230 ++	jmp	rp_read
   3.231 ++
   3.232 ++read_track: 
   3.233 ++	pusha				/* 80186 opcode */
   3.234 ++	pushw	%ax
   3.235 ++	pushw	%bx
   3.236 ++	pushw	%bp			/* just in case the BIOS is buggy */
   3.237 ++	movb	$0x2e, %al		/* 0x2e = . */
   3.238 ++	call	print_char
   3.239 ++	popw	%bp
   3.240 ++	popw	%bx
   3.241 ++	popw	%ax
   3.242 ++
   3.243 ++	movw	sread, %cx
   3.244 ++	incw	%cx
   3.245 ++	movb	track, %ch
   3.246 ++	movw	$0x0100, %dx
   3.247 ++	andb	head, %dh
   3.248 ++	movb	$2, %ah
   3.249 ++
   3.250 ++	pushw	%dx			/* save for error dump */
   3.251 ++	pushw	%cx
   3.252 ++	pushw	%bx
   3.253 ++	pushw	%ax
   3.254 ++
   3.255 ++	int	$0x13
   3.256 ++	jc	bad_rt
   3.257 ++	addw	$8, %sp
   3.258 ++	popa				/* 80186 opcode */
   3.259 ++	ret
   3.260 ++
   3.261 ++bad_rt: pushw	%ax			/* save error code */
   3.262 ++	call	print_all		/* ah = error, al = read */
   3.263 ++
   3.264 ++	xorb	%ah,%ah
   3.265 ++	xorb	%dl,%dl
   3.266 ++	int	$0x13
   3.267 ++
   3.268 ++	addw	$10, %sp
   3.269 ++	popa				/* 80186 opcode */
   3.270 ++	jmp	read_track
   3.271 ++
   3.272 ++/* print_all is for debugging purposes.	It will print out all of the registers.
   3.273 ++ * The assumption is that this is called from a routine, with a stack frame like
   3.274 ++ *	dx
   3.275 ++ *	cx
   3.276 ++ *	bx
   3.277 ++ *	ax
   3.278 ++ *	error
   3.279 ++ *	ret <- sp
   3.280 ++ */
   3.281 ++
   3.282 ++print_all: 
   3.283 ++	call	print_nl		/* nl for readability */
   3.284 ++					/* print_nl update ah and bx */
   3.285 ++	movw	$5, %cx			/* error code + 4 registers */
   3.286 ++	movw	%sp,%bp
   3.287 ++
   3.288 ++print_loop: 
   3.289 ++	pushw	%cx			/* save count left */
   3.290 ++
   3.291 ++	cmpb	$5, %cl
   3.292 ++	jae	no_reg			/* see if register name is needed */
   3.293 ++
   3.294 ++	movb	$0x5+0x41-1, %al
   3.295 ++	subb	%cl,%al
   3.296 ++	int	$0x10
   3.297 ++
   3.298 ++	movb	$0x58, %al		/* 'X' */
   3.299 + 	int	$0x10
   3.300 ++
   3.301 ++	movb	$0x3A, %al		/* ':' */
   3.302 ++	int	$0x10
   3.303 ++
   3.304 ++no_reg: 
   3.305 ++	addw	$2, %bp			/* next register */
   3.306 ++	call	print_hex		/* print it */
   3.307 ++	movb	$0x20, %al		/* print a space */
   3.308 ++	int	$0x10
   3.309 ++	popw	%cx
   3.310 ++	loop	print_loop
   3.311 ++					/* nl for readability */
   3.312 ++print_nl: 
   3.313 ++	movb	$0xd, %al		/* CR */
   3.314 ++	call	print_char
   3.315 ++	movb	$0xa, %al		/* LF */
   3.316 ++	jmp	print_char
   3.317 ++
   3.318 ++
   3.319 ++print_str: 
   3.320 ++prloop: 
   3.321 ++	lodsb
   3.322 ++	call	print_char
   3.323 + 	loop	prloop
   3.324 +-freeze: jmp	freeze
   3.325 ++	ret
   3.326 ++
   3.327 ++/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
   3.328 ++
   3.329 ++print_hex: 
   3.330 ++	movw	(%bp),%dx		/* load word into dx */
   3.331 ++	movb	$4, %cl
   3.332 ++	call	print_2digits
   3.333 ++print_2digits: 
   3.334 ++	call	print_digit
   3.335 ++/* fall through */
   3.336 ++print_digit: 
   3.337 ++	rol	%cl,%dx			/* rotate to use lowest 4 bits */
   3.338 ++	movb	$0x0f, %al		/* mask for nybble */
   3.339 ++	andb	%dl,%al
   3.340 ++	addb	$0x90, %al		/* convert al to ascii hex */
   3.341 ++	daa				/* (four instructions) */
   3.342 ++	adcb	$0x40, %al
   3.343 ++	daa
   3.344 ++print_char:
   3.345 ++	movb	$0x0e, %ah		/* write char, tty mode */
   3.346 ++	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   3.347 ++	int	$0x10
   3.348 ++	ret
   3.349 ++
   3.350 ++sread:	.word 0				/* sectors read of current track */
   3.351 ++head:	.word 0				/* current head */
   3.352 ++track:	.word 0				/* current track */
   3.353 ++
   3.354 ++sectors: 
   3.355 ++	.word 0
   3.356 + 
   3.357 +-why:	.ascii	"This image cannot be loaded from a floppy disk.\r\n"
   3.358 +-why_end: 
   3.359 ++dpseg:	.word 0
   3.360 ++dpoff:	.word 0
   3.361 + 
   3.362 ++disksizes: 
   3.363 ++	.byte 36,18,15,9,0
   3.364 ++
   3.365 ++msg1: 
   3.366 ++	.ascii "Loading ROM image"
   3.367 ++msg1end: 
   3.368 + 
   3.369 + 	.org	497
   3.370 + setup_sects: 
   3.371 +@@ -123,14 +426,23 @@
   3.372 + 	executing the Etherboot image that's loaded at SYSSEG:0 and
   3.373 + 	whose entry point is SYSSEG:0.
   3.374 + */
   3.375 +-setup_code:
   3.376 ++setup_code: 
   3.377 ++	movw	$(SYSSEG-(PREFIXSIZE/16)), %ax
   3.378 + 	/* Etherboot expects to be contiguous in memory once loaded.
   3.379 + 	 * LILO doesn't do this, but since we don't need any
   3.380 + 	 * information that's left in the prefix, it doesn't matter:
   3.381 + 	 * we just have to ensure that %cs:0000 is where the start of
   3.382 + 	 * the Etherboot image *would* be.
   3.383 + 	 */
   3.384 +-	ljmp	$(SYSSEG-(PREFIXSIZE/16)), $run_etherboot
   3.385 ++go_setup_code: 
   3.386 ++	xorw	%cx, %cx
   3.387 ++	pushw	%cx
   3.388 ++	pushw	%cx		/* No parameters to preserve for exit path */
   3.389 ++	pushw	%cx		/* Use prefix exit path mechanism */
   3.390 ++	pushw	%ax
   3.391 ++	pushw	$run_etherboot
   3.392 ++	/* Calculated lcall to _start with %cs:0000 = image start */
   3.393 ++	lret
   3.394 + 
   3.395 + 
   3.396 + 	.org	PREFIXSIZE