wok-next diff syslinux/stuff/iso2exe/bootlinux.c @ rev 17160

syslinux/iso2exe: full zImage support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Sep 17 11:38:34 2014 +0200 (2014-09-17)
parents 3865e09ec026
children c15bb3c9e12d
line diff
     1.1 --- a/syslinux/stuff/iso2exe/bootlinux.c	Thu Mar 13 08:22:47 2014 +0000
     1.2 +++ b/syslinux/stuff/iso2exe/bootlinux.c	Wed Sep 17 11:38:34 2014 +0200
     1.3 @@ -1,7 +1,9 @@
     1.4  #include <stdio.h>
     1.5 +#include "libdos.h"
     1.6  #include "iso9660.h"
     1.7  
     1.8  static unsigned setup_version;
     1.9 +#define ELKSSIG		0x1E6
    1.10  #define SETUPSECTORS	0x1F1
    1.11  #define ROFLAG		0x1F2
    1.12  #define SYSSIZE		0x1F4
    1.13 @@ -39,11 +41,16 @@
    1.14  	while (1);
    1.15  }
    1.16  
    1.17 +static int iselks;
    1.18  static int vm86(void)
    1.19  {
    1.20  #asm
    1.21 -		smsw	ax
    1.22 +		xor	ax, ax
    1.23 +		cmp	ax, _iselks
    1.24 +		jne	fakerealmode	// elks may run on a 8086
    1.25 +		smsw	ax		// 286+
    1.26  		and	ax, #1		// 0:realmode	1:vm86
    1.27 +fakerealmode:
    1.28  #endasm
    1.29  } 
    1.30  
    1.31 @@ -55,13 +62,31 @@
    1.32  static void movehi(void)
    1.33  {
    1.34  #asm
    1.35 -		pusha
    1.36 +		push	si
    1.37 +		push	di
    1.38 +
    1.39 +		mov	si, #_mem
    1.40 +		cmp	word ptr [si+2], #0x10
    1.41 +		jnc	movehiz
    1.42 +		mov	ax, [si+1]
    1.43 +		mov	cl, #4
    1.44 +		shl	ax, cl		// 8086 support for elks
    1.45 +		mov	es, ax
    1.46 +		mov	di, #0x00FF
    1.47 +		and	di, [si]
    1.48 +		mov	si, #_buffer
    1.49 +		mov	cx, #BUFFERSZ/2
    1.50 +		cld
    1.51 +		rep
    1.52 +		  movw
    1.53 +		jmp	movedone
    1.54 +movehiz:
    1.55  		xor	di, di		// 30
    1.56  		mov	cx, #9		// 2E..1E
    1.57  zero1:
    1.58  		push	di
    1.59  		loop	zero1
    1.60 -		push	dword [_mem]	// 1A mem.base
    1.61 +		push	dword [si]	// 1A mem.base
    1.62  		push	#-1		// 18
    1.63  		push	di		// 16
    1.64  		xor	eax, eax
    1.65 @@ -86,15 +111,17 @@
    1.66  		xchg	[si+0x1F], al	// bits 24..31
    1.67  		int	0x15
    1.68  		add	sp, #0x30
    1.69 -		popa
    1.70 +movedone:
    1.71 +		pop	di
    1.72 +		pop	si
    1.73  #endasm
    1.74  }
    1.75  
    1.76  #define ZIMAGE_SUPPORT
    1.77 +#define FULL_ZIMAGE
    1.78  
    1.79  #ifdef ZIMAGE_SUPPORT
    1.80  static unsigned zimage = 0;
    1.81 -#ifndef FULL_ZIMAGE 
    1.82  static unsigned getss(void)
    1.83  {
    1.84  #asm
    1.85 @@ -102,18 +129,6 @@
    1.86  #endasm
    1.87  }
    1.88  #endif
    1.89 -#endif
    1.90 -
    1.91 -static int versiondos;
    1.92 -static int dosversion(void)
    1.93 -{
    1.94 -#asm
    1.95 -		mov	ah, #0x30
    1.96 -		int	0x21
    1.97 -		cbw
    1.98 -		mov	_versiondos, ax
    1.99 -#endasm
   1.100 -}
   1.101  
   1.102  static unsigned extendedramsizeinkb(void)
   1.103  {
   1.104 @@ -135,10 +150,12 @@
   1.105  		die("Need real mode");
   1.106  	switch (mem.align) {
   1.107  	case 0:	// kernel
   1.108 +#ifdef __MSDOS__ 
   1.109  		if ((unsigned) (dosversion() - 3) > 7 - 3) {
   1.110  			printf("DOS %d not supported.\nTrying anyway...\n",
   1.111  				versiondos);
   1.112  		}
   1.113 +#endif
   1.114  		mem.align = PAGE_SIZE;
   1.115  		break;
   1.116  	case PAGE_SIZE: // first initrd : keep 16M..48M for the kernel
   1.117 @@ -165,21 +182,21 @@
   1.118  	mem.base &= - mem.align;
   1.119  }
   1.120  
   1.121 +static unsigned setupseg = SETUP_SEGMENT;
   1.122  static unsigned setupofs = 0;
   1.123  
   1.124  void movesetup(void)
   1.125  {
   1.126  #asm
   1.127 -		pusha
   1.128 -		push	#SETUP_SEGMENT
   1.129 -		pop	es
   1.130 +		push	si
   1.131 +		mov	es, _setupseg
   1.132  		mov	si, #_buffer
   1.133 -		mov	di, _setupofs
   1.134 +		xchg	di, _setupofs
   1.135  		mov	cx, #BUFFERSZ/2
   1.136  		rep
   1.137  		  movsw
   1.138 -		mov	_setupofs, di
   1.139 -		popa
   1.140 +		xchg	_setupofs, di
   1.141 +		pop	si
   1.142  #endasm
   1.143  }
   1.144  
   1.145 @@ -190,23 +207,40 @@
   1.146  #endasm
   1.147  }
   1.148  
   1.149 +static unsigned long kernel_version = 0;
   1.150  unsigned long loadkernel(void)
   1.151  {
   1.152  	unsigned setup, n = BUFFERSZ;
   1.153 -	unsigned long syssize = 0, kernel_version = 0;
   1.154 +	unsigned long syssize = 0;
   1.155  
   1.156  	do {
   1.157  		isoread(buffer, n);
   1.158  		if (setupofs == 0) {
   1.159  			if (* (unsigned short *) (buffer + BOOTFLAG) != 0xAA55)
   1.160  				die("The kernel is not bootable");
   1.161 +#asm
   1.162 +			int	0x12
   1.163 +			jc	has640k
   1.164 +			dec	ax
   1.165 +			and	al, #0xC0
   1.166 +			mov	cl, #6
   1.167 +			shl	ax, cl
   1.168 +			cmp	ax, _setupseg
   1.169 +			jnc	has640k
   1.170 +			mov	_setupseg, ax
   1.171 +has640k:
   1.172 +#endasm
   1.173  			setup = (1 + buffer[SETUPSECTORS]) << 9;
   1.174  			if (setup == 512) setup = 5 << 9;
   1.175  			syssize = * (unsigned long  *) (buffer + SYSSIZE) << 4;
   1.176 +			if (!syssize) syssize = 0x7F000;
   1.177  			setup_version = * (unsigned short *) (buffer + VERSION);
   1.178  #define HDRS	0x53726448
   1.179  			if (* (unsigned long *) (buffer + HEADER) != HDRS)
   1.180  				setup_version = 0;
   1.181 +#define ELKS	0x534B4C45
   1.182 +			if (* (unsigned long *) (buffer + ELKSSIG) == ELKS)
   1.183 +				iselks = 1;
   1.184  			if (setup_version < 0x204)
   1.185  				syssize &= 0x000FFFFFUL;
   1.186  			if (setup_version) {
   1.187 @@ -237,16 +271,16 @@
   1.188  			}
   1.189  			if (!setup_version || !(buffer[LOADFLAGS] & 1)) {
   1.190  #ifdef ZIMAGE_SUPPORT
   1.191 -#ifndef FULL_ZIMAGE 
   1.192  				zimage = getss() + 0x1000;
   1.193  				mem.base = zimage * 16L; 
   1.194 -				if (mem.base + syssize > SETUP_SEGMENT*16L - 32)
   1.195 +				if (mem.base + syssize > setupseg*16L - 32) {
   1.196 +#ifdef FULL_ZIMAGE
   1.197 +					zimage = 0x11;
   1.198 +					mem.base = 0x110000L;	// 1M + 64K HMA 
   1.199 +#else
   1.200  					die("Out of memory");
   1.201 -#else
   1.202 -				zimage = 0x11;
   1.203 -				mem.base = 0x110000L;	// 1M + 64K HMA 
   1.204 -
   1.205  #endif
   1.206 +				}
   1.207  #else
   1.208  				die("Not a bzImage format");
   1.209  #endif
   1.210 @@ -258,17 +292,16 @@
   1.211  	} while (setup > 0);
   1.212  
   1.213  #asm
   1.214 +		push	si
   1.215 +		mov	si, #0x200
   1.216 +		cmp	si, _setup_version
   1.217 +		jae	noversion
   1.218  		push	ds
   1.219 -		push	#SETUP_SEGMENT
   1.220 -		pop	ds
   1.221 -		mov	si, #0x200
   1.222 -		mov	eax, #0x53726448	// HdrS
   1.223 +		mov	ds, _setupseg		// setup > 2.00 => 386+
   1.224 +		xor	eax, eax
   1.225  		cdq				// clear edx
   1.226 -		cmp	[si+2], eax
   1.227 -		jne	noversion
   1.228  		add	si, [si+14]
   1.229  		mov	cx, #3
   1.230 -		xor	ax, ax
   1.231  nextdigit:
   1.232  		shl	al, #4
   1.233  		shl	ax, #4
   1.234 @@ -281,10 +314,9 @@
   1.235  		shld	edx, eax, #8
   1.236  		loop	next
   1.237  		pop	ds
   1.238 -		mov	.loadkernel.kernel_version[bp], edx
   1.239 -		push	ds
   1.240 +		mov	_kernel_version, edx
   1.241  noversion:
   1.242 -		pop	ds
   1.243 +		pop	si
   1.244  #endasm
   1.245  	load(syssize);
   1.246  	return kernel_version;
   1.247 @@ -292,15 +324,15 @@
   1.248  
   1.249  void loadinitrd(void)
   1.250  {
   1.251 -	if (setup_version && zimage == 0)
   1.252 +	if (setup_version)
   1.253  		load(isofilesize);
   1.254  }
   1.255  
   1.256  void bootlinux(char *cmdline)
   1.257  {
   1.258 +	dosshutdown();
   1.259  #asm
   1.260 -	push	#SETUP_SEGMENT
   1.261 -	pop	es
   1.262 +	mov	es, _setupseg
   1.263  #endasm
   1.264  	if (cmdline) {
   1.265  		if (setup_version <= 0x201) {
   1.266 @@ -345,82 +377,111 @@
   1.267  #endasm
   1.268  #ifdef ZIMAGE_SUPPORT
   1.269  #asm
   1.270 +	cld
   1.271 +	mov	ax, _mem
   1.272 +	mov	dx, _mem+2
   1.273  	mov	bx, _zimage
   1.274 +	mov	bp, _iselks
   1.275 +	mov	si, #sysmove
   1.276 +	mov	di, #SETUP_END
   1.277 +	mov	cx, #endsysmove-sysmove
   1.278  	or	bx, bx
   1.279  	jz	notzimage
   1.280 -		mov	eax, _mem
   1.281 -#ifndef FULL_ZIMAGE 
   1.282 -		shr	eax, #4		// top
   1.283 -		mov	dx, #SYSTEM_SEGMENT
   1.284 -#else
   1.285 -		dec	eax
   1.286 -		shr	eax, #16
   1.287 -		inc	ax
   1.288 -		mov	dx, #SYSTEM_SEGMENT/0x1000
   1.289 -#endif
   1.290  		push	cs
   1.291  		pop	ds
   1.292 -		push	ss
   1.293 -		pop	es
   1.294  		push	es
   1.295 -		mov	si, #sysmove
   1.296 -		mov	di, #SETUP_END
   1.297  		push	di
   1.298 -		mov	cx, #endsysmove-sysmove
   1.299 -		cld
   1.300  		rep
   1.301  		  movsb
   1.302  		retf
   1.303  sysmove:
   1.304 -#ifndef FULL_ZIMAGE 
   1.305 -		mov	ds, bx
   1.306 -		mov	es, dx
   1.307 -		xor	di, di
   1.308 -		xor	si, si
   1.309 -		mov	cl, #8
   1.310 -		rep
   1.311 -		  movsw
   1.312 -		inc	bx
   1.313 +#ifdef FULL_ZIMAGE
   1.314 +		cmp	dx, #0x0010
   1.315 +		jb	lowsys
   1.316 +// bx first 64k page, dx:ax last byte+1
   1.317 +		xchg	ax, cx			// clear ax
   1.318 +		jcxz	aligned
   1.319  		inc	dx
   1.320 -		cmp	ax, bx
   1.321 -		jne	sysmove
   1.322 -#else
   1.323 -		xchg	ax, cx
   1.324 +aligned:
   1.325  		mov	si, di
   1.326 -		push	es
   1.327 -		pop	ds
   1.328 -		push	cx
   1.329  		mov	cx, #0x18
   1.330  		rep
   1.331  		  stosw
   1.332 +		push	es
   1.333 +		pop	ds
   1.334  		dec	cx
   1.335 -		mov	[si+0x10], cx
   1.336 -		mov	[si+0x18], cx
   1.337 -		pop	cx
   1.338 +		mov	[si+0x10], cx	// limit = -1
   1.339 +		mov	[si+0x18], cx	// limit = -1
   1.340 +		mov	cx, #0x9300+SYSTEM_SEGMENT/0x1000
   1.341  		mov	bh, #0x93
   1.342 -		mov	dh, #0x93
   1.343  mvdown:
   1.344  		mov	[si+0x12+2], bx	// srce
   1.345 -		mov	[si+0x1A+2], dx	// dest
   1.346 -		pusha
   1.347 +		mov	[si+0x1A+2], cx	// dest
   1.348 +		pusha			// more than 1Mb => 286+
   1.349  		mov	cx, #0x8000
   1.350  		mov	ah, #0x87
   1.351 -		int	0x15	// catched by himem.sys: may need dos=high,umb
   1.352 +		int	0x15
   1.353  		popa
   1.354  		inc	bx
   1.355 -		inc	dx
   1.356 -		cmp	cl, bl
   1.357 +		inc	cx
   1.358 +		cmp	dl, bl
   1.359  		jne	mvdown
   1.360 +		jmp	notzimage
   1.361  #endif
   1.362 +lowsys:
   1.363 +// bx first segment, dx:ax last byte+1 (paragraph aligned)
   1.364 +		mov	cl, #4
   1.365 +		shr	ax, cl
   1.366 +		mov	cl, #12
   1.367 +		shl	dx, cl
   1.368 +		or	ax, dx		// last segment+1
   1.369 +		mov	dx, #SYSTEM_SEGMENT
   1.370 +		sub	ax, bx		// ax = paragraph count
   1.371 +		sub	bx, dx
   1.372 +		jnc	sysmovelp
   1.373 +		add	dx, ax		// top down
   1.374 +		dec	dx
   1.375 +sysmovelp:		// move ax paragraphs from bx+dx:0 to dx:0
   1.376 +		mov	es, dx
   1.377 +		mov	cx, dx
   1.378 +		add	cx, bx
   1.379 +		mov	ds, cx
   1.380 +		sbb	cx, cx		// cx = 0 : -1
   1.381 +		cmc			// C  = 1 :  0
   1.382 +		adc	dx, cx
   1.383 +		xor	di, di
   1.384 +		xor	si, si
   1.385 +		mov	cx, #8
   1.386 +		rep
   1.387 +		  movsw
   1.388 +		dec	ax
   1.389 +		jne	sysmovelp
   1.390  notzimage:
   1.391 +	or	bp, bp
   1.392 +	jz	notelks
   1.393 +	push	ss
   1.394 +	pop	ds
   1.395 +	mov	cx, #0x100
   1.396 +	mov	es, cx
   1.397 +	mov	ch, #0x78	// do not overload SYSTEM_SEGMENT
   1.398 +	xor	si, si
   1.399 +	xor	di, di
   1.400 +	push	es
   1.401 +	rep
   1.402 +	  movsw
   1.403 +	pop	ss
   1.404 +notelks:
   1.405  #endasm
   1.406  #endif
   1.407  #asm
   1.408 -	push	ss
   1.409 -	pop	ds
   1.410 -	push	ds
   1.411 -	pop	es
   1.412 -	jmpi	0, #0x9020
   1.413 +	mov	ax, ss
   1.414 +	mov	ds, ax
   1.415 +	mov	es, ax
   1.416 +	add	ax, #0x20
   1.417 +	push	ax
   1.418 +	xor	dx, dx
   1.419 +	push	dx
   1.420 +	retf
   1.421  endsysmove:
   1.422  #endasm
   1.423  }