wok diff syslinux/stuff/iso2exe/bootlinux.c @ rev 16022

syslinux/iso2exe: add zimage support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Mar 06 19:57:41 2014 +0000 (2014-03-06)
parents 825165c08d25
children d814ca840c3c
line diff
     1.1 --- a/syslinux/stuff/iso2exe/bootlinux.c	Tue Mar 04 16:29:56 2014 +0000
     1.2 +++ b/syslinux/stuff/iso2exe/bootlinux.c	Thu Mar 06 19:57:41 2014 +0000
     1.3 @@ -1,7 +1,7 @@
     1.4  #include <stdio.h>
     1.5  #include "iso9660.h"
     1.6  
     1.7 -static unsigned version;
     1.8 +static unsigned setup_version;
     1.9  #define SETUPSECTORS	0x1F1
    1.10  #define ROFLAG		0x1F2
    1.11  #define SYSSIZE		0x1F4
    1.12 @@ -24,9 +24,9 @@
    1.13  
    1.14  #define PAGE_BITS	12
    1.15  #define PAGE_SIZE	4096
    1.16 -#define BUFFERSZ	PAGE_SIZE
    1.17 +#define BUFFERSZ	2048		// lower than mix setup
    1.18  static char buffer[BUFFERSZ];
    1.19 -static unsigned long initrd_addr, initrd_size;
    1.20 +static unsigned long initrd_addr = 0, initrd_size;
    1.21  
    1.22  static int may_exit_dos = 1;
    1.23  static void die(char *msg)
    1.24 @@ -45,12 +45,10 @@
    1.25  #endasm
    1.26  } 
    1.27  
    1.28 -static struct mem {
    1.29 +static struct {
    1.30  	unsigned long base;
    1.31  	int align;
    1.32 -} kernelmem = { 0x100000, 0 };
    1.33 -
    1.34 -#define initrdmem kernelmem
    1.35 +} mem = { 0x100000, 0 };
    1.36  
    1.37  static void movehi(void)
    1.38  {
    1.39 @@ -61,7 +59,7 @@
    1.40  zero1:
    1.41  		push	di
    1.42  		loop	zero1
    1.43 -		push	dword [_kernelmem]	// 1A p->base
    1.44 +		push	dword [_mem]	// 1A mem.base
    1.45  		push	#-1		// 18
    1.46  		push	di		// 16
    1.47  		xor	eax, eax
    1.48 @@ -90,7 +88,18 @@
    1.49  #endasm
    1.50  }
    1.51  
    1.52 -#undef ZIMAGE_SUPPORT	/* Does not work... */
    1.53 +#define ZIMAGE_SUPPORT
    1.54 +
    1.55 +#ifdef ZIMAGE_SUPPORT
    1.56 +static int zimage = 0;
    1.57 +static unsigned zimage_base;
    1.58 +static unsigned getss(void)
    1.59 +{
    1.60 +#asm
    1.61 +	mov	ax, ss
    1.62 +#endasm
    1.63 +}
    1.64 +#endif
    1.65  
    1.66  static int versiondos;
    1.67  static int dosversion(void)
    1.68 @@ -114,11 +123,11 @@
    1.69  #endasm
    1.70  }
    1.71  
    1.72 -static void load(struct mem *p, unsigned long size)
    1.73 +static void load(unsigned long size)
    1.74  {
    1.75  	if (vm86())
    1.76  		die("Need real mode");
    1.77 -	switch (p->align) {
    1.78 +	switch (mem.align) {
    1.79  	case 0:	// kernel
    1.80  		switch (dosversion()) {
    1.81  		case 3: case 4: case 6: case 7: break;
    1.82 @@ -126,29 +135,27 @@
    1.83  			printf("DOS %d not supported.\nTrying anyway...\n",
    1.84  				versiondos);
    1.85  		}
    1.86 -		p->align = PAGE_SIZE;
    1.87 +		mem.align = PAGE_SIZE;
    1.88  		break;
    1.89  	case PAGE_SIZE: // first initrd : keep 16M..48M for the kernel
    1.90 -		if (extendedramsizeinkb() > 0xF000U && p->base < 0x3000000)
    1.91 -			p->base = 0x3000000;
    1.92 -		initrd_addr = p->base;
    1.93 -		p->align = 4;
    1.94 +		if (extendedramsizeinkb() > 0xF000U && mem.base < 0x3000000)
    1.95 +			mem.base = 0x3000000;
    1.96 +		initrd_addr = mem.base;
    1.97 +		mem.align = 4;
    1.98  	}
    1.99  	while (size) {
   1.100  		int n, s = sizeof(buffer);
   1.101  		for (n = 0; n < s; n++) buffer[n] = 0;
   1.102  		if (s > size) s = size;
   1.103 -		n = isoread(buffer, s);
   1.104 +		if ((n = isoread(buffer, s)) < 0) break;
   1.105  		movehi();
   1.106 -		if (n != -1) {
   1.107 -			p->base += n;
   1.108 -			size -= n;
   1.109 -		}
   1.110 -		if (s != n) break;
   1.111 +		mem.base += n;
   1.112 +		size -= n;
   1.113 +		if (s != n) break;	// end of file
   1.114  	}
   1.115 -	initrd_size = p->base - initrd_addr;
   1.116 -	p->base += p->align - 1;
   1.117 -	p->base &= - p->align;
   1.118 +	initrd_size = mem.base - initrd_addr;
   1.119 +	mem.base += mem.align - 1;
   1.120 +	mem.base &= - mem.align;
   1.121  }
   1.122  
   1.123  static unsigned setupofs = 0;
   1.124 @@ -189,13 +196,13 @@
   1.125  			setup = (1 + buffer[SETUPSECTORS]) << 9;
   1.126  			if (setup == 512) setup = 5 << 9;
   1.127  			syssize = * (unsigned long  *) (buffer + SYSSIZE) << 4;
   1.128 -			version = * (unsigned short *) (buffer + VERSION);
   1.129 +			setup_version = * (unsigned short *) (buffer + VERSION);
   1.130  #define HDRS	0x53726448
   1.131  			if (* (unsigned long *) (buffer + HEADER) != HDRS)
   1.132 -				version = 0;
   1.133 -			if (version < 0x204)
   1.134 +				setup_version = 0;
   1.135 +			if (setup_version < 0x204)
   1.136  				syssize &= 0x000FFFFFUL;
   1.137 -			if (version) {
   1.138 +			if (setup_version) {
   1.139  #ifdef REALMODE_SWITCH
   1.140  				extern int far_realmode_switch();
   1.141  #asm
   1.142 @@ -213,7 +220,7 @@
   1.143  				* (unsigned short *) (buffer + RMSWSEG) = 
   1.144  					getcs();
   1.145  #endif
   1.146 -				kernelmem.base =
   1.147 +				mem.base =
   1.148  					* (unsigned long *) (buffer + SYSTEMCODE);
   1.149  				* (unsigned short *) (buffer + HEAPPTR) = 
   1.150  					0x9B00;
   1.151 @@ -221,34 +228,16 @@
   1.152  				* (unsigned short *) (buffer + LOADERTYPE) |= 
   1.153  					0x80FF;
   1.154  			}
   1.155 -			if (!version || !(buffer[LOADFLAGS] & 1)) {
   1.156 +			if (!setup_version || !(buffer[LOADFLAGS] & 1)) {
   1.157  #ifdef ZIMAGE_SUPPORT
   1.158 -#asm
   1.159 -		pusha
   1.160 -		mov	cx, #0x8000
   1.161 -		mov	es, cx
   1.162 -		xor	si, si
   1.163 -		xor	di, di
   1.164 -		rep
   1.165 -		  movsw			// move 64K data
   1.166 -		push	es
   1.167 -		pop	ds
   1.168 -		push	es
   1.169 -		pop	ss
   1.170 -		mov	ch, #0x70
   1.171 -		mov	es, cx
   1.172 -		mov	ch, #0x80
   1.173 -		rep
   1.174 -		 seg	cs
   1.175 -		  movsw			// move 64K code
   1.176 -		popa
   1.177 -		jmpi	relocated, #0x7000
   1.178 -relocated:
   1.179 -#endasm
   1.180 -				kernelmem.base = 0x10000;
   1.181 -				if (syssize > 0x60000)	/* 384K max */
   1.182 +				zimage = 1;
   1.183 +				zimage_base = getss() + 0x1000L;
   1.184 +				mem.base = zimage_base * 16L; 
   1.185 +				if (mem.base + syssize > SETUP_SEGMENT*16L - 32)
   1.186 +					die("Out of memory");
   1.187 +#else
   1.188 +				die("Not a bzImage format");
   1.189  #endif
   1.190 -				die("Not a bzImage format");
   1.191  			}
   1.192  		}
   1.193  		movesetup();
   1.194 @@ -281,16 +270,18 @@
   1.195  		loop	next
   1.196  		pop	ds
   1.197  		mov	.loadkernel.kernel_version[bp], edx
   1.198 +		push	ds
   1.199  noversion:
   1.200 +		pop	ds
   1.201  #endasm
   1.202 -	load(&kernelmem, syssize);
   1.203 +	load(syssize);
   1.204  	return kernel_version;
   1.205  }
   1.206  
   1.207  void loadinitrd(void)
   1.208  {
   1.209 -	if (version)
   1.210 -		load(&initrdmem, isofilesize);
   1.211 +	if (setup_version && zimage == 0)
   1.212 +		load(isofilesize);
   1.213  }
   1.214  
   1.215  void bootlinux(char *cmdline)
   1.216 @@ -298,6 +289,9 @@
   1.217  #asm
   1.218  	push	#SETUP_SEGMENT
   1.219  	pop	es
   1.220 +	push	es
   1.221 +	pop	ss
   1.222 +	mov	sp, #CMDLINE_OFFSET
   1.223  	mov	eax, _initrd_addr
   1.224  	or	eax, eax
   1.225  	jz	no_initrd
   1.226 @@ -308,7 +302,7 @@
   1.227  no_initrd:
   1.228  #endasm
   1.229  	if (cmdline) {
   1.230 -		if (version <= 0x201) {
   1.231 +		if (setup_version <= 0x201) {
   1.232  #asm
   1.233  		mov	di, #0x0020
   1.234  		mov	ax, #0xA33F
   1.235 @@ -334,12 +328,45 @@
   1.236  		jne	copy
   1.237  #endasm
   1.238  	}
   1.239 +#ifdef ZIMAGE_SUPPORT
   1.240 +	if (zimage) {
   1.241  #asm
   1.242 -	push	es
   1.243 +		mov	eax, _mem
   1.244 +		shr	eax, #4		// top
   1.245 +		mov	bx, _zimage_base
   1.246 +		mov	dx, #0x1000
   1.247 +		push	cs
   1.248 +		pop	ds
   1.249 +		mov	es, ax
   1.250 +		push	es
   1.251 +		mov	si, #sysmove
   1.252 +		xor	di, di
   1.253 +		push	di
   1.254 +		mov	cx, #endsysmove-sysmove
   1.255 +		rep
   1.256 +		  movsb
   1.257 +		retf
   1.258 +sysmove:
   1.259 +		mov	ds, bx
   1.260 +		mov	es, dx
   1.261 +		xor	di, di
   1.262 +		xor	si, si
   1.263 +		mov	cl, #8
   1.264 +		rep
   1.265 +		  movsw
   1.266 +		inc	bx
   1.267 +		inc	dx
   1.268 +		cmp	ax,bx
   1.269 +		jne	sysmove
   1.270 +#endasm
   1.271 +	}
   1.272 +#endif
   1.273 +#asm
   1.274 +	push	ss
   1.275  	pop	ds
   1.276  	push	ds
   1.277 -	pop	ss
   1.278 -	mov	sp, #CMDLINE_OFFSET
   1.279 +	pop	es
   1.280  	jmpi	0, #0x9020
   1.281 +endsysmove:
   1.282  #endasm
   1.283  }